diff options
| author | Stefan Monnier | 2003-07-15 19:19:59 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2003-07-15 19:19:59 +0000 |
| commit | 08b7c2cbf381616c51799da3981e32c442655a6b (patch) | |
| tree | 6e49036fdb43fba33a55671d371d052c03d97cfc /src/alloc.c | |
| parent | dd038e2602ee6ce7614ffbd19b2046cf0d7dd83a (diff) | |
| download | emacs-08b7c2cbf381616c51799da3981e32c442655a6b.tar.gz emacs-08b7c2cbf381616c51799da3981e32c442655a6b.zip | |
Use bitmaps for cons cells, as was done for floats.
(init_float, init_cons): Let the normal code allocate the first block.
(CONS_BLOCK_SIZE): Redefine based on BLOCK_BYTES and bitmap size.
(CONS_BLOCK, CONS_INDEX, CONS_MARKED_P, CONS_MARK, CONS_UNMARK): New macros.
(struct cons_block): Move conses to the beginning. Add gcmarkbits.
(Fcons): Use lisp_align_malloc and CONS_UNMARK.
(live_cons_p): Check the pointer is not past the `conses' array.
(mark_maybe_object, mark_maybe_pointer): Use CONS_MARKED_P.
(mark_object, mark_buffer): Use CONS_MARKED_P and CONS_MARK.
(survives_gc_p): Use CONS_MARKED_P and simplify.
(gc_sweep): Use CONS_MARKED_P, CONS_UNMARK, and lisp_align_free.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 94 |
1 files changed, 45 insertions, 49 deletions
diff --git a/src/alloc.c b/src/alloc.c index 18770929532..ea93ba0070a 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2183,14 +2183,10 @@ struct Lisp_Float *float_free_list; | |||
| 2183 | void | 2183 | void |
| 2184 | init_float () | 2184 | init_float () |
| 2185 | { | 2185 | { |
| 2186 | float_block = (struct float_block *) lisp_align_malloc (sizeof *float_block, | 2186 | float_block = NULL; |
| 2187 | MEM_TYPE_FLOAT); | 2187 | float_block_index = FLOAT_BLOCK_SIZE; /* Force alloc of new float_block. */ |
| 2188 | float_block->next = 0; | ||
| 2189 | bzero ((char *) float_block->floats, sizeof float_block->floats); | ||
| 2190 | bzero ((char *) float_block->gcmarkbits, sizeof float_block->gcmarkbits); | ||
| 2191 | float_block_index = 0; | ||
| 2192 | float_free_list = 0; | 2188 | float_free_list = 0; |
| 2193 | n_float_blocks = 1; | 2189 | n_float_blocks = 0; |
| 2194 | } | 2190 | } |
| 2195 | 2191 | ||
| 2196 | 2192 | ||
| @@ -2252,21 +2248,35 @@ make_float (float_value) | |||
| 2252 | /* We store cons cells inside of cons_blocks, allocating a new | 2248 | /* We store cons cells inside of cons_blocks, allocating a new |
| 2253 | cons_block with malloc whenever necessary. Cons cells reclaimed by | 2249 | cons_block with malloc whenever necessary. Cons cells reclaimed by |
| 2254 | GC are put on a free list to be reallocated before allocating | 2250 | GC are put on a free list to be reallocated before allocating |
| 2255 | any new cons cells from the latest cons_block. | 2251 | any new cons cells from the latest cons_block. */ |
| 2256 | |||
| 2257 | Each cons_block is just under 1020 bytes long, | ||
| 2258 | since malloc really allocates in units of powers of two | ||
| 2259 | and uses 4 bytes for its own overhead. */ | ||
| 2260 | 2252 | ||
| 2261 | #define CONS_BLOCK_SIZE \ | 2253 | #define CONS_BLOCK_SIZE \ |
| 2262 | ((1020 - sizeof (struct cons_block *)) / sizeof (struct Lisp_Cons)) | 2254 | (((BLOCK_BYTES - sizeof (struct cons_block *)) * CHAR_BIT) \ |
| 2255 | / (sizeof (struct Lisp_Cons) * CHAR_BIT + 1)) | ||
| 2256 | |||
| 2257 | #define CONS_BLOCK(fptr) \ | ||
| 2258 | ((struct cons_block *)(((EMACS_UINT)(fptr)) & ~(BLOCK_ALIGN - 1))) | ||
| 2259 | |||
| 2260 | #define CONS_INDEX(fptr) \ | ||
| 2261 | ((((EMACS_UINT)(fptr)) & (BLOCK_ALIGN - 1)) / sizeof (struct Lisp_Cons)) | ||
| 2263 | 2262 | ||
| 2264 | struct cons_block | 2263 | struct cons_block |
| 2265 | { | 2264 | { |
| 2266 | struct cons_block *next; | 2265 | /* Place `conses' at the beginning, to ease up CONS_INDEX's job. */ |
| 2267 | struct Lisp_Cons conses[CONS_BLOCK_SIZE]; | 2266 | struct Lisp_Cons conses[CONS_BLOCK_SIZE]; |
| 2267 | int gcmarkbits[1 + CONS_BLOCK_SIZE / (sizeof(int) * CHAR_BIT)]; | ||
| 2268 | struct cons_block *next; | ||
| 2268 | }; | 2269 | }; |
| 2269 | 2270 | ||
| 2271 | #define CONS_MARKED_P(fptr) \ | ||
| 2272 | GETMARKBIT (CONS_BLOCK (fptr), CONS_INDEX ((fptr))) | ||
| 2273 | |||
| 2274 | #define CONS_MARK(fptr) \ | ||
| 2275 | SETMARKBIT (CONS_BLOCK (fptr), CONS_INDEX ((fptr))) | ||
| 2276 | |||
| 2277 | #define CONS_UNMARK(fptr) \ | ||
| 2278 | UNSETMARKBIT (CONS_BLOCK (fptr), CONS_INDEX ((fptr))) | ||
| 2279 | |||
| 2270 | /* Current cons_block. */ | 2280 | /* Current cons_block. */ |
| 2271 | 2281 | ||
| 2272 | struct cons_block *cons_block; | 2282 | struct cons_block *cons_block; |
| @@ -2289,13 +2299,10 @@ int n_cons_blocks; | |||
| 2289 | void | 2299 | void |
| 2290 | init_cons () | 2300 | init_cons () |
| 2291 | { | 2301 | { |
| 2292 | cons_block = (struct cons_block *) lisp_malloc (sizeof *cons_block, | 2302 | cons_block = NULL; |
| 2293 | MEM_TYPE_CONS); | 2303 | cons_block_index = CONS_BLOCK_SIZE; /* Force alloc of new cons_block. */ |
| 2294 | cons_block->next = 0; | ||
| 2295 | bzero ((char *) cons_block->conses, sizeof cons_block->conses); | ||
| 2296 | cons_block_index = 0; | ||
| 2297 | cons_free_list = 0; | 2304 | cons_free_list = 0; |
| 2298 | n_cons_blocks = 1; | 2305 | n_cons_blocks = 0; |
| 2299 | } | 2306 | } |
| 2300 | 2307 | ||
| 2301 | 2308 | ||
| @@ -2332,8 +2339,8 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2332 | if (cons_block_index == CONS_BLOCK_SIZE) | 2339 | if (cons_block_index == CONS_BLOCK_SIZE) |
| 2333 | { | 2340 | { |
| 2334 | register struct cons_block *new; | 2341 | register struct cons_block *new; |
| 2335 | new = (struct cons_block *) lisp_malloc (sizeof *new, | 2342 | new = (struct cons_block *) lisp_align_malloc (sizeof *new, |
| 2336 | MEM_TYPE_CONS); | 2343 | MEM_TYPE_CONS); |
| 2337 | new->next = cons_block; | 2344 | new->next = cons_block; |
| 2338 | cons_block = new; | 2345 | cons_block = new; |
| 2339 | cons_block_index = 0; | 2346 | cons_block_index = 0; |
| @@ -2344,6 +2351,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2344 | 2351 | ||
| 2345 | XSETCAR (val, car); | 2352 | XSETCAR (val, car); |
| 2346 | XSETCDR (val, cdr); | 2353 | XSETCDR (val, cdr); |
| 2354 | CONS_UNMARK (XCONS (val)); | ||
| 2347 | consing_since_gc += sizeof (struct Lisp_Cons); | 2355 | consing_since_gc += sizeof (struct Lisp_Cons); |
| 2348 | cons_cells_consed++; | 2356 | cons_cells_consed++; |
| 2349 | return val; | 2357 | return val; |
| @@ -3435,6 +3443,7 @@ live_cons_p (m, p) | |||
| 3435 | one of the unused cells in the current cons block, | 3443 | one of the unused cells in the current cons block, |
| 3436 | and not be on the free-list. */ | 3444 | and not be on the free-list. */ |
| 3437 | return (offset >= 0 | 3445 | return (offset >= 0 |
| 3446 | && offset < (CONS_BLOCK_SIZE * sizeof b->conses[0]) | ||
| 3438 | && offset % sizeof b->conses[0] == 0 | 3447 | && offset % sizeof b->conses[0] == 0 |
| 3439 | && (b != cons_block | 3448 | && (b != cons_block |
| 3440 | || offset / sizeof b->conses[0] < cons_block_index) | 3449 | || offset / sizeof b->conses[0] < cons_block_index) |
| @@ -3629,8 +3638,7 @@ mark_maybe_object (obj) | |||
| 3629 | break; | 3638 | break; |
| 3630 | 3639 | ||
| 3631 | case Lisp_Cons: | 3640 | case Lisp_Cons: |
| 3632 | mark_p = (live_cons_p (m, po) | 3641 | mark_p = (live_cons_p (m, po) && !CONS_MARKED_P (XCONS (obj))); |
| 3633 | && !XMARKBIT (XCONS (obj)->car)); | ||
| 3634 | break; | 3642 | break; |
| 3635 | 3643 | ||
| 3636 | case Lisp_Symbol: | 3644 | case Lisp_Symbol: |
| @@ -3704,8 +3712,7 @@ mark_maybe_pointer (p) | |||
| 3704 | break; | 3712 | break; |
| 3705 | 3713 | ||
| 3706 | case MEM_TYPE_CONS: | 3714 | case MEM_TYPE_CONS: |
| 3707 | if (live_cons_p (m, p) | 3715 | if (live_cons_p (m, p) && !CONS_MARKED_P ((struct Lisp_Cons *) p)) |
| 3708 | && !XMARKBIT (((struct Lisp_Cons *) p)->car)) | ||
| 3709 | XSETCONS (obj, p); | 3716 | XSETCONS (obj, p); |
| 3710 | break; | 3717 | break; |
| 3711 | 3718 | ||
| @@ -4405,8 +4412,6 @@ returns nil, because real GC can't be done. */) | |||
| 4405 | for (i = 0; i < tail->nvars; i++) | 4412 | for (i = 0; i < tail->nvars; i++) |
| 4406 | if (!XMARKBIT (tail->var[i])) | 4413 | if (!XMARKBIT (tail->var[i])) |
| 4407 | { | 4414 | { |
| 4408 | /* Explicit casting prevents compiler warning about | ||
| 4409 | discarding the `volatile' qualifier. */ | ||
| 4410 | mark_object (tail->var[i]); | 4415 | mark_object (tail->var[i]); |
| 4411 | XMARK (tail->var[i]); | 4416 | XMARK (tail->var[i]); |
| 4412 | } | 4417 | } |
| @@ -4416,7 +4421,6 @@ returns nil, because real GC can't be done. */) | |||
| 4416 | mark_byte_stack (); | 4421 | mark_byte_stack (); |
| 4417 | for (bind = specpdl; bind != specpdl_ptr; bind++) | 4422 | for (bind = specpdl; bind != specpdl_ptr; bind++) |
| 4418 | { | 4423 | { |
| 4419 | /* These casts avoid a warning for discarding `volatile'. */ | ||
| 4420 | mark_object (bind->symbol); | 4424 | mark_object (bind->symbol); |
| 4421 | mark_object (bind->old_value); | 4425 | mark_object (bind->old_value); |
| 4422 | } | 4426 | } |
| @@ -5044,9 +5048,9 @@ mark_object (arg) | |||
| 5044 | case Lisp_Cons: | 5048 | case Lisp_Cons: |
| 5045 | { | 5049 | { |
| 5046 | register struct Lisp_Cons *ptr = XCONS (obj); | 5050 | register struct Lisp_Cons *ptr = XCONS (obj); |
| 5047 | if (XMARKBIT (ptr->car)) break; | 5051 | if (CONS_MARKED_P (ptr)) break; |
| 5048 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); | 5052 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); |
| 5049 | XMARK (ptr->car); | 5053 | CONS_MARK (ptr); |
| 5050 | /* If the cdr is nil, avoid recursion for the car. */ | 5054 | /* If the cdr is nil, avoid recursion for the car. */ |
| 5051 | if (EQ (ptr->cdr, Qnil)) | 5055 | if (EQ (ptr->cdr, Qnil)) |
| 5052 | { | 5056 | { |
| @@ -5105,14 +5109,14 @@ mark_buffer (buf) | |||
| 5105 | { | 5109 | { |
| 5106 | register struct Lisp_Cons *ptr = XCONS (tail); | 5110 | register struct Lisp_Cons *ptr = XCONS (tail); |
| 5107 | 5111 | ||
| 5108 | if (XMARKBIT (ptr->car)) | 5112 | if (CONS_MARKED_P (ptr)) |
| 5109 | break; | 5113 | break; |
| 5110 | XMARK (ptr->car); | 5114 | CONS_MARK (ptr); |
| 5111 | if (GC_CONSP (ptr->car) | 5115 | if (GC_CONSP (ptr->car) |
| 5112 | && ! XMARKBIT (XCAR (ptr->car)) | 5116 | && !CONS_MARKED_P (XCONS (ptr->car)) |
| 5113 | && GC_MARKERP (XCAR (ptr->car))) | 5117 | && GC_MARKERP (XCAR (ptr->car))) |
| 5114 | { | 5118 | { |
| 5115 | XMARK (XCAR_AS_LVALUE (ptr->car)); | 5119 | CONS_MARK (XCONS (ptr->car)); |
| 5116 | mark_object (XCDR (ptr->car)); | 5120 | mark_object (XCDR (ptr->car)); |
| 5117 | } | 5121 | } |
| 5118 | else | 5122 | else |
| @@ -5178,23 +5182,15 @@ survives_gc_p (obj) | |||
| 5178 | break; | 5182 | break; |
| 5179 | 5183 | ||
| 5180 | case Lisp_String: | 5184 | case Lisp_String: |
| 5181 | { | 5185 | survives_p = STRING_MARKED_P (XSTRING (obj)); |
| 5182 | struct Lisp_String *s = XSTRING (obj); | ||
| 5183 | survives_p = STRING_MARKED_P (s); | ||
| 5184 | } | ||
| 5185 | break; | 5186 | break; |
| 5186 | 5187 | ||
| 5187 | case Lisp_Vectorlike: | 5188 | case Lisp_Vectorlike: |
| 5188 | if (GC_BUFFERP (obj)) | 5189 | survives_p = GC_SUBRP (obj) || VECTOR_MARKED_P (XVECTOR (obj)); |
| 5189 | survives_p = VECTOR_MARKED_P (XBUFFER (obj)); | ||
| 5190 | else if (GC_SUBRP (obj)) | ||
| 5191 | survives_p = 1; | ||
| 5192 | else | ||
| 5193 | survives_p = VECTOR_MARKED_P (XVECTOR (obj)); | ||
| 5194 | break; | 5190 | break; |
| 5195 | 5191 | ||
| 5196 | case Lisp_Cons: | 5192 | case Lisp_Cons: |
| 5197 | survives_p = XMARKBIT (XCAR (obj)); | 5193 | survives_p = CONS_MARKED_P (XCONS (obj)); |
| 5198 | break; | 5194 | break; |
| 5199 | 5195 | ||
| 5200 | case Lisp_Float: | 5196 | case Lisp_Float: |
| @@ -5239,7 +5235,7 @@ gc_sweep () | |||
| 5239 | register int i; | 5235 | register int i; |
| 5240 | int this_free = 0; | 5236 | int this_free = 0; |
| 5241 | for (i = 0; i < lim; i++) | 5237 | for (i = 0; i < lim; i++) |
| 5242 | if (!XMARKBIT (cblk->conses[i].car)) | 5238 | if (!CONS_MARKED_P (&cblk->conses[i])) |
| 5243 | { | 5239 | { |
| 5244 | this_free++; | 5240 | this_free++; |
| 5245 | *(struct Lisp_Cons **)&cblk->conses[i].cdr = cons_free_list; | 5241 | *(struct Lisp_Cons **)&cblk->conses[i].cdr = cons_free_list; |
| @@ -5251,7 +5247,7 @@ gc_sweep () | |||
| 5251 | else | 5247 | else |
| 5252 | { | 5248 | { |
| 5253 | num_used++; | 5249 | num_used++; |
| 5254 | XUNMARK (cblk->conses[i].car); | 5250 | CONS_UNMARK (&cblk->conses[i]); |
| 5255 | } | 5251 | } |
| 5256 | lim = CONS_BLOCK_SIZE; | 5252 | lim = CONS_BLOCK_SIZE; |
| 5257 | /* If this block contains only free conses and we have already | 5253 | /* If this block contains only free conses and we have already |
| @@ -5262,7 +5258,7 @@ gc_sweep () | |||
| 5262 | *cprev = cblk->next; | 5258 | *cprev = cblk->next; |
| 5263 | /* Unhook from the free list. */ | 5259 | /* Unhook from the free list. */ |
| 5264 | cons_free_list = *(struct Lisp_Cons **) &cblk->conses[0].cdr; | 5260 | cons_free_list = *(struct Lisp_Cons **) &cblk->conses[0].cdr; |
| 5265 | lisp_free (cblk); | 5261 | lisp_align_free (cblk); |
| 5266 | n_cons_blocks--; | 5262 | n_cons_blocks--; |
| 5267 | } | 5263 | } |
| 5268 | else | 5264 | else |