diff options
| author | Paul Eggert | 2012-04-21 17:53:32 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-04-21 17:53:32 -0700 |
| commit | bbd347f5f7e99da1a559dad818b5fa8f59c0901e (patch) | |
| tree | 77c1fc54c2240b08d2859109d18cac8812a8ffb1 /src/alloc.c | |
| parent | e4ecdc9c71af4199129d5dd2db1a32ff6b725fe4 (diff) | |
| parent | 9ee7d8b93cb143b473e6dffb708e777bc6fe5bd0 (diff) | |
| download | emacs-bbd347f5f7e99da1a559dad818b5fa8f59c0901e.tar.gz emacs-bbd347f5f7e99da1a559dad818b5fa8f59c0901e.zip | |
Merge from trunk.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 114 |
1 files changed, 75 insertions, 39 deletions
diff --git a/src/alloc.c b/src/alloc.c index 27118c91c9c..c07d5c929f9 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -82,6 +82,8 @@ extern POINTER_TYPE *sbrk (); | |||
| 82 | 82 | ||
| 83 | extern size_t _bytes_used; | 83 | extern size_t _bytes_used; |
| 84 | extern size_t __malloc_extra_blocks; | 84 | extern size_t __malloc_extra_blocks; |
| 85 | extern void *_malloc_internal (size_t); | ||
| 86 | extern void _free_internal (void *); | ||
| 85 | 87 | ||
| 86 | #endif /* not DOUG_LEA_MALLOC */ | 88 | #endif /* not DOUG_LEA_MALLOC */ |
| 87 | 89 | ||
| @@ -296,7 +298,6 @@ enum mem_type | |||
| 296 | MEM_TYPE_VECTORLIKE | 298 | MEM_TYPE_VECTORLIKE |
| 297 | }; | 299 | }; |
| 298 | 300 | ||
| 299 | static POINTER_TYPE *lisp_align_malloc (size_t, enum mem_type); | ||
| 300 | static POINTER_TYPE *lisp_malloc (size_t, enum mem_type); | 301 | static POINTER_TYPE *lisp_malloc (size_t, enum mem_type); |
| 301 | 302 | ||
| 302 | 303 | ||
| @@ -315,7 +316,6 @@ static Lisp_Object Vdead; | |||
| 315 | #ifdef GC_MALLOC_CHECK | 316 | #ifdef GC_MALLOC_CHECK |
| 316 | 317 | ||
| 317 | enum mem_type allocated_mem_type; | 318 | enum mem_type allocated_mem_type; |
| 318 | static int dont_register_blocks; | ||
| 319 | 319 | ||
| 320 | #endif /* GC_MALLOC_CHECK */ | 320 | #endif /* GC_MALLOC_CHECK */ |
| 321 | 321 | ||
| @@ -392,8 +392,13 @@ static int live_misc_p (struct mem_node *, void *); | |||
| 392 | static void mark_maybe_object (Lisp_Object); | 392 | static void mark_maybe_object (Lisp_Object); |
| 393 | static void mark_memory (void *, void *); | 393 | static void mark_memory (void *, void *); |
| 394 | static void mem_init (void); | 394 | static void mem_init (void); |
| 395 | #if (defined GC_MALLOC_CHECK \ | ||
| 396 | ? !defined SYSTEM_MALLOC && !defined SYNC_INPUT \ | ||
| 397 | : GC_MARK_STACK) | ||
| 398 | # define NEED_MEM_INSERT | ||
| 395 | static struct mem_node *mem_insert (void *, void *, enum mem_type); | 399 | static struct mem_node *mem_insert (void *, void *, enum mem_type); |
| 396 | static void mem_insert_fixup (struct mem_node *); | 400 | static void mem_insert_fixup (struct mem_node *); |
| 401 | #endif | ||
| 397 | static void mem_rotate_left (struct mem_node *); | 402 | static void mem_rotate_left (struct mem_node *); |
| 398 | static void mem_rotate_right (struct mem_node *); | 403 | static void mem_rotate_right (struct mem_node *); |
| 399 | static void mem_delete (struct mem_node *); | 404 | static void mem_delete (struct mem_node *); |
| @@ -938,13 +943,11 @@ lisp_free (POINTER_TYPE *block) | |||
| 938 | MALLOC_UNBLOCK_INPUT; | 943 | MALLOC_UNBLOCK_INPUT; |
| 939 | } | 944 | } |
| 940 | 945 | ||
| 941 | /* Allocation of aligned blocks of memory to store Lisp data. */ | 946 | /***** Allocation of aligned blocks of memory to store Lisp data. *****/ |
| 942 | /* The entry point is lisp_align_malloc which returns blocks of at most */ | 947 | |
| 943 | /* BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ | 948 | /* The entry point is lisp_align_malloc which returns blocks of at most |
| 949 | BLOCK_BYTES and guarantees they are aligned on a BLOCK_ALIGN boundary. */ | ||
| 944 | 950 | ||
| 945 | /* Use posix_memalloc if the system has it and we're using the system's | ||
| 946 | malloc (because our gmalloc.c routines don't have posix_memalign although | ||
| 947 | its memalloc could be used). */ | ||
| 948 | #if defined (HAVE_POSIX_MEMALIGN) && defined (SYSTEM_MALLOC) | 951 | #if defined (HAVE_POSIX_MEMALIGN) && defined (SYSTEM_MALLOC) |
| 949 | #define USE_POSIX_MEMALIGN 1 | 952 | #define USE_POSIX_MEMALIGN 1 |
| 950 | #endif | 953 | #endif |
| @@ -1001,7 +1004,7 @@ struct ablocks | |||
| 1001 | struct ablock blocks[ABLOCKS_SIZE]; | 1004 | struct ablock blocks[ABLOCKS_SIZE]; |
| 1002 | }; | 1005 | }; |
| 1003 | 1006 | ||
| 1004 | /* Size of the block requested from malloc or memalign. */ | 1007 | /* Size of the block requested from malloc or posix_memalign. */ |
| 1005 | #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) | 1008 | #define ABLOCKS_BYTES (sizeof (struct ablocks) - BLOCK_PADDING) |
| 1006 | 1009 | ||
| 1007 | #define ABLOCK_ABASE(block) \ | 1010 | #define ABLOCK_ABASE(block) \ |
| @@ -1099,7 +1102,7 @@ lisp_align_malloc (size_t nbytes, enum mem_type type) | |||
| 1099 | #endif | 1102 | #endif |
| 1100 | 1103 | ||
| 1101 | /* Initialize the blocks and put them on the free list. | 1104 | /* Initialize the blocks and put them on the free list. |
| 1102 | Is `base' was not properly aligned, we can't use the last block. */ | 1105 | If `base' was not properly aligned, we can't use the last block. */ |
| 1103 | for (i = 0; i < (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1); i++) | 1106 | for (i = 0; i < (aligned ? ABLOCKS_SIZE : ABLOCKS_SIZE - 1); i++) |
| 1104 | { | 1107 | { |
| 1105 | abase->blocks[i].abase = abase; | 1108 | abase->blocks[i].abase = abase; |
| @@ -1146,8 +1149,8 @@ lisp_align_free (POINTER_TYPE *block) | |||
| 1146 | ablock->x.next_free = free_ablock; | 1149 | ablock->x.next_free = free_ablock; |
| 1147 | free_ablock = ablock; | 1150 | free_ablock = ablock; |
| 1148 | /* Update busy count. */ | 1151 | /* Update busy count. */ |
| 1149 | ABLOCKS_BUSY (abase) = | 1152 | ABLOCKS_BUSY (abase) |
| 1150 | (struct ablocks *) (-2 + (intptr_t) ABLOCKS_BUSY (abase)); | 1153 | = (struct ablocks *) (-2 + (intptr_t) ABLOCKS_BUSY (abase)); |
| 1151 | 1154 | ||
| 1152 | if (2 > (intptr_t) ABLOCKS_BUSY (abase)) | 1155 | if (2 > (intptr_t) ABLOCKS_BUSY (abase)) |
| 1153 | { /* All the blocks are free. */ | 1156 | { /* All the blocks are free. */ |
| @@ -1223,6 +1226,10 @@ static void (*old_free_hook) (void*, const void*); | |||
| 1223 | # define BYTES_USED _bytes_used | 1226 | # define BYTES_USED _bytes_used |
| 1224 | #endif | 1227 | #endif |
| 1225 | 1228 | ||
| 1229 | #ifdef GC_MALLOC_CHECK | ||
| 1230 | static int dont_register_blocks; | ||
| 1231 | #endif | ||
| 1232 | |||
| 1226 | static size_t bytes_used_when_reconsidered; | 1233 | static size_t bytes_used_when_reconsidered; |
| 1227 | 1234 | ||
| 1228 | /* Value of _bytes_used, when spare_memory was freed. */ | 1235 | /* Value of _bytes_used, when spare_memory was freed. */ |
| @@ -3137,17 +3144,29 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3137 | Symbol Allocation | 3144 | Symbol Allocation |
| 3138 | ***********************************************************************/ | 3145 | ***********************************************************************/ |
| 3139 | 3146 | ||
| 3147 | /* Like struct Lisp_Symbol, but padded so that the size is a multiple | ||
| 3148 | of the required alignment if LSB tags are used. */ | ||
| 3149 | |||
| 3150 | union aligned_Lisp_Symbol | ||
| 3151 | { | ||
| 3152 | struct Lisp_Symbol s; | ||
| 3153 | #ifdef USE_LSB_TAG | ||
| 3154 | unsigned char c[(sizeof (struct Lisp_Symbol) + (1 << GCTYPEBITS) - 1) | ||
| 3155 | & -(1 << GCTYPEBITS)]; | ||
| 3156 | #endif | ||
| 3157 | }; | ||
| 3158 | |||
| 3140 | /* Each symbol_block is just under 1020 bytes long, since malloc | 3159 | /* Each symbol_block is just under 1020 bytes long, since malloc |
| 3141 | really allocates in units of powers of two and uses 4 bytes for its | 3160 | really allocates in units of powers of two and uses 4 bytes for its |
| 3142 | own overhead. */ | 3161 | own overhead. */ |
| 3143 | 3162 | ||
| 3144 | #define SYMBOL_BLOCK_SIZE \ | 3163 | #define SYMBOL_BLOCK_SIZE \ |
| 3145 | ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) | 3164 | ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) |
| 3146 | 3165 | ||
| 3147 | struct symbol_block | 3166 | struct symbol_block |
| 3148 | { | 3167 | { |
| 3149 | /* Place `symbols' first, to preserve alignment. */ | 3168 | /* Place `symbols' first, to preserve alignment. */ |
| 3150 | struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; | 3169 | union aligned_Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; |
| 3151 | struct symbol_block *next; | 3170 | struct symbol_block *next; |
| 3152 | }; | 3171 | }; |
| 3153 | 3172 | ||
| @@ -3203,7 +3222,7 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3203 | symbol_block = new; | 3222 | symbol_block = new; |
| 3204 | symbol_block_index = 0; | 3223 | symbol_block_index = 0; |
| 3205 | } | 3224 | } |
| 3206 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); | 3225 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index].s); |
| 3207 | symbol_block_index++; | 3226 | symbol_block_index++; |
| 3208 | } | 3227 | } |
| 3209 | 3228 | ||
| @@ -3231,16 +3250,28 @@ Its value and function definition are void, and its property list is nil. */) | |||
| 3231 | Marker (Misc) Allocation | 3250 | Marker (Misc) Allocation |
| 3232 | ***********************************************************************/ | 3251 | ***********************************************************************/ |
| 3233 | 3252 | ||
| 3253 | /* Like union Lisp_Misc, but padded so that its size is a multiple of | ||
| 3254 | the required alignment when LSB tags are used. */ | ||
| 3255 | |||
| 3256 | union aligned_Lisp_Misc | ||
| 3257 | { | ||
| 3258 | union Lisp_Misc m; | ||
| 3259 | #ifdef USE_LSB_TAG | ||
| 3260 | unsigned char c[(sizeof (union Lisp_Misc) + (1 << GCTYPEBITS) - 1) | ||
| 3261 | & -(1 << GCTYPEBITS)]; | ||
| 3262 | #endif | ||
| 3263 | }; | ||
| 3264 | |||
| 3234 | /* Allocation of markers and other objects that share that structure. | 3265 | /* Allocation of markers and other objects that share that structure. |
| 3235 | Works like allocation of conses. */ | 3266 | Works like allocation of conses. */ |
| 3236 | 3267 | ||
| 3237 | #define MARKER_BLOCK_SIZE \ | 3268 | #define MARKER_BLOCK_SIZE \ |
| 3238 | ((1020 - sizeof (struct marker_block *)) / sizeof (union Lisp_Misc)) | 3269 | ((1020 - sizeof (struct marker_block *)) / sizeof (union aligned_Lisp_Misc)) |
| 3239 | 3270 | ||
| 3240 | struct marker_block | 3271 | struct marker_block |
| 3241 | { | 3272 | { |
| 3242 | /* Place `markers' first, to preserve alignment. */ | 3273 | /* Place `markers' first, to preserve alignment. */ |
| 3243 | union Lisp_Misc markers[MARKER_BLOCK_SIZE]; | 3274 | union aligned_Lisp_Misc markers[MARKER_BLOCK_SIZE]; |
| 3244 | struct marker_block *next; | 3275 | struct marker_block *next; |
| 3245 | }; | 3276 | }; |
| 3246 | 3277 | ||
| @@ -3285,7 +3316,7 @@ allocate_misc (void) | |||
| 3285 | marker_block_index = 0; | 3316 | marker_block_index = 0; |
| 3286 | total_free_markers += MARKER_BLOCK_SIZE; | 3317 | total_free_markers += MARKER_BLOCK_SIZE; |
| 3287 | } | 3318 | } |
| 3288 | XSETMISC (val, &marker_block->markers[marker_block_index]); | 3319 | XSETMISC (val, &marker_block->markers[marker_block_index].m); |
| 3289 | marker_block_index++; | 3320 | marker_block_index++; |
| 3290 | } | 3321 | } |
| 3291 | 3322 | ||
| @@ -3548,6 +3579,8 @@ mem_find (void *start) | |||
| 3548 | } | 3579 | } |
| 3549 | 3580 | ||
| 3550 | 3581 | ||
| 3582 | #ifdef NEED_MEM_INSERT | ||
| 3583 | |||
| 3551 | /* Insert a new node into the tree for a block of memory with start | 3584 | /* Insert a new node into the tree for a block of memory with start |
| 3552 | address START, end address END, and type TYPE. Value is a | 3585 | address START, end address END, and type TYPE. Value is a |
| 3553 | pointer to the node that was inserted. */ | 3586 | pointer to the node that was inserted. */ |
| @@ -3695,6 +3728,8 @@ mem_insert_fixup (struct mem_node *x) | |||
| 3695 | mem_root->color = MEM_BLACK; | 3728 | mem_root->color = MEM_BLACK; |
| 3696 | } | 3729 | } |
| 3697 | 3730 | ||
| 3731 | #endif /* NEED_MEM_INSERT */ | ||
| 3732 | |||
| 3698 | 3733 | ||
| 3699 | /* (x) (y) | 3734 | /* (x) (y) |
| 3700 | / \ / \ | 3735 | / \ / \ |
| @@ -6071,22 +6106,22 @@ gc_sweep (void) | |||
| 6071 | for (sblk = symbol_block; sblk; sblk = *sprev) | 6106 | for (sblk = symbol_block; sblk; sblk = *sprev) |
| 6072 | { | 6107 | { |
| 6073 | int this_free = 0; | 6108 | int this_free = 0; |
| 6074 | struct Lisp_Symbol *sym = sblk->symbols; | 6109 | union aligned_Lisp_Symbol *sym = sblk->symbols; |
| 6075 | struct Lisp_Symbol *end = sym + lim; | 6110 | union aligned_Lisp_Symbol *end = sym + lim; |
| 6076 | 6111 | ||
| 6077 | for (; sym < end; ++sym) | 6112 | for (; sym < end; ++sym) |
| 6078 | { | 6113 | { |
| 6079 | /* Check if the symbol was created during loadup. In such a case | 6114 | /* Check if the symbol was created during loadup. In such a case |
| 6080 | it might be pointed to by pure bytecode which we don't trace, | 6115 | it might be pointed to by pure bytecode which we don't trace, |
| 6081 | so we conservatively assume that it is live. */ | 6116 | so we conservatively assume that it is live. */ |
| 6082 | int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); | 6117 | int pure_p = PURE_POINTER_P (XSTRING (sym->s.xname)); |
| 6083 | 6118 | ||
| 6084 | if (!sym->gcmarkbit && !pure_p) | 6119 | if (!sym->s.gcmarkbit && !pure_p) |
| 6085 | { | 6120 | { |
| 6086 | if (sym->redirect == SYMBOL_LOCALIZED) | 6121 | if (sym->s.redirect == SYMBOL_LOCALIZED) |
| 6087 | xfree (SYMBOL_BLV (sym)); | 6122 | xfree (SYMBOL_BLV (&sym->s)); |
| 6088 | sym->next = symbol_free_list; | 6123 | sym->s.next = symbol_free_list; |
| 6089 | symbol_free_list = sym; | 6124 | symbol_free_list = &sym->s; |
| 6090 | #if GC_MARK_STACK | 6125 | #if GC_MARK_STACK |
| 6091 | symbol_free_list->function = Vdead; | 6126 | symbol_free_list->function = Vdead; |
| 6092 | #endif | 6127 | #endif |
| @@ -6096,8 +6131,8 @@ gc_sweep (void) | |||
| 6096 | { | 6131 | { |
| 6097 | ++num_used; | 6132 | ++num_used; |
| 6098 | if (!pure_p) | 6133 | if (!pure_p) |
| 6099 | UNMARK_STRING (XSTRING (sym->xname)); | 6134 | UNMARK_STRING (XSTRING (sym->s.xname)); |
| 6100 | sym->gcmarkbit = 0; | 6135 | sym->s.gcmarkbit = 0; |
| 6101 | } | 6136 | } |
| 6102 | } | 6137 | } |
| 6103 | 6138 | ||
| @@ -6109,7 +6144,7 @@ gc_sweep (void) | |||
| 6109 | { | 6144 | { |
| 6110 | *sprev = sblk->next; | 6145 | *sprev = sblk->next; |
| 6111 | /* Unhook from the free list. */ | 6146 | /* Unhook from the free list. */ |
| 6112 | symbol_free_list = sblk->symbols[0].next; | 6147 | symbol_free_list = sblk->symbols[0].s.next; |
| 6113 | lisp_free (sblk); | 6148 | lisp_free (sblk); |
| 6114 | } | 6149 | } |
| 6115 | else | 6150 | else |
| @@ -6139,22 +6174,22 @@ gc_sweep (void) | |||
| 6139 | 6174 | ||
| 6140 | for (i = 0; i < lim; i++) | 6175 | for (i = 0; i < lim; i++) |
| 6141 | { | 6176 | { |
| 6142 | if (!mblk->markers[i].u_any.gcmarkbit) | 6177 | if (!mblk->markers[i].m.u_any.gcmarkbit) |
| 6143 | { | 6178 | { |
| 6144 | if (mblk->markers[i].u_any.type == Lisp_Misc_Marker) | 6179 | if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker) |
| 6145 | unchain_marker (&mblk->markers[i].u_marker); | 6180 | unchain_marker (&mblk->markers[i].m.u_marker); |
| 6146 | /* Set the type of the freed object to Lisp_Misc_Free. | 6181 | /* Set the type of the freed object to Lisp_Misc_Free. |
| 6147 | We could leave the type alone, since nobody checks it, | 6182 | We could leave the type alone, since nobody checks it, |
| 6148 | but this might catch bugs faster. */ | 6183 | but this might catch bugs faster. */ |
| 6149 | mblk->markers[i].u_marker.type = Lisp_Misc_Free; | 6184 | mblk->markers[i].m.u_marker.type = Lisp_Misc_Free; |
| 6150 | mblk->markers[i].u_free.chain = marker_free_list; | 6185 | mblk->markers[i].m.u_free.chain = marker_free_list; |
| 6151 | marker_free_list = &mblk->markers[i]; | 6186 | marker_free_list = &mblk->markers[i].m; |
| 6152 | this_free++; | 6187 | this_free++; |
| 6153 | } | 6188 | } |
| 6154 | else | 6189 | else |
| 6155 | { | 6190 | { |
| 6156 | num_used++; | 6191 | num_used++; |
| 6157 | mblk->markers[i].u_any.gcmarkbit = 0; | 6192 | mblk->markers[i].m.u_any.gcmarkbit = 0; |
| 6158 | } | 6193 | } |
| 6159 | } | 6194 | } |
| 6160 | lim = MARKER_BLOCK_SIZE; | 6195 | lim = MARKER_BLOCK_SIZE; |
| @@ -6165,7 +6200,7 @@ gc_sweep (void) | |||
| 6165 | { | 6200 | { |
| 6166 | *mprev = mblk->next; | 6201 | *mprev = mblk->next; |
| 6167 | /* Unhook from the free list. */ | 6202 | /* Unhook from the free list. */ |
| 6168 | marker_free_list = mblk->markers[0].u_free.chain; | 6203 | marker_free_list = mblk->markers[0].m.u_free.chain; |
| 6169 | lisp_free (mblk); | 6204 | lisp_free (mblk); |
| 6170 | } | 6205 | } |
| 6171 | else | 6206 | else |
| @@ -6297,11 +6332,12 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max) | |||
| 6297 | { | 6332 | { |
| 6298 | for (sblk = symbol_block; sblk; sblk = sblk->next) | 6333 | for (sblk = symbol_block; sblk; sblk = sblk->next) |
| 6299 | { | 6334 | { |
| 6300 | struct Lisp_Symbol *sym = sblk->symbols; | 6335 | union aligned_Lisp_Symbol *aligned_sym = sblk->symbols; |
| 6301 | int bn; | 6336 | int bn; |
| 6302 | 6337 | ||
| 6303 | for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, sym++) | 6338 | for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++) |
| 6304 | { | 6339 | { |
| 6340 | struct Lisp_Symbol *sym = &aligned_sym->s; | ||
| 6305 | Lisp_Object val; | 6341 | Lisp_Object val; |
| 6306 | Lisp_Object tem; | 6342 | Lisp_Object tem; |
| 6307 | 6343 | ||