aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorStefan Monnier2003-07-15 19:19:59 +0000
committerStefan Monnier2003-07-15 19:19:59 +0000
commit08b7c2cbf381616c51799da3981e32c442655a6b (patch)
tree6e49036fdb43fba33a55671d371d052c03d97cfc /src/alloc.c
parentdd038e2602ee6ce7614ffbd19b2046cf0d7dd83a (diff)
downloademacs-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.c94
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;
2183void 2183void
2184init_float () 2184init_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
2264struct cons_block 2263struct 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
2272struct cons_block *cons_block; 2282struct cons_block *cons_block;
@@ -2289,13 +2299,10 @@ int n_cons_blocks;
2289void 2299void
2290init_cons () 2300init_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