diff options
| author | Andrea Corallo | 2020-06-06 21:52:00 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-06-06 21:52:00 +0200 |
| commit | ee3df1483a9e733c27629da7bcf515789df52ef8 (patch) | |
| tree | 4af53af97a5a15687c0e9707b74a3f806bbbe5fd /src/alloc.c | |
| parent | 385d9e69740e4f6293fe4c7b4206e3a4aca6ca21 (diff) | |
| parent | 7ac79872aed63110c0d26c1e62e1838d6101c9bd (diff) | |
| download | emacs-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.c | 350 |
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 | ||
| 4456 | static Lisp_Object | 4456 | static struct Lisp_String * |
| 4457 | live_string_holding (struct mem_node *m, void *p) | 4457 | live_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 | ||
| 4478 | static bool | 4476 | static bool |
| 4479 | live_string_p (struct mem_node *m, void *p) | 4477 | live_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 | ||
| 4488 | static Lisp_Object | 4486 | static struct Lisp_Cons * |
| 4489 | live_cons_holding (struct mem_node *m, void *p) | 4487 | live_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 | ||
| 4513 | static bool | 4509 | static bool |
| 4514 | live_cons_p (struct mem_node *m, void *p) | 4510 | live_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 | ||
| 4524 | static Lisp_Object | 4520 | static struct Lisp_Symbol * |
| 4525 | live_symbol_holding (struct mem_node *m, void *p) | 4521 | live_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 | ||
| 4549 | static bool | 4543 | static bool |
| 4550 | live_symbol_p (struct mem_node *m, void *p) | 4544 | live_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) | |||
| 4559 | static bool | 4553 | static bool |
| 4560 | live_float_p (struct mem_node *m, void *p) | 4554 | live_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 | ||
| 4583 | static Lisp_Object | 4573 | static struct Lisp_Vector * |
| 4584 | live_vector_holding (struct mem_node *m, void *p) | 4574 | live_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) | 4583 | static bool |
| 4589 | { | 4584 | live_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. */ | 4593 | static struct Lisp_Vector * |
| 4599 | while (VECTOR_IN_BLOCK (vector, block) && vector <= vp) | 4594 | live_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 | ||
| 4618 | static bool | 4616 | static bool |
| 4619 | live_vector_p (struct mem_node *m, void *p) | 4617 | live_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))) |