aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorDmitry Antipov2013-09-24 10:43:20 +0400
committerDmitry Antipov2013-09-24 10:43:20 +0400
commitd6d9cbc15cbebfe466756a7a75601173c15287a2 (patch)
tree2f3e5223e8f8d637dc9c3c152929b879748b7918 /src/alloc.c
parentec7bc82f9c63b6ec533f7489e67b1c1b18d08dd5 (diff)
downloademacs-d6d9cbc15cbebfe466756a7a75601173c15287a2.tar.gz
emacs-d6d9cbc15cbebfe466756a7a75601173c15287a2.zip
Use union for the payload of struct Lisp_Vector.
This helps to avoid a few glitches dictated by C's aliasing rules. * lisp.h (struct Lisp_Vector): Use union for next and contents member. Adjust comment. Change related users. * alloc.c (next_in_free_list, set_next_in_free_list): Remove. Related users changed. * buffer.c, bytecode.c, ccl.c, character.h, chartab.c, composite.c: * composite.h, disptab.h, fns.c, fontset.c, indent.c, keyboard.c: * lread.c, msdos.c, process.c, w32menu.c, window.c, xdisp.c: * xfaces.c, xfont.c, xmenu.c: Related users changed.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c48
1 files changed, 16 insertions, 32 deletions
diff --git a/src/alloc.c b/src/alloc.c
index e380d66cb1b..ca21ba2469b 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2647,22 +2647,6 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
2647 2647
2648#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) 2648#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
2649 2649
2650/* Get and set the next field in block-allocated vectorlike objects on
2651 the free list. Doing it this way respects C's aliasing rules.
2652 We could instead make 'contents' a union, but that would mean
2653 changes everywhere that the code uses 'contents'. */
2654static struct Lisp_Vector *
2655next_in_free_list (struct Lisp_Vector *v)
2656{
2657 intptr_t i = XLI (v->contents[0]);
2658 return (struct Lisp_Vector *) i;
2659}
2660static void
2661set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
2662{
2663 v->contents[0] = XIL ((intptr_t) next);
2664}
2665
2666/* Common shortcut to setup vector on a free list. */ 2650/* Common shortcut to setup vector on a free list. */
2667 2651
2668#define SETUP_ON_FREE_LIST(v, nbytes, tmp) \ 2652#define SETUP_ON_FREE_LIST(v, nbytes, tmp) \
@@ -2672,7 +2656,7 @@ set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
2672 eassert ((nbytes) % roundup_size == 0); \ 2656 eassert ((nbytes) % roundup_size == 0); \
2673 (tmp) = VINDEX (nbytes); \ 2657 (tmp) = VINDEX (nbytes); \
2674 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \ 2658 eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \
2675 set_next_in_free_list (v, vector_free_lists[tmp]); \ 2659 v->u.next = vector_free_lists[tmp]; \
2676 vector_free_lists[tmp] = (v); \ 2660 vector_free_lists[tmp] = (v); \
2677 total_free_vector_slots += (nbytes) / word_size; \ 2661 total_free_vector_slots += (nbytes) / word_size; \
2678 } while (0) 2662 } while (0)
@@ -2769,7 +2753,7 @@ allocate_vector_from_block (size_t nbytes)
2769 if (vector_free_lists[index]) 2753 if (vector_free_lists[index])
2770 { 2754 {
2771 vector = vector_free_lists[index]; 2755 vector = vector_free_lists[index];
2772 vector_free_lists[index] = next_in_free_list (vector); 2756 vector_free_lists[index] = vector->u.next;
2773 total_free_vector_slots -= nbytes / word_size; 2757 total_free_vector_slots -= nbytes / word_size;
2774 return vector; 2758 return vector;
2775 } 2759 }
@@ -2783,7 +2767,7 @@ allocate_vector_from_block (size_t nbytes)
2783 { 2767 {
2784 /* This vector is larger than requested. */ 2768 /* This vector is larger than requested. */
2785 vector = vector_free_lists[index]; 2769 vector = vector_free_lists[index];
2786 vector_free_lists[index] = next_in_free_list (vector); 2770 vector_free_lists[index] = vector->u.next;
2787 total_free_vector_slots -= nbytes / word_size; 2771 total_free_vector_slots -= nbytes / word_size;
2788 2772
2789 /* Excess bytes are used for the smaller vector, 2773 /* Excess bytes are used for the smaller vector,
@@ -2981,7 +2965,7 @@ allocate_vectorlike (ptrdiff_t len)
2981 else 2965 else
2982 { 2966 {
2983 struct large_vector *lv 2967 struct large_vector *lv
2984 = lisp_malloc ((offsetof (struct large_vector, v.contents) 2968 = lisp_malloc ((offsetof (struct large_vector, v.u.contents)
2985 + len * word_size), 2969 + len * word_size),
2986 MEM_TYPE_VECTORLIKE); 2970 MEM_TYPE_VECTORLIKE);
2987 lv->next.vector = large_vectors; 2971 lv->next.vector = large_vectors;
@@ -3035,7 +3019,7 @@ allocate_pseudovector (int memlen, int lisplen, enum pvec_type tag)
3035 3019
3036 /* Only the first lisplen slots will be traced normally by the GC. */ 3020 /* Only the first lisplen slots will be traced normally by the GC. */
3037 for (i = 0; i < lisplen; ++i) 3021 for (i = 0; i < lisplen; ++i)
3038 v->contents[i] = Qnil; 3022 v->u.contents[i] = Qnil;
3039 3023
3040 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); 3024 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
3041 return v; 3025 return v;
@@ -3123,7 +3107,7 @@ See also the function `vector'. */)
3123 p = allocate_vector (XFASTINT (length)); 3107 p = allocate_vector (XFASTINT (length));
3124 sizei = XFASTINT (length); 3108 sizei = XFASTINT (length);
3125 for (i = 0; i < sizei; i++) 3109 for (i = 0; i < sizei; i++)
3126 p->contents[i] = init; 3110 p->u.contents[i] = init;
3127 3111
3128 XSETVECTOR (vector, p); 3112 XSETVECTOR (vector, p);
3129 return vector; 3113 return vector;
@@ -3141,21 +3125,21 @@ usage: (vector &rest OBJECTS) */)
3141 register struct Lisp_Vector *p = XVECTOR (val); 3125 register struct Lisp_Vector *p = XVECTOR (val);
3142 3126
3143 for (i = 0; i < nargs; i++) 3127 for (i = 0; i < nargs; i++)
3144 p->contents[i] = args[i]; 3128 p->u.contents[i] = args[i];
3145 return val; 3129 return val;
3146} 3130}
3147 3131
3148void 3132void
3149make_byte_code (struct Lisp_Vector *v) 3133make_byte_code (struct Lisp_Vector *v)
3150{ 3134{
3151 if (v->header.size > 1 && STRINGP (v->contents[1]) 3135 if (v->header.size > 1 && STRINGP (v->u.contents[1])
3152 && STRING_MULTIBYTE (v->contents[1])) 3136 && STRING_MULTIBYTE (v->u.contents[1]))
3153 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the 3137 /* BYTECODE-STRING must have been produced by Emacs 20.2 or the
3154 earlier because they produced a raw 8-bit string for byte-code 3138 earlier because they produced a raw 8-bit string for byte-code
3155 and now such a byte-code string is loaded as multibyte while 3139 and now such a byte-code string is loaded as multibyte while
3156 raw 8-bit characters converted to multibyte form. Thus, now we 3140 raw 8-bit characters converted to multibyte form. Thus, now we
3157 must convert them back to the original unibyte form. */ 3141 must convert them back to the original unibyte form. */
3158 v->contents[1] = Fstring_as_unibyte (v->contents[1]); 3142 v->u.contents[1] = Fstring_as_unibyte (v->u.contents[1]);
3159 XSETPVECTYPE (v, PVEC_COMPILED); 3143 XSETPVECTYPE (v, PVEC_COMPILED);
3160} 3144}
3161 3145
@@ -3190,7 +3174,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3190 to be setcar'd). */ 3174 to be setcar'd). */
3191 3175
3192 for (i = 0; i < nargs; i++) 3176 for (i = 0; i < nargs; i++)
3193 p->contents[i] = args[i]; 3177 p->u.contents[i] = args[i];
3194 make_byte_code (p); 3178 make_byte_code (p);
3195 XSETCOMPILED (val, p); 3179 XSETCOMPILED (val, p);
3196 return val; 3180 return val;
@@ -5183,7 +5167,7 @@ Does not copy symbols. Copies strings without text properties. */)
5183 size &= PSEUDOVECTOR_SIZE_MASK; 5167 size &= PSEUDOVECTOR_SIZE_MASK;
5184 vec = XVECTOR (make_pure_vector (size)); 5168 vec = XVECTOR (make_pure_vector (size));
5185 for (i = 0; i < size; i++) 5169 for (i = 0; i < size; i++)
5186 vec->contents[i] = Fpurecopy (AREF (obj, i)); 5170 vec->u.contents[i] = Fpurecopy (AREF (obj, i));
5187 if (COMPILEDP (obj)) 5171 if (COMPILEDP (obj))
5188 { 5172 {
5189 XSETPVECTYPE (vec, PVEC_COMPILED); 5173 XSETPVECTYPE (vec, PVEC_COMPILED);
@@ -5674,7 +5658,7 @@ mark_vectorlike (struct Lisp_Vector *ptr)
5674 The distinction is used e.g. by Lisp_Process which places extra 5658 The distinction is used e.g. by Lisp_Process which places extra
5675 non-Lisp_Object fields at the end of the structure... */ 5659 non-Lisp_Object fields at the end of the structure... */
5676 for (i = 0; i < size; i++) /* ...and then mark its elements. */ 5660 for (i = 0; i < size; i++) /* ...and then mark its elements. */
5677 mark_object (ptr->contents[i]); 5661 mark_object (ptr->u.contents[i]);
5678} 5662}
5679 5663
5680/* Like mark_vectorlike but optimized for char-tables (and 5664/* Like mark_vectorlike but optimized for char-tables (and
@@ -5691,7 +5675,7 @@ mark_char_table (struct Lisp_Vector *ptr)
5691 VECTOR_MARK (ptr); 5675 VECTOR_MARK (ptr);
5692 for (i = 0; i < size; i++) 5676 for (i = 0; i < size; i++)
5693 { 5677 {
5694 Lisp_Object val = ptr->contents[i]; 5678 Lisp_Object val = ptr->u.contents[i];
5695 5679
5696 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) 5680 if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit))
5697 continue; 5681 continue;
@@ -5896,10 +5880,10 @@ mark_object (Lisp_Object arg)
5896 VECTOR_MARK (ptr); 5880 VECTOR_MARK (ptr);
5897 for (i = 0; i < size; i++) 5881 for (i = 0; i < size; i++)
5898 if (i != COMPILED_CONSTANTS) 5882 if (i != COMPILED_CONSTANTS)
5899 mark_object (ptr->contents[i]); 5883 mark_object (ptr->u.contents[i]);
5900 if (size > COMPILED_CONSTANTS) 5884 if (size > COMPILED_CONSTANTS)
5901 { 5885 {
5902 obj = ptr->contents[COMPILED_CONSTANTS]; 5886 obj = ptr->u.contents[COMPILED_CONSTANTS];
5903 goto loop; 5887 goto loop;
5904 } 5888 }
5905 } 5889 }