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 |