aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorAndrea Corallo2020-06-06 21:52:00 +0200
committerAndrea Corallo2020-06-06 21:52:00 +0200
commitee3df1483a9e733c27629da7bcf515789df52ef8 (patch)
tree4af53af97a5a15687c0e9707b74a3f806bbbe5fd /src/alloc.c
parent385d9e69740e4f6293fe4c7b4206e3a4aca6ca21 (diff)
parent7ac79872aed63110c0d26c1e62e1838d6101c9bd (diff)
downloademacs-ee3df1483a9e733c27629da7bcf515789df52ef8.tar.gz
emacs-ee3df1483a9e733c27629da7bcf515789df52ef8.zip
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c350
1 files changed, 197 insertions, 153 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 281525b20e5..9a9dbb52e7b 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4445,7 +4445,7 @@ mem_delete_fixup (struct mem_node *x)
4445 4445
4446 4446
4447/* If P is a pointer into a live Lisp string object on the heap, 4447/* If P is a pointer into a live Lisp string object on the heap,
4448 return the object. Otherwise, return nil. M is a pointer to the 4448 return the object's address. Otherwise, return NULL. M points to the
4449 mem_block for P. 4449 mem_block for P.
4450 4450
4451 This and other *_holding functions look for a pointer anywhere into 4451 This and other *_holding functions look for a pointer anywhere into
@@ -4453,103 +4453,97 @@ mem_delete_fixup (struct mem_node *x)
4453 because some compilers sometimes optimize away the latter. See 4453 because some compilers sometimes optimize away the latter. See
4454 Bug#28213. */ 4454 Bug#28213. */
4455 4455
4456static Lisp_Object 4456static struct Lisp_String *
4457live_string_holding (struct mem_node *m, void *p) 4457live_string_holding (struct mem_node *m, void *p)
4458{ 4458{
4459 if (m->type == MEM_TYPE_STRING) 4459 eassert (m->type == MEM_TYPE_STRING);
4460 { 4460 struct string_block *b = m->start;
4461 struct string_block *b = m->start; 4461 char *cp = p;
4462 char *cp = p; 4462 ptrdiff_t offset = cp - (char *) &b->strings[0];
4463 ptrdiff_t offset = cp - (char *) &b->strings[0];
4464 4463
4465 /* P must point into a Lisp_String structure, and it 4464 /* P must point into a Lisp_String structure, and it
4466 must not be on the free-list. */ 4465 must not be on the free-list. */
4467 if (0 <= offset && offset < sizeof b->strings) 4466 if (0 <= offset && offset < sizeof b->strings)
4468 { 4467 {
4469 cp = ptr_bounds_copy (cp, b); 4468 cp = ptr_bounds_copy (cp, b);
4470 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; 4469 struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0];
4471 if (s->u.s.data) 4470 if (s->u.s.data)
4472 return make_lisp_ptr (s, Lisp_String); 4471 return s;
4473 }
4474 } 4472 }
4475 return Qnil; 4473 return NULL;
4476} 4474}
4477 4475
4478static bool 4476static bool
4479live_string_p (struct mem_node *m, void *p) 4477live_string_p (struct mem_node *m, void *p)
4480{ 4478{
4481 return !NILP (live_string_holding (m, p)); 4479 return live_string_holding (m, p) == p;
4482} 4480}
4483 4481
4484/* If P is a pointer into a live Lisp cons object on the heap, return 4482/* If P is a pointer into a live Lisp cons object on the heap, return
4485 the object. Otherwise, return nil. M is a pointer to the 4483 the object's address. Otherwise, return NULL. M points to the
4486 mem_block for P. */ 4484 mem_block for P. */
4487 4485
4488static Lisp_Object 4486static struct Lisp_Cons *
4489live_cons_holding (struct mem_node *m, void *p) 4487live_cons_holding (struct mem_node *m, void *p)
4490{ 4488{
4491 if (m->type == MEM_TYPE_CONS) 4489 eassert (m->type == MEM_TYPE_CONS);
4490 struct cons_block *b = m->start;
4491 char *cp = p;
4492 ptrdiff_t offset = cp - (char *) &b->conses[0];
4493
4494 /* P must point into a Lisp_Cons, not be
4495 one of the unused cells in the current cons block,
4496 and not be on the free-list. */
4497 if (0 <= offset && offset < sizeof b->conses
4498 && (b != cons_block
4499 || offset / sizeof b->conses[0] < cons_block_index))
4492 { 4500 {
4493 struct cons_block *b = m->start; 4501 cp = ptr_bounds_copy (cp, b);
4494 char *cp = p; 4502 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0];
4495 ptrdiff_t offset = cp - (char *) &b->conses[0]; 4503 if (!deadp (s->u.s.car))
4496 4504 return s;
4497 /* P must point into a Lisp_Cons, not be
4498 one of the unused cells in the current cons block,
4499 and not be on the free-list. */
4500 if (0 <= offset && offset < sizeof b->conses
4501 && (b != cons_block
4502 || offset / sizeof b->conses[0] < cons_block_index))
4503 {
4504 cp = ptr_bounds_copy (cp, b);
4505 struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0];
4506 if (!deadp (s->u.s.car))
4507 return make_lisp_ptr (s, Lisp_Cons);
4508 }
4509 } 4505 }
4510 return Qnil; 4506 return NULL;
4511} 4507}
4512 4508
4513static bool 4509static bool
4514live_cons_p (struct mem_node *m, void *p) 4510live_cons_p (struct mem_node *m, void *p)
4515{ 4511{
4516 return !NILP (live_cons_holding (m, p)); 4512 return live_cons_holding (m, p) == p;
4517} 4513}
4518 4514
4519 4515
4520/* If P is a pointer into a live Lisp symbol object on the heap, 4516/* If P is a pointer into a live Lisp symbol object on the heap,
4521 return the object. Otherwise, return nil. M is a pointer to the 4517 return the object's address. Otherwise, return NULL. M points to the
4522 mem_block for P. */ 4518 mem_block for P. */
4523 4519
4524static Lisp_Object 4520static struct Lisp_Symbol *
4525live_symbol_holding (struct mem_node *m, void *p) 4521live_symbol_holding (struct mem_node *m, void *p)
4526{ 4522{
4527 if (m->type == MEM_TYPE_SYMBOL) 4523 eassert (m->type == MEM_TYPE_SYMBOL);
4524 struct symbol_block *b = m->start;
4525 char *cp = p;
4526 ptrdiff_t offset = cp - (char *) &b->symbols[0];
4527
4528 /* P must point into the Lisp_Symbol, not be
4529 one of the unused cells in the current symbol block,
4530 and not be on the free-list. */
4531 if (0 <= offset && offset < sizeof b->symbols
4532 && (b != symbol_block
4533 || offset / sizeof b->symbols[0] < symbol_block_index))
4528 { 4534 {
4529 struct symbol_block *b = m->start; 4535 cp = ptr_bounds_copy (cp, b);
4530 char *cp = p; 4536 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0];
4531 ptrdiff_t offset = cp - (char *) &b->symbols[0]; 4537 if (!deadp (s->u.s.function))
4532 4538 return s;
4533 /* P must point into the Lisp_Symbol, not be
4534 one of the unused cells in the current symbol block,
4535 and not be on the free-list. */
4536 if (0 <= offset && offset < sizeof b->symbols
4537 && (b != symbol_block
4538 || offset / sizeof b->symbols[0] < symbol_block_index))
4539 {
4540 cp = ptr_bounds_copy (cp, b);
4541 struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0];
4542 if (!deadp (s->u.s.function))
4543 return make_lisp_symbol (s);
4544 }
4545 } 4539 }
4546 return Qnil; 4540 return NULL;
4547} 4541}
4548 4542
4549static bool 4543static bool
4550live_symbol_p (struct mem_node *m, void *p) 4544live_symbol_p (struct mem_node *m, void *p)
4551{ 4545{
4552 return !NILP (live_symbol_holding (m, p)); 4546 return live_symbol_holding (m, p) == p;
4553} 4547}
4554 4548
4555 4549
@@ -4559,66 +4553,70 @@ live_symbol_p (struct mem_node *m, void *p)
4559static bool 4553static bool
4560live_float_p (struct mem_node *m, void *p) 4554live_float_p (struct mem_node *m, void *p)
4561{ 4555{
4562 if (m->type == MEM_TYPE_FLOAT) 4556 eassert (m->type == MEM_TYPE_FLOAT);
4563 { 4557 struct float_block *b = m->start;
4564 struct float_block *b = m->start; 4558 char *cp = p;
4565 char *cp = p; 4559 ptrdiff_t offset = cp - (char *) &b->floats[0];
4566 ptrdiff_t offset = cp - (char *) &b->floats[0]; 4560
4567 4561 /* P must point to the start of a Lisp_Float and not be
4568 /* P must point to the start of a Lisp_Float and not be 4562 one of the unused cells in the current float block. */
4569 one of the unused cells in the current float block. */ 4563 return (0 <= offset && offset < sizeof b->floats
4570 return (0 <= offset && offset < sizeof b->floats 4564 && offset % sizeof b->floats[0] == 0
4571 && offset % sizeof b->floats[0] == 0 4565 && (b != float_block
4572 && (b != float_block 4566 || offset / sizeof b->floats[0] < float_block_index));
4573 || offset / sizeof b->floats[0] < float_block_index));
4574 }
4575 else
4576 return 0;
4577} 4567}
4578 4568
4579/* If P is a pointer to a live vector-like object, return the object. 4569/* If P is a pointer to a live, large vector-like object, return the object.
4580 Otherwise, return nil. 4570 Otherwise, return nil.
4581 M is a pointer to the mem_block for P. */ 4571 M is a pointer to the mem_block for P. */
4582 4572
4583static Lisp_Object 4573static struct Lisp_Vector *
4584live_vector_holding (struct mem_node *m, void *p) 4574live_large_vector_holding (struct mem_node *m, void *p)
4585{ 4575{
4576 eassert (m->type == MEM_TYPE_VECTORLIKE);
4586 struct Lisp_Vector *vp = p; 4577 struct Lisp_Vector *vp = p;
4578 struct Lisp_Vector *vector = large_vector_vec (m->start);
4579 struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector));
4580 return vector <= vp && vp < next ? vector : NULL;
4581}
4587 4582
4588 if (m->type == MEM_TYPE_VECTOR_BLOCK) 4583static bool
4589 { 4584live_large_vector_p (struct mem_node *m, void *p)
4590 /* This memory node corresponds to a vector block. */ 4585{
4591 struct vector_block *block = m->start; 4586 return live_large_vector_holding (m, p) == p;
4592 struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data; 4587}
4593 4588
4594 /* P is in the block's allocation range. Scan the block 4589/* If P is a pointer to a live, small vector-like object, return the object.
4595 up to P and see whether P points to the start of some 4590 Otherwise, return NULL.
4596 vector which is not on a free list. FIXME: check whether 4591 M is a pointer to the mem_block for P. */
4597 some allocation patterns (probably a lot of short vectors) 4592
4598 may cause a substantial overhead of this loop. */ 4593static struct Lisp_Vector *
4599 while (VECTOR_IN_BLOCK (vector, block) && vector <= vp) 4594live_small_vector_holding (struct mem_node *m, void *p)
4600 { 4595{
4601 struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector)); 4596 eassert (m->type == MEM_TYPE_VECTOR_BLOCK);
4602 if (vp < next && !PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) 4597 struct Lisp_Vector *vp = p;
4603 return make_lisp_ptr (vector, Lisp_Vectorlike); 4598 struct vector_block *block = m->start;
4604 vector = next; 4599 struct Lisp_Vector *vector = (struct Lisp_Vector *) block->data;
4605 } 4600
4606 } 4601 /* P is in the block's allocation range. Scan the block
4607 else if (m->type == MEM_TYPE_VECTORLIKE) 4602 up to P and see whether P points to the start of some
4603 vector which is not on a free list. FIXME: check whether
4604 some allocation patterns (probably a lot of short vectors)
4605 may cause a substantial overhead of this loop. */
4606 while (VECTOR_IN_BLOCK (vector, block) && vector <= vp)
4608 { 4607 {
4609 /* This memory node corresponds to a large vector. */
4610 struct Lisp_Vector *vector = large_vector_vec (m->start);
4611 struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector)); 4608 struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector));
4612 if (vector <= vp && vp < next) 4609 if (vp < next && !PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE))
4613 return make_lisp_ptr (vector, Lisp_Vectorlike); 4610 return vector;
4611 vector = next;
4614 } 4612 }
4615 return Qnil; 4613 return NULL;
4616} 4614}
4617 4615
4618static bool 4616static bool
4619live_vector_p (struct mem_node *m, void *p) 4617live_small_vector_p (struct mem_node *m, void *p)
4620{ 4618{
4621 return !NILP (live_vector_holding (m, p)); 4619 return live_small_vector_holding (m, p) == p;
4622} 4620}
4623 4621
4624/* Mark OBJ if we can prove it's a Lisp_Object. */ 4622/* Mark OBJ if we can prove it's a Lisp_Object. */
@@ -4630,10 +4628,24 @@ mark_maybe_object (Lisp_Object obj)
4630 VALGRIND_MAKE_MEM_DEFINED (&obj, sizeof (obj)); 4628 VALGRIND_MAKE_MEM_DEFINED (&obj, sizeof (obj));
4631#endif 4629#endif
4632 4630
4633 if (FIXNUMP (obj)) 4631 int type_tag = XTYPE (obj);
4634 return; 4632 intptr_t offset;
4633
4634 switch (type_tag)
4635 {
4636 case_Lisp_Int: case Lisp_Type_Unused0:
4637 return;
4638
4639 case Lisp_Symbol:
4640 offset = (intptr_t) lispsym;
4641 break;
4635 4642
4636 void *po = XPNTR (obj); 4643 default:
4644 offset = 0;
4645 break;
4646 }
4647
4648 void *po = (char *) XLP (obj) + (offset - LISP_WORD_TAG (type_tag));
4637 4649
4638 /* If the pointer is in the dump image and the dump has a record 4650 /* If the pointer is in the dump image and the dump has a record
4639 of the object starting at the place where the pointer points, we 4651 of the object starting at the place where the pointer points, we
@@ -4645,7 +4657,7 @@ mark_maybe_object (Lisp_Object obj)
4645 /* Don't use pdumper_object_p_precise here! It doesn't check the 4657 /* Don't use pdumper_object_p_precise here! It doesn't check the
4646 tag bits. OBJ here might be complete garbage, so we need to 4658 tag bits. OBJ here might be complete garbage, so we need to
4647 verify both the pointer and the tag. */ 4659 verify both the pointer and the tag. */
4648 if (XTYPE (obj) == pdumper_find_object_type (po)) 4660 if (pdumper_find_object_type (po) == type_tag)
4649 mark_object (obj); 4661 mark_object (obj);
4650 return; 4662 return;
4651 } 4663 }
@@ -4656,30 +4668,33 @@ mark_maybe_object (Lisp_Object obj)
4656 { 4668 {
4657 bool mark_p = false; 4669 bool mark_p = false;
4658 4670
4659 switch (XTYPE (obj)) 4671 switch (type_tag)
4660 { 4672 {
4661 case Lisp_String: 4673 case Lisp_String:
4662 mark_p = EQ (obj, live_string_holding (m, po)); 4674 mark_p = m->type == MEM_TYPE_STRING && live_string_p (m, po);
4663 break; 4675 break;
4664 4676
4665 case Lisp_Cons: 4677 case Lisp_Cons:
4666 mark_p = EQ (obj, live_cons_holding (m, po)); 4678 mark_p = m->type == MEM_TYPE_CONS && live_cons_p (m, po);
4667 break; 4679 break;
4668 4680
4669 case Lisp_Symbol: 4681 case Lisp_Symbol:
4670 mark_p = EQ (obj, live_symbol_holding (m, po)); 4682 mark_p = m->type == MEM_TYPE_SYMBOL && live_symbol_p (m, po);
4671 break; 4683 break;
4672 4684
4673 case Lisp_Float: 4685 case Lisp_Float:
4674 mark_p = live_float_p (m, po); 4686 mark_p = m->type == MEM_TYPE_FLOAT && live_float_p (m, po);
4675 break; 4687 break;
4676 4688
4677 case Lisp_Vectorlike: 4689 case Lisp_Vectorlike:
4678 mark_p = (EQ (obj, live_vector_holding (m, po))); 4690 mark_p = (m->type == MEM_TYPE_VECTOR_BLOCK
4691 ? live_small_vector_p (m, po)
4692 : (m->type == MEM_TYPE_VECTORLIKE
4693 && live_large_vector_p (m, po)));
4679 break; 4694 break;
4680 4695
4681 default: 4696 default:
4682 break; 4697 eassume (false);
4683 } 4698 }
4684 4699
4685 if (mark_p) 4700 if (mark_p)
@@ -4720,43 +4735,71 @@ mark_maybe_pointer (void *p)
4720 m = mem_find (p); 4735 m = mem_find (p);
4721 if (m != MEM_NIL) 4736 if (m != MEM_NIL)
4722 { 4737 {
4723 Lisp_Object obj = Qnil; 4738 Lisp_Object obj;
4724 4739
4725 switch (m->type) 4740 switch (m->type)
4726 { 4741 {
4727 case MEM_TYPE_NON_LISP: 4742 case MEM_TYPE_NON_LISP:
4728 case MEM_TYPE_SPARE: 4743 case MEM_TYPE_SPARE:
4729 /* Nothing to do; not a pointer to Lisp memory. */ 4744 /* Nothing to do; not a pointer to Lisp memory. */
4730 break; 4745 return;
4731 4746
4732 case MEM_TYPE_CONS: 4747 case MEM_TYPE_CONS:
4733 obj = live_cons_holding (m, p); 4748 {
4749 struct Lisp_Cons *h = live_cons_holding (m, p);
4750 if (!h)
4751 return;
4752 obj = make_lisp_ptr (h, Lisp_Cons);
4753 }
4734 break; 4754 break;
4735 4755
4736 case MEM_TYPE_STRING: 4756 case MEM_TYPE_STRING:
4737 obj = live_string_holding (m, p); 4757 {
4758 struct Lisp_String *h = live_string_holding (m, p);
4759 if (!h)
4760 return;
4761 obj = make_lisp_ptr (h, Lisp_String);
4762 }
4738 break; 4763 break;
4739 4764
4740 case MEM_TYPE_SYMBOL: 4765 case MEM_TYPE_SYMBOL:
4741 obj = live_symbol_holding (m, p); 4766 {
4767 struct Lisp_Symbol *h = live_symbol_holding (m, p);
4768 if (!h)
4769 return;
4770 obj = make_lisp_symbol (h);
4771 }
4742 break; 4772 break;
4743 4773
4744 case MEM_TYPE_FLOAT: 4774 case MEM_TYPE_FLOAT:
4745 if (live_float_p (m, p)) 4775 if (! live_float_p (m, p))
4746 obj = make_lisp_ptr (p, Lisp_Float); 4776 return;
4777 obj = make_lisp_ptr (p, Lisp_Float);
4747 break; 4778 break;
4748 4779
4749 case MEM_TYPE_VECTORLIKE: 4780 case MEM_TYPE_VECTORLIKE:
4781 {
4782 struct Lisp_Vector *h = live_large_vector_holding (m, p);
4783 if (!h)
4784 return;
4785 obj = make_lisp_ptr (h, Lisp_Vectorlike);
4786 }
4787 break;
4788
4750 case MEM_TYPE_VECTOR_BLOCK: 4789 case MEM_TYPE_VECTOR_BLOCK:
4751 obj = live_vector_holding (m, p); 4790 {
4791 struct Lisp_Vector *h = live_small_vector_holding (m, p);
4792 if (!h)
4793 return;
4794 obj = make_lisp_ptr (h, Lisp_Vectorlike);
4795 }
4752 break; 4796 break;
4753 4797
4754 default: 4798 default:
4755 emacs_abort (); 4799 emacs_abort ();
4756 } 4800 }
4757 4801
4758 if (!NILP (obj)) 4802 mark_object (obj);
4759 mark_object (obj);
4760 } 4803 }
4761} 4804}
4762 4805
@@ -5163,8 +5206,10 @@ valid_lisp_object_p (Lisp_Object obj)
5163 return live_float_p (m, p); 5206 return live_float_p (m, p);
5164 5207
5165 case MEM_TYPE_VECTORLIKE: 5208 case MEM_TYPE_VECTORLIKE:
5209 return live_large_vector_p (m, p);
5210
5166 case MEM_TYPE_VECTOR_BLOCK: 5211 case MEM_TYPE_VECTOR_BLOCK:
5167 return live_vector_p (m, p); 5212 return live_small_vector_p (m, p);
5168 5213
5169 default: 5214 default:
5170 break; 5215 break;
@@ -5686,7 +5731,7 @@ compact_font_cache_entry (Lisp_Object entry)
5686 struct font *font = GC_XFONT_OBJECT (val); 5731 struct font *font = GC_XFONT_OBJECT (val);
5687 5732
5688 if (!NILP (AREF (val, FONT_TYPE_INDEX)) 5733 if (!NILP (AREF (val, FONT_TYPE_INDEX))
5689 && vectorlike_marked_p(&font->header)) 5734 && vectorlike_marked_p (&font->header))
5690 break; 5735 break;
5691 } 5736 }
5692 if (CONSP (objlist)) 5737 if (CONSP (objlist))
@@ -6525,7 +6570,7 @@ mark_object (Lisp_Object arg)
6525 structure allocated from the heap. */ 6570 structure allocated from the heap. */
6526#define CHECK_ALLOCATED() \ 6571#define CHECK_ALLOCATED() \
6527 do { \ 6572 do { \
6528 if (pdumper_object_p(po)) \ 6573 if (pdumper_object_p (po)) \
6529 { \ 6574 { \
6530 if (!pdumper_object_p_precise (po)) \ 6575 if (!pdumper_object_p_precise (po)) \
6531 emacs_abort (); \ 6576 emacs_abort (); \
@@ -6538,19 +6583,19 @@ mark_object (Lisp_Object arg)
6538 6583
6539 /* Check that the object pointed to by PO is live, using predicate 6584 /* Check that the object pointed to by PO is live, using predicate
6540 function LIVEP. */ 6585 function LIVEP. */
6541#define CHECK_LIVE(LIVEP) \ 6586#define CHECK_LIVE(LIVEP, MEM_TYPE) \
6542 do { \ 6587 do { \
6543 if (pdumper_object_p(po)) \ 6588 if (pdumper_object_p (po)) \
6544 break; \ 6589 break; \
6545 if (!LIVEP (m, po)) \ 6590 if (! (m->type == MEM_TYPE && LIVEP (m, po))) \
6546 emacs_abort (); \ 6591 emacs_abort (); \
6547 } while (0) 6592 } while (0)
6548 6593
6549 /* Check both of the above conditions, for non-symbols. */ 6594 /* Check both of the above conditions, for non-symbols. */
6550#define CHECK_ALLOCATED_AND_LIVE(LIVEP) \ 6595#define CHECK_ALLOCATED_AND_LIVE(LIVEP, MEM_TYPE) \
6551 do { \ 6596 do { \
6552 CHECK_ALLOCATED (); \ 6597 CHECK_ALLOCATED (); \
6553 CHECK_LIVE (LIVEP); \ 6598 CHECK_LIVE (LIVEP, MEM_TYPE); \
6554 } while (false) 6599 } while (false)
6555 6600
6556 /* Check both of the above conditions, for symbols. */ 6601 /* Check both of the above conditions, for symbols. */
@@ -6559,15 +6604,14 @@ mark_object (Lisp_Object arg)
6559 if (!c_symbol_p (ptr)) \ 6604 if (!c_symbol_p (ptr)) \
6560 { \ 6605 { \
6561 CHECK_ALLOCATED (); \ 6606 CHECK_ALLOCATED (); \
6562 CHECK_LIVE (live_symbol_p); \ 6607 CHECK_LIVE (live_symbol_p, MEM_TYPE_SYMBOL); \
6563 } \ 6608 } \
6564 } while (false) 6609 } while (false)
6565 6610
6566#else /* not GC_CHECK_MARKED_OBJECTS */ 6611#else /* not GC_CHECK_MARKED_OBJECTS */
6567 6612
6568#define CHECK_LIVE(LIVEP) ((void) 0) 6613#define CHECK_ALLOCATED_AND_LIVE(LIVEP, MEM_TYPE) ((void) 0)
6569#define CHECK_ALLOCATED_AND_LIVE(LIVEP) ((void) 0) 6614#define CHECK_ALLOCATED_AND_LIVE_SYMBOL() ((void) 0)
6570#define CHECK_ALLOCATED_AND_LIVE_SYMBOL() ((void) 0)
6571 6615
6572#endif /* not GC_CHECK_MARKED_OBJECTS */ 6616#endif /* not GC_CHECK_MARKED_OBJECTS */
6573 6617
@@ -6578,7 +6622,7 @@ mark_object (Lisp_Object arg)
6578 register struct Lisp_String *ptr = XSTRING (obj); 6622 register struct Lisp_String *ptr = XSTRING (obj);
6579 if (string_marked_p (ptr)) 6623 if (string_marked_p (ptr))
6580 break; 6624 break;
6581 CHECK_ALLOCATED_AND_LIVE (live_string_p); 6625 CHECK_ALLOCATED_AND_LIVE (live_string_p, MEM_TYPE_STRING);
6582 set_string_marked (ptr); 6626 set_string_marked (ptr);
6583 mark_interval_tree (ptr->u.s.intervals); 6627 mark_interval_tree (ptr->u.s.intervals);
6584#ifdef GC_CHECK_STRING_BYTES 6628#ifdef GC_CHECK_STRING_BYTES
@@ -6596,21 +6640,21 @@ mark_object (Lisp_Object arg)
6596 if (vector_marked_p (ptr)) 6640 if (vector_marked_p (ptr))
6597 break; 6641 break;
6598 6642
6643 enum pvec_type pvectype
6644 = PSEUDOVECTOR_TYPE (ptr);
6645
6599#ifdef GC_CHECK_MARKED_OBJECTS 6646#ifdef GC_CHECK_MARKED_OBJECTS
6600 if (!pdumper_object_p(po)) 6647 if (!pdumper_object_p (po) && !SUBRP (obj) && !main_thread_p (po))
6601 { 6648 {
6602 m = mem_find (po); 6649 m = mem_find (po);
6603 if (m == MEM_NIL && !SUBRP (obj) && !main_thread_p (po)) 6650 if (m == MEM_NIL)
6604 emacs_abort (); 6651 emacs_abort ();
6652 if (m->type == MEM_TYPE_VECTORLIKE)
6653 CHECK_LIVE (live_large_vector_p, MEM_TYPE_VECTORLIKE);
6654 else
6655 CHECK_LIVE (live_small_vector_p, MEM_TYPE_VECTOR_BLOCK);
6605 } 6656 }
6606#endif /* GC_CHECK_MARKED_OBJECTS */ 6657#endif
6607
6608 enum pvec_type pvectype
6609 = PSEUDOVECTOR_TYPE (ptr);
6610
6611 if (pvectype != PVEC_SUBR &&
6612 !main_thread_p (po))
6613 CHECK_LIVE (live_vector_p);
6614 6658
6615 switch (pvectype) 6659 switch (pvectype)
6616 { 6660 {
@@ -6649,7 +6693,7 @@ mark_object (Lisp_Object arg)
6649 /* bool vectors in a dump are permanently "marked", since 6693 /* bool vectors in a dump are permanently "marked", since
6650 they're in the old section and don't have mark bits. 6694 they're in the old section and don't have mark bits.
6651 If we're looking at a dumped bool vector, we should 6695 If we're looking at a dumped bool vector, we should
6652 have aborted above when we called vector_marked_p(), so 6696 have aborted above when we called vector_marked_p, so
6653 we should never get here. */ 6697 we should never get here. */
6654 eassert (!pdumper_object_p (ptr)); 6698 eassert (!pdumper_object_p (ptr));
6655 set_vector_marked (ptr); 6699 set_vector_marked (ptr);
@@ -6687,7 +6731,7 @@ mark_object (Lisp_Object arg)
6687 if (symbol_marked_p (ptr)) 6731 if (symbol_marked_p (ptr))
6688 break; 6732 break;
6689 CHECK_ALLOCATED_AND_LIVE_SYMBOL (); 6733 CHECK_ALLOCATED_AND_LIVE_SYMBOL ();
6690 set_symbol_marked(ptr); 6734 set_symbol_marked (ptr);
6691 /* Attempt to catch bogus objects. */ 6735 /* Attempt to catch bogus objects. */
6692 eassert (valid_lisp_object_p (ptr->u.s.function)); 6736 eassert (valid_lisp_object_p (ptr->u.s.function));
6693 mark_object (ptr->u.s.function); 6737 mark_object (ptr->u.s.function);
@@ -6728,7 +6772,7 @@ mark_object (Lisp_Object arg)
6728 struct Lisp_Cons *ptr = XCONS (obj); 6772 struct Lisp_Cons *ptr = XCONS (obj);
6729 if (cons_marked_p (ptr)) 6773 if (cons_marked_p (ptr))
6730 break; 6774 break;
6731 CHECK_ALLOCATED_AND_LIVE (live_cons_p); 6775 CHECK_ALLOCATED_AND_LIVE (live_cons_p, MEM_TYPE_CONS);
6732 set_cons_marked (ptr); 6776 set_cons_marked (ptr);
6733 /* If the cdr is nil, avoid recursion for the car. */ 6777 /* If the cdr is nil, avoid recursion for the car. */
6734 if (NILP (ptr->u.s.u.cdr)) 6778 if (NILP (ptr->u.s.u.cdr))
@@ -6746,7 +6790,7 @@ mark_object (Lisp_Object arg)
6746 } 6790 }
6747 6791
6748 case Lisp_Float: 6792 case Lisp_Float:
6749 CHECK_ALLOCATED_AND_LIVE (live_float_p); 6793 CHECK_ALLOCATED_AND_LIVE (live_float_p, MEM_TYPE_FLOAT);
6750 /* Do not mark floats stored in a dump image: these floats are 6794 /* Do not mark floats stored in a dump image: these floats are
6751 "cold" and do not have mark bits. */ 6795 "cold" and do not have mark bits. */
6752 if (pdumper_object_p (XFLOAT (obj))) 6796 if (pdumper_object_p (XFLOAT (obj)))