diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 74 |
1 files changed, 49 insertions, 25 deletions
diff --git a/src/alloc.c b/src/alloc.c index 314438ba9f1..7f78619407d 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3136,17 +3136,29 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3136 | Symbol Allocation | 3136 | Symbol Allocation |
| 3137 | ***********************************************************************/ | 3137 | ***********************************************************************/ |
| 3138 | 3138 | ||
| 3139 | /* Like struct Lisp_Symbol, but padded so that the size is a multiple | ||
| 3140 | of the required alignment if LSB tags are used. */ | ||
| 3141 | |||
| 3142 | union aligned_Lisp_Symbol | ||
| 3143 | { | ||
| 3144 | struct Lisp_Symbol s; | ||
| 3145 | #ifdef USE_LSB_TAG | ||
| 3146 | unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1) | ||
| 3147 | & -(1 << GCTYPEBITS)]; | ||
| 3148 | #endif | ||
| 3149 | }; | ||
| 3150 | |||
| 3139 | /* Each symbol_block is just under 1020 bytes long, since malloc | 3151 | /* Each symbol_block is just under 1020 bytes long, since malloc |
| 3140 | really allocates in units of powers of two and uses 4 bytes for its | 3152 | really allocates in units of powers of two and uses 4 bytes for its |
| 3141 | own overhead. */ | 3153 | own overhead. */ |
| 3142 | 3154 | ||
| 3143 | #define SYMBOL_BLOCK_SIZE \ | 3155 | #define SYMBOL_BLOCK_SIZE \ |
| 3144 | ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) | 3156 | ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) |
| 3145 | 3157 | ||
| 3146 | struct symbol_block | 3158 | struct symbol_block |
| 3147 | { | 3159 | { |
| 3148 | /* Place `symbols' first, to preserve alignment. */ | 3160 | /* Place `symbols' first, to preserve alignment. */ |
| 3149 | struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; | 3161 | union aligned_Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; |
| 3150 | struct symbol_block *next; | 3162 | struct symbol_block *next; |
| 3151 | }; | 3163 | }; |
| 3152 | 3164 | ||
| @@ -3202,7 +3214,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3202 | symbol_block = new; | 3214 | symbol_block = new; |
| 3203 | symbol_block_index = 0; | 3215 | symbol_block_index = 0; |
| 3204 | } | 3216 | } |
| 3205 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); | 3217 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index].s); |
| 3206 | symbol_block_index++; | 3218 | symbol_block_index++; |
| 3207 | } | 3219 | } |
| 3208 | 3220 | ||
| @@ -3230,16 +3242,28 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3230 | Marker (Misc) Allocation | 3242 | Marker (Misc) Allocation |
| 3231 | ***********************************************************************/ | 3243 | ***********************************************************************/ |
| 3232 | 3244 | ||
| 3245 | /* Like union Lisp_Misc, but padded so that its size is a multiple of | ||
| 3246 | the required alignment when LSB tags are used. */ | ||
| 3247 | |||
| 3248 | union aligned_Lisp_Misc | ||
| 3249 | { | ||
| 3250 | union Lisp_Misc m; | ||
| 3251 | #ifdef USE_LSB_TAG | ||
| 3252 | unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1) | ||
| 3253 | & -(1 << GCTYPEBITS)]; | ||
| 3254 | #endif | ||
| 3255 | }; | ||
| 3256 | |||
| 3233 | /* Allocation of markers and other objects that share that structure. | 3257 | /* Allocation of markers and other objects that share that structure. |
| 3234 | Works like allocation of conses. */ | 3258 | Works like allocation of conses. */ |
| 3235 | 3259 | ||
| 3236 | #define MARKER_BLOCK_SIZE \ | 3260 | #define MARKER_BLOCK_SIZE \ |
| 3237 | ((1020 - sizeof (struct marker_block *)) / sizeof (union Lisp_Misc)) | 3261 | ((1020 - sizeof (struct marker_block *)) / sizeof (union aligned_Lisp_Misc)) |
| 3238 | 3262 | ||
| 3239 | struct marker_block | 3263 | struct marker_block |
| 3240 | { | 3264 | { |
| 3241 | /* Place `markers' first, to preserve alignment. */ | 3265 | /* Place `markers' first, to preserve alignment. */ |
| 3242 | union Lisp_Misc markers[MARKER_BLOCK_SIZE]; | 3266 | union aligned_Lisp_Misc markers[MARKER_BLOCK_SIZE]; |
| 3243 | struct marker_block *next; | 3267 | struct marker_block *next; |
| 3244 | }; | 3268 | }; |
| 3245 | 3269 | ||
| @@ -3284,7 +3308,7 @@ allocate_misc (void) | |||
| 3284 | marker_block_index = 0; | 3308 | marker_block_index = 0; |
| 3285 | total_free_markers += MARKER_BLOCK_SIZE; | 3309 | total_free_markers += MARKER_BLOCK_SIZE; |
| 3286 | } | 3310 | } |
| 3287 | XSETMISC (val, &marker_block->markers[marker_block_index]); | 3311 | XSETMISC (val, &marker_block->markers[marker_block_index].m); |
| 3288 | marker_block_index++; | 3312 | marker_block_index++; |
| 3289 | } | 3313 | } |
| 3290 | 3314 | ||
| @@ -6070,22 +6094,22 @@ gc_sweep (void) | |||
| 6070 | for (sblk = symbol_block; sblk; sblk = *sprev) | 6094 | for (sblk = symbol_block; sblk; sblk = *sprev) |
| 6071 | { | 6095 | { |
| 6072 | int this_free = 0; | 6096 | int this_free = 0; |
| 6073 | struct Lisp_Symbol *sym = sblk->symbols; | 6097 | union aligned_Lisp_Symbol *sym = sblk->symbols; |
| 6074 | struct Lisp_Symbol *end = sym + lim; | 6098 | union aligned_Lisp_Symbol *end = sym + lim; |
| 6075 | 6099 | ||
| 6076 | for (; sym < end; ++sym) | 6100 | for (; sym < end; ++sym) |
| 6077 | { | 6101 | { |
| 6078 | /* Check if the symbol was created during loadup. In such a case | 6102 | /* Check if the symbol was created during loadup. In such a case |
| 6079 | it might be pointed to by pure bytecode which we don't trace, | 6103 | it might be pointed to by pure bytecode which we don't trace, |
| 6080 | so we conservatively assume that it is live. */ | 6104 | so we conservatively assume that it is live. */ |
| 6081 | int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); | 6105 | int pure_p = PURE_POINTER_P (XSTRING (sym->s.xname)); |
| 6082 | 6106 | ||
| 6083 | if (!sym->gcmarkbit && !pure_p) | 6107 | if (!sym->s.gcmarkbit && !pure_p) |
| 6084 | { | 6108 | { |
| 6085 | if (sym->redirect == SYMBOL_LOCALIZED) | 6109 | if (sym->s.redirect == SYMBOL_LOCALIZED) |
| 6086 | xfree (SYMBOL_BLV (sym)); | 6110 | xfree (SYMBOL_BLV (&sym->s)); |
| 6087 | sym->next = symbol_free_list; | 6111 | sym->s.next = symbol_free_list; |
| 6088 | symbol_free_list = sym; | 6112 | symbol_free_list = &sym->s; |
| 6089 | #if GC_MARK_STACK | 6113 | #if GC_MARK_STACK |
| 6090 | symbol_free_list->function = Vdead; | 6114 | symbol_free_list->function = Vdead; |
| 6091 | #endif | 6115 | #endif |
| @@ -6095,8 +6119,8 @@ gc_sweep (void) | |||
| 6095 | { | 6119 | { |
| 6096 | ++num_used; | 6120 | ++num_used; |
| 6097 | if (!pure_p) | 6121 | if (!pure_p) |
| 6098 | UNMARK_STRING (XSTRING (sym->xname)); | 6122 | UNMARK_STRING (XSTRING (sym->s.xname)); |
| 6099 | sym->gcmarkbit = 0; | 6123 | sym->s.gcmarkbit = 0; |
| 6100 | } | 6124 | } |
| 6101 | } | 6125 | } |
| 6102 | 6126 | ||
| @@ -6108,7 +6132,7 @@ gc_sweep (void) | |||
| 6108 | { | 6132 | { |
| 6109 | *sprev = sblk->next; | 6133 | *sprev = sblk->next; |
| 6110 | /* Unhook from the free list. */ | 6134 | /* Unhook from the free list. */ |
| 6111 | symbol_free_list = sblk->symbols[0].next; | 6135 | symbol_free_list = sblk->symbols[0].s.next; |
| 6112 | lisp_free (sblk); | 6136 | lisp_free (sblk); |
| 6113 | } | 6137 | } |
| 6114 | else | 6138 | else |
| @@ -6138,22 +6162,22 @@ gc_sweep (void) | |||
| 6138 | 6162 | ||
| 6139 | for (i = 0; i < lim; i++) | 6163 | for (i = 0; i < lim; i++) |
| 6140 | { | 6164 | { |
| 6141 | if (!mblk->markers[i].u_any.gcmarkbit) | 6165 | if (!mblk->markers[i].m.u_any.gcmarkbit) |
| 6142 | { | 6166 | { |
| 6143 | if (mblk->markers[i].u_any.type == Lisp_Misc_Marker) | 6167 | if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker) |
| 6144 | unchain_marker (&mblk->markers[i].u_marker); | 6168 | unchain_marker (&mblk->markers[i].m.u_marker); |
| 6145 | /* Set the type of the freed object to Lisp_Misc_Free. | 6169 | /* Set the type of the freed object to Lisp_Misc_Free. |
| 6146 | We could leave the type alone, since nobody checks it, | 6170 | We could leave the type alone, since nobody checks it, |
| 6147 | but this might catch bugs faster. */ | 6171 | but this might catch bugs faster. */ |
| 6148 | mblk->markers[i].u_marker.type = Lisp_Misc_Free; | 6172 | mblk->markers[i].m.u_marker.type = Lisp_Misc_Free; |
| 6149 | mblk->markers[i].u_free.chain = marker_free_list; | 6173 | mblk->markers[i].m.u_free.chain = marker_free_list; |
| 6150 | marker_free_list = &mblk->markers[i]; | 6174 | marker_free_list = &mblk->markers[i].m; |
| 6151 | this_free++; | 6175 | this_free++; |
| 6152 | } | 6176 | } |
| 6153 | else | 6177 | else |
| 6154 | { | 6178 | { |
| 6155 | num_used++; | 6179 | num_used++; |
| 6156 | mblk->markers[i].u_any.gcmarkbit = 0; | 6180 | mblk->markers[i].m.u_any.gcmarkbit = 0; |
| 6157 | } | 6181 | } |
| 6158 | } | 6182 | } |
| 6159 | lim = MARKER_BLOCK_SIZE; | 6183 | lim = MARKER_BLOCK_SIZE; |
| @@ -6164,7 +6188,7 @@ gc_sweep (void) | |||
| 6164 | { | 6188 | { |
| 6165 | *mprev = mblk->next; | 6189 | *mprev = mblk->next; |
| 6166 | /* Unhook from the free list. */ | 6190 | /* Unhook from the free list. */ |
| 6167 | marker_free_list = mblk->markers[0].u_free.chain; | 6191 | marker_free_list = mblk->markers[0].m.u_free.chain; |
| 6168 | lisp_free (mblk); | 6192 | lisp_free (mblk); |
| 6169 | } | 6193 | } |
| 6170 | else | 6194 | else |