diff options
| author | Dmitry Antipov | 2013-09-24 10:43:20 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2013-09-24 10:43:20 +0400 |
| commit | d6d9cbc15cbebfe466756a7a75601173c15287a2 (patch) | |
| tree | 2f3e5223e8f8d637dc9c3c152929b879748b7918 /src/alloc.c | |
| parent | ec7bc82f9c63b6ec533f7489e67b1c1b18d08dd5 (diff) | |
| download | emacs-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.c | 48 |
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'. */ | ||
| 2654 | static struct Lisp_Vector * | ||
| 2655 | next_in_free_list (struct Lisp_Vector *v) | ||
| 2656 | { | ||
| 2657 | intptr_t i = XLI (v->contents[0]); | ||
| 2658 | return (struct Lisp_Vector *) i; | ||
| 2659 | } | ||
| 2660 | static void | ||
| 2661 | set_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 | ||
| 3148 | void | 3132 | void |
| 3149 | make_byte_code (struct Lisp_Vector *v) | 3133 | make_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 | } |