comparison src/alloc.c @ 51683:fb960854a12c

(VECTOR_MARK, VECTOR_UNMARK, VECTOR_MARKED_P): New macros. (GC_STRING_BYTES): Don't mask markbit (it's only used on `size'). (allocate_buffer): Move. (string_bytes): Don't mask markbit of `size_byte'. (mark_maybe_object, mark_maybe_pointer, Fgarbage_collect) (mark_object, mark_buffer, survives_gc_p, gc_sweep): Use the `size' field of buffers (rather than the `name' field) for the mark bit, as is done for all other vectorlike objects. Use the new macros to access the mark bit of vectorlike objects.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 27 Jun 2003 21:54:20 +0000
parents 0f333fd92a1d
children 17c015f1f795
comparison
equal deleted inserted replaced
51682:f4620c9305c7 51683:fb960854a12c
93 93
94 #define MARK_STRING(S) ((S)->size |= MARKBIT) 94 #define MARK_STRING(S) ((S)->size |= MARKBIT)
95 #define UNMARK_STRING(S) ((S)->size &= ~MARKBIT) 95 #define UNMARK_STRING(S) ((S)->size &= ~MARKBIT)
96 #define STRING_MARKED_P(S) ((S)->size & MARKBIT) 96 #define STRING_MARKED_P(S) ((S)->size & MARKBIT)
97 97
98 #define VECTOR_MARK(V) ((V)->size |= ARRAY_MARK_FLAG)
99 #define VECTOR_UNMARK(V) ((V)->size &= ~ARRAY_MARK_FLAG)
100 #define VECTOR_MARKED_P(V) ((V)->size & ARRAY_MARK_FLAG)
101
98 /* Value is the number of bytes/chars of S, a pointer to a struct 102 /* Value is the number of bytes/chars of S, a pointer to a struct
99 Lisp_String. This must be used instead of STRING_BYTES (S) or 103 Lisp_String. This must be used instead of STRING_BYTES (S) or
100 S->size during GC, because S->size contains the mark bit for 104 S->size during GC, because S->size contains the mark bit for
101 strings. */ 105 strings. */
102 106
103 #define GC_STRING_BYTES(S) (STRING_BYTES (S) & ~MARKBIT) 107 #define GC_STRING_BYTES(S) (STRING_BYTES (S))
104 #define GC_STRING_CHARS(S) ((S)->size & ~MARKBIT) 108 #define GC_STRING_CHARS(S) ((S)->size & ~MARKBIT)
105 109
106 /* Number of bytes of consing done since the last gc. */ 110 /* Number of bytes of consing done since the last gc. */
107 111
108 int consing_since_gc; 112 int consing_since_gc;
614 if (!val && nbytes) 618 if (!val && nbytes)
615 memory_full (); 619 memory_full ();
616 return val; 620 return val;
617 } 621 }
618 622
619
620 /* Return a new buffer structure allocated from the heap with
621 a call to lisp_malloc. */
622
623 struct buffer *
624 allocate_buffer ()
625 {
626 struct buffer *b
627 = (struct buffer *) lisp_malloc (sizeof (struct buffer),
628 MEM_TYPE_BUFFER);
629 return b;
630 }
631
632
633 /* Free BLOCK. This must be called to free memory allocated with a 623 /* Free BLOCK. This must be called to free memory allocated with a
634 call to lisp_malloc. */ 624 call to lisp_malloc. */
635 625
636 static void 626 static void
637 lisp_free (block) 627 lisp_free (block)
641 free (block); 631 free (block);
642 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK 632 #if GC_MARK_STACK && !defined GC_MALLOC_CHECK
643 mem_delete (mem_find (block)); 633 mem_delete (mem_find (block));
644 #endif 634 #endif
645 UNBLOCK_INPUT; 635 UNBLOCK_INPUT;
636 }
637
638
639 /* Return a new buffer structure allocated from the heap with
640 a call to lisp_malloc. */
641
642 struct buffer *
643 allocate_buffer ()
644 {
645 struct buffer *b
646 = (struct buffer *) lisp_malloc (sizeof (struct buffer),
647 MEM_TYPE_BUFFER);
648 return b;
646 } 649 }
647 650
648 651
649 /* Arranging to disable input signals while we're in malloc. 652 /* Arranging to disable input signals while we're in malloc.
650 653
1221 1224
1222 int 1225 int
1223 string_bytes (s) 1226 string_bytes (s)
1224 struct Lisp_String *s; 1227 struct Lisp_String *s;
1225 { 1228 {
1226 int nbytes = (s->size_byte < 0 ? s->size : s->size_byte) & ~MARKBIT; 1229 int nbytes = (s->size_byte < 0 ? s->size & ~MARKBIT : s->size_byte);
1227 if (!PURE_POINTER_P (s) 1230 if (!PURE_POINTER_P (s)
1228 && s->data 1231 && s->data
1229 && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) 1232 && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s)))
1230 abort (); 1233 abort ();
1231 return nbytes; 1234 return nbytes;
3398 case Lisp_Vectorlike: 3401 case Lisp_Vectorlike:
3399 /* Note: can't check GC_BUFFERP before we know it's a 3402 /* Note: can't check GC_BUFFERP before we know it's a
3400 buffer because checking that dereferences the pointer 3403 buffer because checking that dereferences the pointer
3401 PO which might point anywhere. */ 3404 PO which might point anywhere. */
3402 if (live_vector_p (m, po)) 3405 if (live_vector_p (m, po))
3403 mark_p = (!GC_SUBRP (obj) 3406 mark_p = !GC_SUBRP (obj) && !VECTOR_MARKED_P (XVECTOR (obj));
3404 && !(XVECTOR (obj)->size & ARRAY_MARK_FLAG));
3405 else if (live_buffer_p (m, po)) 3407 else if (live_buffer_p (m, po))
3406 mark_p = GC_BUFFERP (obj) && !XMARKBIT (XBUFFER (obj)->name); 3408 mark_p = GC_BUFFERP (obj) && !VECTOR_MARKED_P (XBUFFER (obj));
3407 break; 3409 break;
3408 3410
3409 case Lisp_Misc: 3411 case Lisp_Misc:
3410 mark_p = (live_misc_p (m, po) && !XMARKER (obj)->gcmarkbit); 3412 mark_p = (live_misc_p (m, po) && !XMARKER (obj)->gcmarkbit);
3411 break; 3413 break;
3452 case MEM_TYPE_NON_LISP: 3454 case MEM_TYPE_NON_LISP:
3453 /* Nothing to do; not a pointer to Lisp memory. */ 3455 /* Nothing to do; not a pointer to Lisp memory. */
3454 break; 3456 break;
3455 3457
3456 case MEM_TYPE_BUFFER: 3458 case MEM_TYPE_BUFFER:
3457 if (live_buffer_p (m, p) 3459 if (live_buffer_p (m, p) && !VECTOR_MARKED_P((struct buffer *)p))
3458 && !XMARKBIT (((struct buffer *) p)->name))
3459 XSETVECTOR (obj, p); 3460 XSETVECTOR (obj, p);
3460 break; 3461 break;
3461 3462
3462 case MEM_TYPE_CONS: 3463 case MEM_TYPE_CONS:
3463 if (live_cons_p (m, p) 3464 if (live_cons_p (m, p)
3494 case MEM_TYPE_WINDOW: 3495 case MEM_TYPE_WINDOW:
3495 if (live_vector_p (m, p)) 3496 if (live_vector_p (m, p))
3496 { 3497 {
3497 Lisp_Object tem; 3498 Lisp_Object tem;
3498 XSETVECTOR (tem, p); 3499 XSETVECTOR (tem, p);
3499 if (!GC_SUBRP (tem) 3500 if (!GC_SUBRP (tem) && !VECTOR_MARKED_P (XVECTOR (tem)))
3500 && !(XVECTOR (tem)->size & ARRAY_MARK_FLAG))
3501 obj = tem; 3501 obj = tem;
3502 } 3502 }
3503 break; 3503 break;
3504 3504
3505 default: 3505 default:
4284 else 4284 else
4285 i = backlist->nargs - 1; 4285 i = backlist->nargs - 1;
4286 for (; i >= 0; i--) 4286 for (; i >= 0; i--)
4287 XUNMARK (backlist->args[i]); 4287 XUNMARK (backlist->args[i]);
4288 } 4288 }
4289 XUNMARK (buffer_defaults.name); 4289 VECTOR_UNMARK (&buffer_defaults);
4290 XUNMARK (buffer_local_symbols.name); 4290 VECTOR_UNMARK (&buffer_local_symbols);
4291 4291
4292 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES && 0 4292 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES && 0
4293 dump_zombies (); 4293 dump_zombies ();
4294 #endif 4294 #endif
4295 4295
4546 abort (); 4546 abort ();
4547 #endif /* GC_CHECK_MARKED_OBJECTS */ 4547 #endif /* GC_CHECK_MARKED_OBJECTS */
4548 4548
4549 if (GC_BUFFERP (obj)) 4549 if (GC_BUFFERP (obj))
4550 { 4550 {
4551 if (!XMARKBIT (XBUFFER (obj)->name)) 4551 if (!VECTOR_MARKED_P (XBUFFER (obj)))
4552 { 4552 {
4553 #ifdef GC_CHECK_MARKED_OBJECTS 4553 #ifdef GC_CHECK_MARKED_OBJECTS
4554 if (po != &buffer_defaults && po != &buffer_local_symbols) 4554 if (po != &buffer_defaults && po != &buffer_local_symbols)
4555 { 4555 {
4556 struct buffer *b; 4556 struct buffer *b;
4572 { 4572 {
4573 register struct Lisp_Vector *ptr = XVECTOR (obj); 4573 register struct Lisp_Vector *ptr = XVECTOR (obj);
4574 register EMACS_INT size = ptr->size; 4574 register EMACS_INT size = ptr->size;
4575 register int i; 4575 register int i;
4576 4576
4577 if (size & ARRAY_MARK_FLAG) 4577 if (VECTOR_MARKED_P (ptr))
4578 break; /* Already marked */ 4578 break; /* Already marked */
4579 4579
4580 CHECK_LIVE (live_vector_p); 4580 CHECK_LIVE (live_vector_p);
4581 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ 4581 VECTOR_MARK (ptr); /* Else mark it */
4582 size &= PSEUDOVECTOR_SIZE_MASK; 4582 size &= PSEUDOVECTOR_SIZE_MASK;
4583 for (i = 0; i < size; i++) /* and then mark its elements */ 4583 for (i = 0; i < size; i++) /* and then mark its elements */
4584 { 4584 {
4585 if (i != COMPILED_CONSTANTS) 4585 if (i != COMPILED_CONSTANTS)
4586 mark_object (&ptr->contents[i]); 4586 mark_object (&ptr->contents[i]);
4591 goto loop; 4591 goto loop;
4592 } 4592 }
4593 else if (GC_FRAMEP (obj)) 4593 else if (GC_FRAMEP (obj))
4594 { 4594 {
4595 register struct frame *ptr = XFRAME (obj); 4595 register struct frame *ptr = XFRAME (obj);
4596 register EMACS_INT size = ptr->size; 4596
4597 4597 if (VECTOR_MARKED_P (ptr)) break; /* Already marked */
4598 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ 4598 VECTOR_MARK (ptr); /* Else mark it */
4599 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
4600 4599
4601 CHECK_LIVE (live_vector_p); 4600 CHECK_LIVE (live_vector_p);
4602 mark_object (&ptr->name); 4601 mark_object (&ptr->name);
4603 mark_object (&ptr->icon_name); 4602 mark_object (&ptr->icon_name);
4604 mark_object (&ptr->title); 4603 mark_object (&ptr->title);
4625 } 4624 }
4626 else if (GC_BOOL_VECTOR_P (obj)) 4625 else if (GC_BOOL_VECTOR_P (obj))
4627 { 4626 {
4628 register struct Lisp_Vector *ptr = XVECTOR (obj); 4627 register struct Lisp_Vector *ptr = XVECTOR (obj);
4629 4628
4630 if (ptr->size & ARRAY_MARK_FLAG) 4629 if (VECTOR_MARKED_P (ptr))
4631 break; /* Already marked */ 4630 break; /* Already marked */
4632 CHECK_LIVE (live_vector_p); 4631 CHECK_LIVE (live_vector_p);
4633 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ 4632 VECTOR_MARK (ptr); /* Else mark it */
4634 } 4633 }
4635 else if (GC_WINDOWP (obj)) 4634 else if (GC_WINDOWP (obj))
4636 { 4635 {
4637 register struct Lisp_Vector *ptr = XVECTOR (obj); 4636 register struct Lisp_Vector *ptr = XVECTOR (obj);
4638 struct window *w = XWINDOW (obj); 4637 struct window *w = XWINDOW (obj);
4639 register EMACS_INT size = ptr->size;
4640 register int i; 4638 register int i;
4641 4639
4642 /* Stop if already marked. */ 4640 /* Stop if already marked. */
4643 if (size & ARRAY_MARK_FLAG) 4641 if (VECTOR_MARKED_P (ptr))
4644 break; 4642 break;
4645 4643
4646 /* Mark it. */ 4644 /* Mark it. */
4647 CHECK_LIVE (live_vector_p); 4645 CHECK_LIVE (live_vector_p);
4648 ptr->size |= ARRAY_MARK_FLAG; 4646 VECTOR_MARK (ptr);
4649 4647
4650 /* There is no Lisp data above The member CURRENT_MATRIX in 4648 /* There is no Lisp data above The member CURRENT_MATRIX in
4651 struct WINDOW. Stop marking when that slot is reached. */ 4649 struct WINDOW. Stop marking when that slot is reached. */
4652 for (i = 0; 4650 for (i = 0;
4653 (char *) &ptr->contents[i] < (char *) &w->current_matrix; 4651 (char *) &ptr->contents[i] < (char *) &w->current_matrix;
4666 } 4664 }
4667 } 4665 }
4668 else if (GC_HASH_TABLE_P (obj)) 4666 else if (GC_HASH_TABLE_P (obj))
4669 { 4667 {
4670 struct Lisp_Hash_Table *h = XHASH_TABLE (obj); 4668 struct Lisp_Hash_Table *h = XHASH_TABLE (obj);
4671 EMACS_INT size = h->size;
4672 4669
4673 /* Stop if already marked. */ 4670 /* Stop if already marked. */
4674 if (size & ARRAY_MARK_FLAG) 4671 if (VECTOR_MARKED_P (h))
4675 break; 4672 break;
4676 4673
4677 /* Mark it. */ 4674 /* Mark it. */
4678 CHECK_LIVE (live_vector_p); 4675 CHECK_LIVE (live_vector_p);
4679 h->size |= ARRAY_MARK_FLAG; 4676 VECTOR_MARK (h);
4680 4677
4681 /* Mark contents. */ 4678 /* Mark contents. */
4682 /* Do not mark next_free or next_weak. 4679 /* Do not mark next_free or next_weak.
4683 Being in the next_weak chain 4680 Being in the next_weak chain
4684 should not keep the hash table alive. 4681 should not keep the hash table alive.
4696 /* If hash table is not weak, mark all keys and values. 4693 /* If hash table is not weak, mark all keys and values.
4697 For weak tables, mark only the vector. */ 4694 For weak tables, mark only the vector. */
4698 if (GC_NILP (h->weak)) 4695 if (GC_NILP (h->weak))
4699 mark_object (&h->key_and_value); 4696 mark_object (&h->key_and_value);
4700 else 4697 else
4701 XVECTOR (h->key_and_value)->size |= ARRAY_MARK_FLAG; 4698 VECTOR_MARK (XVECTOR (h->key_and_value));
4702
4703 } 4699 }
4704 else 4700 else
4705 { 4701 {
4706 register struct Lisp_Vector *ptr = XVECTOR (obj); 4702 register struct Lisp_Vector *ptr = XVECTOR (obj);
4707 register EMACS_INT size = ptr->size; 4703 register EMACS_INT size = ptr->size;
4708 register int i; 4704 register int i;
4709 4705
4710 if (size & ARRAY_MARK_FLAG) break; /* Already marked */ 4706 if (VECTOR_MARKED_P (ptr)) break; /* Already marked */
4711 CHECK_LIVE (live_vector_p); 4707 CHECK_LIVE (live_vector_p);
4712 ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ 4708 VECTOR_MARK (ptr); /* Else mark it */
4713 if (size & PSEUDOVECTOR_FLAG) 4709 if (size & PSEUDOVECTOR_FLAG)
4714 size &= PSEUDOVECTOR_SIZE_MASK; 4710 size &= PSEUDOVECTOR_SIZE_MASK;
4715 4711
4716 for (i = 0; i < size; i++) /* and then mark its elements */ 4712 for (i = 0; i < size; i++) /* and then mark its elements */
4717 mark_object (&ptr->contents[i]); 4713 mark_object (&ptr->contents[i]);
4852 { 4848 {
4853 register struct buffer *buffer = XBUFFER (buf); 4849 register struct buffer *buffer = XBUFFER (buf);
4854 register Lisp_Object *ptr; 4850 register Lisp_Object *ptr;
4855 Lisp_Object base_buffer; 4851 Lisp_Object base_buffer;
4856 4852
4857 /* This is the buffer's markbit */ 4853 VECTOR_MARK (buffer);
4858 mark_object (&buffer->name);
4859 XMARK (buffer->name);
4860 4854
4861 MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); 4855 MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
4862 4856
4863 if (CONSP (buffer->undo_list)) 4857 if (CONSP (buffer->undo_list))
4864 { 4858 {
4894 mark_object (&XCDR_AS_LVALUE (tail)); 4888 mark_object (&XCDR_AS_LVALUE (tail));
4895 } 4889 }
4896 else 4890 else
4897 mark_object (&buffer->undo_list); 4891 mark_object (&buffer->undo_list);
4898 4892
4899 for (ptr = &buffer->name + 1; 4893 for (ptr = &buffer->name;
4900 (char *)ptr < (char *)buffer + sizeof (struct buffer); 4894 (char *)ptr < (char *)buffer + sizeof (struct buffer);
4901 ptr++) 4895 ptr++)
4902 mark_object (ptr); 4896 mark_object (ptr);
4903 4897
4904 /* If this is an indirect buffer, mark its base buffer. */ 4898 /* If this is an indirect buffer, mark its base buffer. */
4940 } 4934 }
4941 break; 4935 break;
4942 4936
4943 case Lisp_Vectorlike: 4937 case Lisp_Vectorlike:
4944 if (GC_BUFFERP (obj)) 4938 if (GC_BUFFERP (obj))
4945 survives_p = XMARKBIT (XBUFFER (obj)->name); 4939 survives_p = VECTOR_MARKED_P (XBUFFER (obj));
4946 else if (GC_SUBRP (obj)) 4940 else if (GC_SUBRP (obj))
4947 survives_p = 1; 4941 survives_p = 1;
4948 else 4942 else
4949 survives_p = XVECTOR (obj)->size & ARRAY_MARK_FLAG; 4943 survives_p = VECTOR_MARKED_P (XVECTOR (obj));
4950 break; 4944 break;
4951 4945
4952 case Lisp_Cons: 4946 case Lisp_Cons:
4953 survives_p = XMARKBIT (XCAR (obj)); 4947 survives_p = XMARKBIT (XCAR (obj));
4954 break; 4948 break;
5210 5204
5211 for (i = 0; i < lim; i++) 5205 for (i = 0; i < lim; i++)
5212 { 5206 {
5213 if (!mblk->markers[i].u_marker.gcmarkbit) 5207 if (!mblk->markers[i].u_marker.gcmarkbit)
5214 { 5208 {
5215 Lisp_Object tem;
5216 if (mblk->markers[i].u_marker.type == Lisp_Misc_Marker) 5209 if (mblk->markers[i].u_marker.type == Lisp_Misc_Marker)
5217 unchain_marker (&mblk->markers[i].u_marker); 5210 unchain_marker (&mblk->markers[i].u_marker);
5218 /* Set the type of the freed object to Lisp_Misc_Free. 5211 /* Set the type of the freed object to Lisp_Misc_Free.
5219 We could leave the type alone, since nobody checks it, 5212 We could leave the type alone, since nobody checks it,
5220 but this might catch bugs faster. */ 5213 but this might catch bugs faster. */
5255 /* Free all unmarked buffers */ 5248 /* Free all unmarked buffers */
5256 { 5249 {
5257 register struct buffer *buffer = all_buffers, *prev = 0, *next; 5250 register struct buffer *buffer = all_buffers, *prev = 0, *next;
5258 5251
5259 while (buffer) 5252 while (buffer)
5260 if (!XMARKBIT (buffer->name)) 5253 if (!VECTOR_MARKED_P (buffer))
5261 { 5254 {
5262 if (prev) 5255 if (prev)
5263 prev->next = buffer->next; 5256 prev->next = buffer->next;
5264 else 5257 else
5265 all_buffers = buffer->next; 5258 all_buffers = buffer->next;
5267 lisp_free (buffer); 5260 lisp_free (buffer);
5268 buffer = next; 5261 buffer = next;
5269 } 5262 }
5270 else 5263 else
5271 { 5264 {
5272 XUNMARK (buffer->name); 5265 VECTOR_UNMARK (buffer);
5273 UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer)); 5266 UNMARK_BALANCE_INTERVALS (BUF_INTERVALS (buffer));
5274 prev = buffer, buffer = buffer->next; 5267 prev = buffer, buffer = buffer->next;
5275 } 5268 }
5276 } 5269 }
5277 5270
5279 { 5272 {
5280 register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next; 5273 register struct Lisp_Vector *vector = all_vectors, *prev = 0, *next;
5281 total_vector_size = 0; 5274 total_vector_size = 0;
5282 5275
5283 while (vector) 5276 while (vector)
5284 if (!(vector->size & ARRAY_MARK_FLAG)) 5277 if (!VECTOR_MARKED_P (vector))
5285 { 5278 {
5286 if (prev) 5279 if (prev)
5287 prev->next = vector->next; 5280 prev->next = vector->next;
5288 else 5281 else
5289 all_vectors = vector->next; 5282 all_vectors = vector->next;
5293 vector = next; 5286 vector = next;
5294 5287
5295 } 5288 }
5296 else 5289 else
5297 { 5290 {
5298 vector->size &= ~ARRAY_MARK_FLAG; 5291 VECTOR_UNMARK (vector);
5299 if (vector->size & PSEUDOVECTOR_FLAG) 5292 if (vector->size & PSEUDOVECTOR_FLAG)
5300 total_vector_size += (PSEUDOVECTOR_SIZE_MASK & vector->size); 5293 total_vector_size += (PSEUDOVECTOR_SIZE_MASK & vector->size);
5301 else 5294 else
5302 total_vector_size += vector->size; 5295 total_vector_size += vector->size;
5303 prev = vector, vector = vector->next; 5296 prev = vector, vector = vector->next;