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