Mercurial > emacs
comparison src/alloc.c @ 105986:850debe3a245
(mark_object): Don't reprocess marked strings.
Check vector's markbit earlier. Adjust calls to mark_vectorlike.
(mark_vectorlike, mark_char_table): Assume the object is unmarked.
| author | Stefan Monnier <monnier@iro.umontreal.ca> |
|---|---|
| date | Fri, 13 Nov 2009 15:26:28 +0000 |
| parents | 341a779db1d0 |
| children | 1d1d5d9bd884 |
comparison
equal
deleted
inserted
replaced
| 105985:10cb13aa45b6 | 105986:850debe3a245 |
|---|---|
| 5355 links of a list, in mark_object. In debugging, | 5355 links of a list, in mark_object. In debugging, |
| 5356 the call to abort will hit a breakpoint. | 5356 the call to abort will hit a breakpoint. |
| 5357 Normally this is zero and the check never goes off. */ | 5357 Normally this is zero and the check never goes off. */ |
| 5358 static int mark_object_loop_halt; | 5358 static int mark_object_loop_halt; |
| 5359 | 5359 |
| 5360 /* Return non-zero if the object was not yet marked. */ | 5360 static void |
| 5361 static int | |
| 5362 mark_vectorlike (ptr) | 5361 mark_vectorlike (ptr) |
| 5363 struct Lisp_Vector *ptr; | 5362 struct Lisp_Vector *ptr; |
| 5364 { | 5363 { |
| 5365 register EMACS_INT size = ptr->size; | 5364 register EMACS_INT size = ptr->size; |
| 5366 register int i; | 5365 register int i; |
| 5367 | 5366 |
| 5368 if (VECTOR_MARKED_P (ptr)) | 5367 eassert (!VECTOR_MARKED_P (ptr)); |
| 5369 return 0; /* Already marked */ | |
| 5370 VECTOR_MARK (ptr); /* Else mark it */ | 5368 VECTOR_MARK (ptr); /* Else mark it */ |
| 5371 if (size & PSEUDOVECTOR_FLAG) | 5369 if (size & PSEUDOVECTOR_FLAG) |
| 5372 size &= PSEUDOVECTOR_SIZE_MASK; | 5370 size &= PSEUDOVECTOR_SIZE_MASK; |
| 5373 | 5371 |
| 5374 /* Note that this size is not the memory-footprint size, but only | 5372 /* Note that this size is not the memory-footprint size, but only |
| 5375 the number of Lisp_Object fields that we should trace. | 5373 the number of Lisp_Object fields that we should trace. |
| 5376 The distinction is used e.g. by Lisp_Process which places extra | 5374 The distinction is used e.g. by Lisp_Process which places extra |
| 5377 non-Lisp_Object fields at the end of the structure. */ | 5375 non-Lisp_Object fields at the end of the structure. */ |
| 5378 for (i = 0; i < size; i++) /* and then mark its elements */ | 5376 for (i = 0; i < size; i++) /* and then mark its elements */ |
| 5379 mark_object (ptr->contents[i]); | 5377 mark_object (ptr->contents[i]); |
| 5380 return 1; | |
| 5381 } | 5378 } |
| 5382 | 5379 |
| 5383 /* Like mark_vectorlike but optimized for char-tables (and | 5380 /* Like mark_vectorlike but optimized for char-tables (and |
| 5384 sub-char-tables) assuming that the contents are mostly integers or | 5381 sub-char-tables) assuming that the contents are mostly integers or |
| 5385 symbols. */ | 5382 symbols. */ |
| 5389 struct Lisp_Vector *ptr; | 5386 struct Lisp_Vector *ptr; |
| 5390 { | 5387 { |
| 5391 register EMACS_INT size = ptr->size & PSEUDOVECTOR_SIZE_MASK; | 5388 register EMACS_INT size = ptr->size & PSEUDOVECTOR_SIZE_MASK; |
| 5392 register int i; | 5389 register int i; |
| 5393 | 5390 |
| 5391 eassert (!VECTOR_MARKED_P (ptr)); | |
| 5394 VECTOR_MARK (ptr); | 5392 VECTOR_MARK (ptr); |
| 5395 for (i = 0; i < size; i++) | 5393 for (i = 0; i < size; i++) |
| 5396 { | 5394 { |
| 5397 Lisp_Object val = ptr->contents[i]; | 5395 Lisp_Object val = ptr->contents[i]; |
| 5398 | 5396 |
| 5470 switch (SWITCH_ENUM_CAST (XTYPE (obj))) | 5468 switch (SWITCH_ENUM_CAST (XTYPE (obj))) |
| 5471 { | 5469 { |
| 5472 case Lisp_String: | 5470 case Lisp_String: |
| 5473 { | 5471 { |
| 5474 register struct Lisp_String *ptr = XSTRING (obj); | 5472 register struct Lisp_String *ptr = XSTRING (obj); |
| 5473 if (STRING_MARKED_P (ptr)) | |
| 5474 break; | |
| 5475 CHECK_ALLOCATED_AND_LIVE (live_string_p); | 5475 CHECK_ALLOCATED_AND_LIVE (live_string_p); |
| 5476 MARK_INTERVAL_TREE (ptr->intervals); | 5476 MARK_INTERVAL_TREE (ptr->intervals); |
| 5477 MARK_STRING (ptr); | 5477 MARK_STRING (ptr); |
| 5478 #ifdef GC_CHECK_STRING_BYTES | 5478 #ifdef GC_CHECK_STRING_BYTES |
| 5479 /* Check that the string size recorded in the string is the | 5479 /* Check that the string size recorded in the string is the |
| 5482 #endif /* GC_CHECK_STRING_BYTES */ | 5482 #endif /* GC_CHECK_STRING_BYTES */ |
| 5483 } | 5483 } |
| 5484 break; | 5484 break; |
| 5485 | 5485 |
| 5486 case Lisp_Vectorlike: | 5486 case Lisp_Vectorlike: |
| 5487 if (VECTOR_MARKED_P (XVECTOR (obj))) | |
| 5488 break; | |
| 5487 #ifdef GC_CHECK_MARKED_OBJECTS | 5489 #ifdef GC_CHECK_MARKED_OBJECTS |
| 5488 m = mem_find (po); | 5490 m = mem_find (po); |
| 5489 if (m == MEM_NIL && !SUBRP (obj) | 5491 if (m == MEM_NIL && !SUBRP (obj) |
| 5490 && po != &buffer_defaults | 5492 && po != &buffer_defaults |
| 5491 && po != &buffer_local_symbols) | 5493 && po != &buffer_local_symbols) |
| 5492 abort (); | 5494 abort (); |
| 5493 #endif /* GC_CHECK_MARKED_OBJECTS */ | 5495 #endif /* GC_CHECK_MARKED_OBJECTS */ |
| 5494 | 5496 |
| 5495 if (BUFFERP (obj)) | 5497 if (BUFFERP (obj)) |
| 5496 { | 5498 { |
| 5497 if (!VECTOR_MARKED_P (XBUFFER (obj))) | 5499 #ifdef GC_CHECK_MARKED_OBJECTS |
| 5500 if (po != &buffer_defaults && po != &buffer_local_symbols) | |
| 5498 { | 5501 { |
| 5499 #ifdef GC_CHECK_MARKED_OBJECTS | 5502 struct buffer *b; |
| 5500 if (po != &buffer_defaults && po != &buffer_local_symbols) | 5503 for (b = all_buffers; b && b != po; b = b->next) |
| 5501 { | 5504 ; |
| 5502 struct buffer *b; | 5505 if (b == NULL) |
| 5503 for (b = all_buffers; b && b != po; b = b->next) | 5506 abort (); |
| 5504 ; | 5507 } |
| 5505 if (b == NULL) | |
| 5506 abort (); | |
| 5507 } | |
| 5508 #endif /* GC_CHECK_MARKED_OBJECTS */ | 5508 #endif /* GC_CHECK_MARKED_OBJECTS */ |
| 5509 mark_buffer (obj); | 5509 mark_buffer (obj); |
| 5510 } | |
| 5511 } | 5510 } |
| 5512 else if (SUBRP (obj)) | 5511 else if (SUBRP (obj)) |
| 5513 break; | 5512 break; |
| 5514 else if (COMPILEDP (obj)) | 5513 else if (COMPILEDP (obj)) |
| 5515 /* We could treat this just like a vector, but it is better to | 5514 /* We could treat this just like a vector, but it is better to |
| 5517 recursion there. */ | 5516 recursion there. */ |
| 5518 { | 5517 { |
| 5519 register struct Lisp_Vector *ptr = XVECTOR (obj); | 5518 register struct Lisp_Vector *ptr = XVECTOR (obj); |
| 5520 register EMACS_INT size = ptr->size; | 5519 register EMACS_INT size = ptr->size; |
| 5521 register int i; | 5520 register int i; |
| 5522 | |
| 5523 if (VECTOR_MARKED_P (ptr)) | |
| 5524 break; /* Already marked */ | |
| 5525 | 5521 |
| 5526 CHECK_LIVE (live_vector_p); | 5522 CHECK_LIVE (live_vector_p); |
| 5527 VECTOR_MARK (ptr); /* Else mark it */ | 5523 VECTOR_MARK (ptr); /* Else mark it */ |
| 5528 size &= PSEUDOVECTOR_SIZE_MASK; | 5524 size &= PSEUDOVECTOR_SIZE_MASK; |
| 5529 for (i = 0; i < size; i++) /* and then mark its elements */ | 5525 for (i = 0; i < size; i++) /* and then mark its elements */ |
| 5535 goto loop; | 5531 goto loop; |
| 5536 } | 5532 } |
| 5537 else if (FRAMEP (obj)) | 5533 else if (FRAMEP (obj)) |
| 5538 { | 5534 { |
| 5539 register struct frame *ptr = XFRAME (obj); | 5535 register struct frame *ptr = XFRAME (obj); |
| 5540 if (mark_vectorlike (XVECTOR (obj))) | 5536 mark_vectorlike (XVECTOR (obj)); |
| 5541 mark_face_cache (ptr->face_cache); | 5537 mark_face_cache (ptr->face_cache); |
| 5542 } | 5538 } |
| 5543 else if (WINDOWP (obj)) | 5539 else if (WINDOWP (obj)) |
| 5544 { | 5540 { |
| 5545 register struct Lisp_Vector *ptr = XVECTOR (obj); | 5541 register struct Lisp_Vector *ptr = XVECTOR (obj); |
| 5546 struct window *w = XWINDOW (obj); | 5542 struct window *w = XWINDOW (obj); |
| 5547 if (mark_vectorlike (ptr)) | 5543 mark_vectorlike (ptr); |
| 5544 /* Mark glyphs for leaf windows. Marking window matrices is | |
| 5545 sufficient because frame matrices use the same glyph | |
| 5546 memory. */ | |
| 5547 if (NILP (w->hchild) | |
| 5548 && NILP (w->vchild) | |
| 5549 && w->current_matrix) | |
| 5548 { | 5550 { |
| 5549 /* Mark glyphs for leaf windows. Marking window matrices is | 5551 mark_glyph_matrix (w->current_matrix); |
| 5550 sufficient because frame matrices use the same glyph | 5552 mark_glyph_matrix (w->desired_matrix); |
| 5551 memory. */ | |
| 5552 if (NILP (w->hchild) | |
| 5553 && NILP (w->vchild) | |
| 5554 && w->current_matrix) | |
| 5555 { | |
| 5556 mark_glyph_matrix (w->current_matrix); | |
| 5557 mark_glyph_matrix (w->desired_matrix); | |
| 5558 } | |
| 5559 } | 5553 } |
| 5560 } | 5554 } |
| 5561 else if (HASH_TABLE_P (obj)) | 5555 else if (HASH_TABLE_P (obj)) |
| 5562 { | 5556 { |
| 5563 struct Lisp_Hash_Table *h = XHASH_TABLE (obj); | 5557 struct Lisp_Hash_Table *h = XHASH_TABLE (obj); |
| 5564 if (mark_vectorlike ((struct Lisp_Vector *)h)) | 5558 mark_vectorlike ((struct Lisp_Vector *)h); |
| 5565 { /* If hash table is not weak, mark all keys and values. | 5559 /* If hash table is not weak, mark all keys and values. |
| 5566 For weak tables, mark only the vector. */ | 5560 For weak tables, mark only the vector. */ |
| 5567 if (NILP (h->weak)) | 5561 if (NILP (h->weak)) |
| 5568 mark_object (h->key_and_value); | 5562 mark_object (h->key_and_value); |
| 5569 else | 5563 else |
| 5570 VECTOR_MARK (XVECTOR (h->key_and_value)); | 5564 VECTOR_MARK (XVECTOR (h->key_and_value)); |
| 5571 } | |
| 5572 } | 5565 } |
| 5573 else if (CHAR_TABLE_P (obj)) | 5566 else if (CHAR_TABLE_P (obj)) |
| 5574 { | 5567 mark_char_table (XVECTOR (obj)); |
| 5575 if (! VECTOR_MARKED_P (XVECTOR (obj))) | |
| 5576 mark_char_table (XVECTOR (obj)); | |
| 5577 } | |
| 5578 else | 5568 else |
| 5579 mark_vectorlike (XVECTOR (obj)); | 5569 mark_vectorlike (XVECTOR (obj)); |
| 5580 break; | 5570 break; |
| 5581 | 5571 |
| 5582 case Lisp_Symbol: | 5572 case Lisp_Symbol: |
| 5583 { | 5573 { |
| 5584 register struct Lisp_Symbol *ptr = XSYMBOL (obj); | 5574 register struct Lisp_Symbol *ptr = XSYMBOL (obj); |
| 5585 struct Lisp_Symbol *ptrx; | 5575 struct Lisp_Symbol *ptrx; |
| 5586 | 5576 |
| 5587 if (ptr->gcmarkbit) break; | 5577 if (ptr->gcmarkbit) |
| 5578 break; | |
| 5588 CHECK_ALLOCATED_AND_LIVE (live_symbol_p); | 5579 CHECK_ALLOCATED_AND_LIVE (live_symbol_p); |
| 5589 ptr->gcmarkbit = 1; | 5580 ptr->gcmarkbit = 1; |
| 5590 mark_object (ptr->value); | 5581 mark_object (ptr->value); |
| 5591 mark_object (ptr->function); | 5582 mark_object (ptr->function); |
| 5592 mark_object (ptr->plist); | 5583 mark_object (ptr->plist); |
| 5687 break; | 5678 break; |
| 5688 | 5679 |
| 5689 case Lisp_Cons: | 5680 case Lisp_Cons: |
| 5690 { | 5681 { |
| 5691 register struct Lisp_Cons *ptr = XCONS (obj); | 5682 register struct Lisp_Cons *ptr = XCONS (obj); |
| 5692 if (CONS_MARKED_P (ptr)) break; | 5683 if (CONS_MARKED_P (ptr)) |
| 5684 break; | |
| 5693 CHECK_ALLOCATED_AND_LIVE (live_cons_p); | 5685 CHECK_ALLOCATED_AND_LIVE (live_cons_p); |
| 5694 CONS_MARK (ptr); | 5686 CONS_MARK (ptr); |
| 5695 /* If the cdr is nil, avoid recursion for the car. */ | 5687 /* If the cdr is nil, avoid recursion for the car. */ |
| 5696 if (EQ (ptr->u.cdr, Qnil)) | 5688 if (EQ (ptr->u.cdr, Qnil)) |
| 5697 { | 5689 { |
| 5732 { | 5724 { |
| 5733 register struct buffer *buffer = XBUFFER (buf); | 5725 register struct buffer *buffer = XBUFFER (buf); |
| 5734 register Lisp_Object *ptr, tmp; | 5726 register Lisp_Object *ptr, tmp; |
| 5735 Lisp_Object base_buffer; | 5727 Lisp_Object base_buffer; |
| 5736 | 5728 |
| 5729 eassert (!VECTOR_MARKED_P (buffer)); | |
| 5737 VECTOR_MARK (buffer); | 5730 VECTOR_MARK (buffer); |
| 5738 | 5731 |
| 5739 MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); | 5732 MARK_INTERVAL_TREE (BUF_INTERVALS (buffer)); |
| 5740 | 5733 |
| 5741 /* For now, we just don't mark the undo_list. It's done later in | 5734 /* For now, we just don't mark the undo_list. It's done later in |
| 5776 { | 5769 { |
| 5777 struct terminal *t; | 5770 struct terminal *t; |
| 5778 for (t = terminal_list; t; t = t->next_terminal) | 5771 for (t = terminal_list; t; t = t->next_terminal) |
| 5779 { | 5772 { |
| 5780 eassert (t->name != NULL); | 5773 eassert (t->name != NULL); |
| 5774 if (!VECTOR_MARKED_P (t)) | |
| 5775 { | |
| 5781 #ifdef HAVE_WINDOW_SYSTEM | 5776 #ifdef HAVE_WINDOW_SYSTEM |
| 5782 mark_image_cache (t->image_cache); | 5777 mark_image_cache (t->image_cache); |
| 5783 #endif /* HAVE_WINDOW_SYSTEM */ | 5778 #endif /* HAVE_WINDOW_SYSTEM */ |
| 5784 mark_vectorlike ((struct Lisp_Vector *)t); | 5779 mark_vectorlike ((struct Lisp_Vector *)t); |
| 5780 } | |
| 5785 } | 5781 } |
| 5786 } | 5782 } |
| 5787 | 5783 |
| 5788 | 5784 |
| 5789 | 5785 |
