diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 325 |
1 files changed, 193 insertions, 132 deletions
diff --git a/src/alloc.c b/src/alloc.c index 6e57b2024bc..300f5e420d3 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2961,25 +2961,23 @@ verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS)); | |||
| 2961 | 2961 | ||
| 2962 | /* Common shortcut to advance vector pointer over a block data. */ | 2962 | /* Common shortcut to advance vector pointer over a block data. */ |
| 2963 | 2963 | ||
| 2964 | #define ADVANCE(v, nbytes) ((struct Lisp_Vector *) ((char *) (v) + (nbytes))) | 2964 | static struct Lisp_Vector * |
| 2965 | ADVANCE (struct Lisp_Vector *v, ptrdiff_t nbytes) | ||
| 2966 | { | ||
| 2967 | void *vv = v; | ||
| 2968 | char *cv = vv; | ||
| 2969 | void *p = cv + nbytes; | ||
| 2970 | return p; | ||
| 2971 | } | ||
| 2965 | 2972 | ||
| 2966 | /* Common shortcut to calculate NBYTES-vector index in VECTOR_FREE_LISTS. */ | 2973 | /* Common shortcut to calculate NBYTES-vector index in VECTOR_FREE_LISTS. */ |
| 2967 | 2974 | ||
| 2968 | #define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size) | 2975 | static ptrdiff_t |
| 2969 | 2976 | VINDEX (ptrdiff_t nbytes) | |
| 2970 | /* Common shortcut to setup vector on a free list. */ | 2977 | { |
| 2971 | 2978 | eassume (VBLOCK_BYTES_MIN <= nbytes); | |
| 2972 | #define SETUP_ON_FREE_LIST(v, nbytes, tmp) \ | 2979 | return (nbytes - VBLOCK_BYTES_MIN) / roundup_size; |
| 2973 | do { \ | 2980 | } |
| 2974 | (tmp) = ((nbytes - header_size) / word_size); \ | ||
| 2975 | XSETPVECTYPESIZE (v, PVEC_FREE, 0, (tmp)); \ | ||
| 2976 | eassert ((nbytes) % roundup_size == 0); \ | ||
| 2977 | (tmp) = VINDEX (nbytes); \ | ||
| 2978 | eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \ | ||
| 2979 | set_next_vector (v, vector_free_lists[tmp]); \ | ||
| 2980 | vector_free_lists[tmp] = (v); \ | ||
| 2981 | total_free_vector_slots += (nbytes) / word_size; \ | ||
| 2982 | } while (0) | ||
| 2983 | 2981 | ||
| 2984 | /* This internal type is used to maintain the list of large vectors | 2982 | /* This internal type is used to maintain the list of large vectors |
| 2985 | which are allocated at their own, e.g. outside of vector blocks. | 2983 | which are allocated at their own, e.g. outside of vector blocks. |
| @@ -3041,6 +3039,22 @@ static EMACS_INT total_vectors; | |||
| 3041 | 3039 | ||
| 3042 | static EMACS_INT total_vector_slots, total_free_vector_slots; | 3040 | static EMACS_INT total_vector_slots, total_free_vector_slots; |
| 3043 | 3041 | ||
| 3042 | /* Common shortcut to setup vector on a free list. */ | ||
| 3043 | |||
| 3044 | static void | ||
| 3045 | setup_on_free_list (struct Lisp_Vector *v, ptrdiff_t nbytes) | ||
| 3046 | { | ||
| 3047 | eassume (header_size <= nbytes); | ||
| 3048 | ptrdiff_t nwords = (nbytes - header_size) / word_size; | ||
| 3049 | XSETPVECTYPESIZE (v, PVEC_FREE, 0, nwords); | ||
| 3050 | eassert (nbytes % roundup_size == 0); | ||
| 3051 | ptrdiff_t vindex = VINDEX (nbytes); | ||
| 3052 | eassert (vindex < VECTOR_MAX_FREE_LIST_INDEX); | ||
| 3053 | set_next_vector (v, vector_free_lists[vindex]); | ||
| 3054 | vector_free_lists[vindex] = v; | ||
| 3055 | total_free_vector_slots += nbytes / word_size; | ||
| 3056 | } | ||
| 3057 | |||
| 3044 | /* Get a new vector block. */ | 3058 | /* Get a new vector block. */ |
| 3045 | 3059 | ||
| 3046 | static struct vector_block * | 3060 | static struct vector_block * |
| @@ -3105,7 +3119,7 @@ allocate_vector_from_block (size_t nbytes) | |||
| 3105 | which should be set on an appropriate free list. */ | 3119 | which should be set on an appropriate free list. */ |
| 3106 | restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; | 3120 | restbytes = index * roundup_size + VBLOCK_BYTES_MIN - nbytes; |
| 3107 | eassert (restbytes % roundup_size == 0); | 3121 | eassert (restbytes % roundup_size == 0); |
| 3108 | SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index); | 3122 | setup_on_free_list (ADVANCE (vector, nbytes), restbytes); |
| 3109 | return vector; | 3123 | return vector; |
| 3110 | } | 3124 | } |
| 3111 | 3125 | ||
| @@ -3121,7 +3135,7 @@ allocate_vector_from_block (size_t nbytes) | |||
| 3121 | if (restbytes >= VBLOCK_BYTES_MIN) | 3135 | if (restbytes >= VBLOCK_BYTES_MIN) |
| 3122 | { | 3136 | { |
| 3123 | eassert (restbytes % roundup_size == 0); | 3137 | eassert (restbytes % roundup_size == 0); |
| 3124 | SETUP_ON_FREE_LIST (ADVANCE (vector, nbytes), restbytes, index); | 3138 | setup_on_free_list (ADVANCE (vector, nbytes), restbytes); |
| 3125 | } | 3139 | } |
| 3126 | return vector; | 3140 | return vector; |
| 3127 | } | 3141 | } |
| @@ -3253,10 +3267,7 @@ sweep_vectors (void) | |||
| 3253 | space was coalesced into the only free vector. */ | 3267 | space was coalesced into the only free vector. */ |
| 3254 | free_this_block = 1; | 3268 | free_this_block = 1; |
| 3255 | else | 3269 | else |
| 3256 | { | 3270 | setup_on_free_list (vector, total_bytes); |
| 3257 | size_t tmp; | ||
| 3258 | SETUP_ON_FREE_LIST (vector, total_bytes, tmp); | ||
| 3259 | } | ||
| 3260 | } | 3271 | } |
| 3261 | } | 3272 | } |
| 3262 | 3273 | ||
| @@ -4171,7 +4182,7 @@ refill_memory_reserve (void) | |||
| 4171 | block to the red-black tree with calls to mem_insert, and function | 4182 | block to the red-black tree with calls to mem_insert, and function |
| 4172 | lisp_free removes it with mem_delete. Functions live_string_p etc | 4183 | lisp_free removes it with mem_delete. Functions live_string_p etc |
| 4173 | call mem_find to lookup information about a given pointer in the | 4184 | call mem_find to lookup information about a given pointer in the |
| 4174 | tree, and use that to determine if the pointer points to a Lisp | 4185 | tree, and use that to determine if the pointer points into a Lisp |
| 4175 | object or not. */ | 4186 | object or not. */ |
| 4176 | 4187 | ||
| 4177 | /* Initialize this part of alloc.c. */ | 4188 | /* Initialize this part of alloc.c. */ |
| @@ -4549,82 +4560,113 @@ mem_delete_fixup (struct mem_node *x) | |||
| 4549 | } | 4560 | } |
| 4550 | 4561 | ||
| 4551 | 4562 | ||
| 4552 | /* Value is non-zero if P is a pointer to a live Lisp string on | 4563 | /* If P is a pointer into a live Lisp string object on the heap, |
| 4553 | the heap. M is a pointer to the mem_block for P. */ | 4564 | return the object. Otherwise, return nil. M is a pointer to the |
| 4565 | mem_block for P. | ||
| 4554 | 4566 | ||
| 4555 | static bool | 4567 | This and other *_holding functions look for a pointer anywhere into |
| 4556 | live_string_p (struct mem_node *m, void *p) | 4568 | the object, not merely for a pointer to the start of the object, |
| 4569 | because some compilers sometimes optimize away the latter. See | ||
| 4570 | Bug#28213. */ | ||
| 4571 | |||
| 4572 | static Lisp_Object | ||
| 4573 | live_string_holding (struct mem_node *m, void *p) | ||
| 4557 | { | 4574 | { |
| 4558 | if (m->type == MEM_TYPE_STRING) | 4575 | if (m->type == MEM_TYPE_STRING) |
| 4559 | { | 4576 | { |
| 4560 | struct string_block *b = m->start; | 4577 | struct string_block *b = m->start; |
| 4561 | ptrdiff_t offset = (char *) p - (char *) &b->strings[0]; | 4578 | char *cp = p; |
| 4579 | ptrdiff_t offset = cp - (char *) &b->strings[0]; | ||
| 4562 | 4580 | ||
| 4563 | /* P must point to the start of a Lisp_String structure, and it | 4581 | /* P must point into a Lisp_String structure, and it |
| 4564 | must not be on the free-list. */ | 4582 | must not be on the free-list. */ |
| 4565 | return (offset >= 0 | 4583 | if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0]) |
| 4566 | && offset % sizeof b->strings[0] == 0 | 4584 | { |
| 4567 | && offset < (STRING_BLOCK_SIZE * sizeof b->strings[0]) | 4585 | struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; |
| 4568 | && ((struct Lisp_String *) p)->data != NULL); | 4586 | if (s->data) |
| 4587 | return make_lisp_ptr (s, Lisp_String); | ||
| 4588 | } | ||
| 4569 | } | 4589 | } |
| 4570 | else | 4590 | return Qnil; |
| 4571 | return 0; | ||
| 4572 | } | 4591 | } |
| 4573 | 4592 | ||
| 4593 | static bool | ||
| 4594 | live_string_p (struct mem_node *m, void *p) | ||
| 4595 | { | ||
| 4596 | return !NILP (live_string_holding (m, p)); | ||
| 4597 | } | ||
| 4574 | 4598 | ||
| 4575 | /* Value is non-zero if P is a pointer to a live Lisp cons on | 4599 | /* If P is a pointer into a live Lisp cons object on the heap, return |
| 4576 | the heap. M is a pointer to the mem_block for P. */ | 4600 | the object. Otherwise, return nil. M is a pointer to the |
| 4601 | mem_block for P. */ | ||
| 4577 | 4602 | ||
| 4578 | static bool | 4603 | static Lisp_Object |
| 4579 | live_cons_p (struct mem_node *m, void *p) | 4604 | live_cons_holding (struct mem_node *m, void *p) |
| 4580 | { | 4605 | { |
| 4581 | if (m->type == MEM_TYPE_CONS) | 4606 | if (m->type == MEM_TYPE_CONS) |
| 4582 | { | 4607 | { |
| 4583 | struct cons_block *b = m->start; | 4608 | struct cons_block *b = m->start; |
| 4584 | ptrdiff_t offset = (char *) p - (char *) &b->conses[0]; | 4609 | char *cp = p; |
| 4610 | ptrdiff_t offset = cp - (char *) &b->conses[0]; | ||
| 4585 | 4611 | ||
| 4586 | /* P must point to the start of a Lisp_Cons, not be | 4612 | /* P must point into a Lisp_Cons, not be |
| 4587 | one of the unused cells in the current cons block, | 4613 | one of the unused cells in the current cons block, |
| 4588 | and not be on the free-list. */ | 4614 | and not be on the free-list. */ |
| 4589 | return (offset >= 0 | 4615 | if (0 <= offset && offset < CONS_BLOCK_SIZE * sizeof b->conses[0] |
| 4590 | && offset % sizeof b->conses[0] == 0 | 4616 | && (b != cons_block |
| 4591 | && offset < (CONS_BLOCK_SIZE * sizeof b->conses[0]) | 4617 | || offset / sizeof b->conses[0] < cons_block_index)) |
| 4592 | && (b != cons_block | 4618 | { |
| 4593 | || offset / sizeof b->conses[0] < cons_block_index) | 4619 | struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; |
| 4594 | && !EQ (((struct Lisp_Cons *) p)->car, Vdead)); | 4620 | if (!EQ (s->car, Vdead)) |
| 4621 | return make_lisp_ptr (s, Lisp_Cons); | ||
| 4622 | } | ||
| 4595 | } | 4623 | } |
| 4596 | else | 4624 | return Qnil; |
| 4597 | return 0; | ||
| 4598 | } | 4625 | } |
| 4599 | 4626 | ||
| 4627 | static bool | ||
| 4628 | live_cons_p (struct mem_node *m, void *p) | ||
| 4629 | { | ||
| 4630 | return !NILP (live_cons_holding (m, p)); | ||
| 4631 | } | ||
| 4600 | 4632 | ||
| 4601 | /* Value is non-zero if P is a pointer to a live Lisp symbol on | ||
| 4602 | the heap. M is a pointer to the mem_block for P. */ | ||
| 4603 | 4633 | ||
| 4604 | static bool | 4634 | /* If P is a pointer into a live Lisp symbol object on the heap, |
| 4605 | live_symbol_p (struct mem_node *m, void *p) | 4635 | return the object. Otherwise, return nil. M is a pointer to the |
| 4636 | mem_block for P. */ | ||
| 4637 | |||
| 4638 | static Lisp_Object | ||
| 4639 | live_symbol_holding (struct mem_node *m, void *p) | ||
| 4606 | { | 4640 | { |
| 4607 | if (m->type == MEM_TYPE_SYMBOL) | 4641 | if (m->type == MEM_TYPE_SYMBOL) |
| 4608 | { | 4642 | { |
| 4609 | struct symbol_block *b = m->start; | 4643 | struct symbol_block *b = m->start; |
| 4610 | ptrdiff_t offset = (char *) p - (char *) &b->symbols[0]; | 4644 | char *cp = p; |
| 4645 | ptrdiff_t offset = cp - (char *) &b->symbols[0]; | ||
| 4611 | 4646 | ||
| 4612 | /* P must point to the start of a Lisp_Symbol, not be | 4647 | /* P must point into the Lisp_Symbol, not be |
| 4613 | one of the unused cells in the current symbol block, | 4648 | one of the unused cells in the current symbol block, |
| 4614 | and not be on the free-list. */ | 4649 | and not be on the free-list. */ |
| 4615 | return (offset >= 0 | 4650 | if (0 <= offset && offset < SYMBOL_BLOCK_SIZE * sizeof b->symbols[0] |
| 4616 | && offset % sizeof b->symbols[0] == 0 | 4651 | && (b != symbol_block |
| 4617 | && offset < (SYMBOL_BLOCK_SIZE * sizeof b->symbols[0]) | 4652 | || offset / sizeof b->symbols[0] < symbol_block_index)) |
| 4618 | && (b != symbol_block | 4653 | { |
| 4619 | || offset / sizeof b->symbols[0] < symbol_block_index) | 4654 | struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; |
| 4620 | && !EQ (((struct Lisp_Symbol *)p)->function, Vdead)); | 4655 | if (!EQ (s->function, Vdead)) |
| 4656 | return make_lisp_symbol (s); | ||
| 4657 | } | ||
| 4621 | } | 4658 | } |
| 4622 | else | 4659 | return Qnil; |
| 4623 | return 0; | ||
| 4624 | } | 4660 | } |
| 4625 | 4661 | ||
| 4662 | static bool | ||
| 4663 | live_symbol_p (struct mem_node *m, void *p) | ||
| 4664 | { | ||
| 4665 | return !NILP (live_symbol_holding (m, p)); | ||
| 4666 | } | ||
| 4626 | 4667 | ||
| 4627 | /* Value is non-zero if P is a pointer to a live Lisp float on | 4668 | |
| 4669 | /* Return true if P is a pointer to a live Lisp float on | ||
| 4628 | the heap. M is a pointer to the mem_block for P. */ | 4670 | the heap. M is a pointer to the mem_block for P. */ |
| 4629 | 4671 | ||
| 4630 | static bool | 4672 | static bool |
| @@ -4633,7 +4675,8 @@ live_float_p (struct mem_node *m, void *p) | |||
| 4633 | if (m->type == MEM_TYPE_FLOAT) | 4675 | if (m->type == MEM_TYPE_FLOAT) |
| 4634 | { | 4676 | { |
| 4635 | struct float_block *b = m->start; | 4677 | struct float_block *b = m->start; |
| 4636 | ptrdiff_t offset = (char *) p - (char *) &b->floats[0]; | 4678 | char *cp = p; |
| 4679 | ptrdiff_t offset = cp - (char *) &b->floats[0]; | ||
| 4637 | 4680 | ||
| 4638 | /* P must point to the start of a Lisp_Float and not be | 4681 | /* P must point to the start of a Lisp_Float and not be |
| 4639 | one of the unused cells in the current float block. */ | 4682 | one of the unused cells in the current float block. */ |
| @@ -4648,38 +4691,48 @@ live_float_p (struct mem_node *m, void *p) | |||
| 4648 | } | 4691 | } |
| 4649 | 4692 | ||
| 4650 | 4693 | ||
| 4651 | /* Value is non-zero if P is a pointer to a live Lisp Misc on | 4694 | /* If P is a pointer to a live Lisp Misc on the heap, return the object. |
| 4652 | the heap. M is a pointer to the mem_block for P. */ | 4695 | Otherwise, return nil. M is a pointer to the mem_block for P. */ |
| 4653 | 4696 | ||
| 4654 | static bool | 4697 | static Lisp_Object |
| 4655 | live_misc_p (struct mem_node *m, void *p) | 4698 | live_misc_holding (struct mem_node *m, void *p) |
| 4656 | { | 4699 | { |
| 4657 | if (m->type == MEM_TYPE_MISC) | 4700 | if (m->type == MEM_TYPE_MISC) |
| 4658 | { | 4701 | { |
| 4659 | struct marker_block *b = m->start; | 4702 | struct marker_block *b = m->start; |
| 4660 | ptrdiff_t offset = (char *) p - (char *) &b->markers[0]; | 4703 | char *cp = p; |
| 4704 | ptrdiff_t offset = cp - (char *) &b->markers[0]; | ||
| 4661 | 4705 | ||
| 4662 | /* P must point to the start of a Lisp_Misc, not be | 4706 | /* P must point into a Lisp_Misc, not be |
| 4663 | one of the unused cells in the current misc block, | 4707 | one of the unused cells in the current misc block, |
| 4664 | and not be on the free-list. */ | 4708 | and not be on the free-list. */ |
| 4665 | return (offset >= 0 | 4709 | if (0 <= offset && offset < MARKER_BLOCK_SIZE * sizeof b->markers[0] |
| 4666 | && offset % sizeof b->markers[0] == 0 | 4710 | && (b != marker_block |
| 4667 | && offset < (MARKER_BLOCK_SIZE * sizeof b->markers[0]) | 4711 | || offset / sizeof b->markers[0] < marker_block_index)) |
| 4668 | && (b != marker_block | 4712 | { |
| 4669 | || offset / sizeof b->markers[0] < marker_block_index) | 4713 | union Lisp_Misc *s = p = cp -= offset % sizeof b->markers[0]; |
| 4670 | && ((union Lisp_Misc *) p)->u_any.type != Lisp_Misc_Free); | 4714 | if (s->u_any.type != Lisp_Misc_Free) |
| 4715 | return make_lisp_ptr (s, Lisp_Misc); | ||
| 4716 | } | ||
| 4671 | } | 4717 | } |
| 4672 | else | 4718 | return Qnil; |
| 4673 | return 0; | ||
| 4674 | } | 4719 | } |
| 4675 | 4720 | ||
| 4721 | static bool | ||
| 4722 | live_misc_p (struct mem_node *m, void *p) | ||
| 4723 | { | ||
| 4724 | return !NILP (live_misc_holding (m, p)); | ||
| 4725 | } | ||
| 4676 | 4726 | ||
| 4677 | /* Value is non-zero if P is a pointer to a live vector-like object. | 4727 | /* If P is a pointer to a live vector-like object, return the object. |
| 4728 | Otherwise, return nil. | ||
| 4678 | M is a pointer to the mem_block for P. */ | 4729 | M is a pointer to the mem_block for P. */ |
| 4679 | 4730 | ||
| 4680 | static bool | 4731 | static Lisp_Object |
| 4681 | live_vector_p (struct mem_node *m, void *p) | 4732 | live_vector_holding (struct mem_node *m, void *p) |
| 4682 | { | 4733 | { |
| 4734 | struct Lisp_Vector *vp = p; | ||
| 4735 | |||
| 4683 | if (m->type == MEM_TYPE_VECTOR_BLOCK) | 4736 | if (m->type == MEM_TYPE_VECTOR_BLOCK) |
| 4684 | { | 4737 | { |
| 4685 | /* This memory node corresponds to a vector block. */ | 4738 | /* This memory node corresponds to a vector block. */ |
| @@ -4691,33 +4744,59 @@ live_vector_p (struct mem_node *m, void *p) | |||
| 4691 | vector which is not on a free list. FIXME: check whether | 4744 | vector which is not on a free list. FIXME: check whether |
| 4692 | some allocation patterns (probably a lot of short vectors) | 4745 | some allocation patterns (probably a lot of short vectors) |
| 4693 | may cause a substantial overhead of this loop. */ | 4746 | may cause a substantial overhead of this loop. */ |
| 4694 | while (VECTOR_IN_BLOCK (vector, block) | 4747 | while (VECTOR_IN_BLOCK (vector, block) && vector <= vp) |
| 4695 | && vector <= (struct Lisp_Vector *) p) | ||
| 4696 | { | 4748 | { |
| 4697 | if (!PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) && vector == p) | 4749 | struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector)); |
| 4698 | return true; | 4750 | if (vp < next && !PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) |
| 4699 | else | 4751 | return make_lisp_ptr (vector, Lisp_Vectorlike); |
| 4700 | vector = ADVANCE (vector, vector_nbytes (vector)); | 4752 | vector = next; |
| 4701 | } | 4753 | } |
| 4702 | } | 4754 | } |
| 4703 | else if (m->type == MEM_TYPE_VECTORLIKE && p == large_vector_vec (m->start)) | 4755 | else if (m->type == MEM_TYPE_VECTORLIKE) |
| 4704 | /* This memory node corresponds to a large vector. */ | 4756 | { |
| 4705 | return 1; | 4757 | /* This memory node corresponds to a large vector. */ |
| 4706 | return 0; | 4758 | struct Lisp_Vector *vector = large_vector_vec (m->start); |
| 4759 | struct Lisp_Vector *next = ADVANCE (vector, vector_nbytes (vector)); | ||
| 4760 | if (vector <= vp && vp < next) | ||
| 4761 | return make_lisp_ptr (vector, Lisp_Vectorlike); | ||
| 4762 | } | ||
| 4763 | return Qnil; | ||
| 4707 | } | 4764 | } |
| 4708 | 4765 | ||
| 4766 | static bool | ||
| 4767 | live_vector_p (struct mem_node *m, void *p) | ||
| 4768 | { | ||
| 4769 | return !NILP (live_vector_holding (m, p)); | ||
| 4770 | } | ||
| 4709 | 4771 | ||
| 4710 | /* Value is non-zero if P is a pointer to a live buffer. M is a | 4772 | /* If P is a pointer into a live buffer, return the buffer. |
| 4711 | pointer to the mem_block for P. */ | 4773 | Otherwise, return nil. M is a pointer to the mem_block for P. */ |
| 4774 | |||
| 4775 | static Lisp_Object | ||
| 4776 | live_buffer_holding (struct mem_node *m, void *p) | ||
| 4777 | { | ||
| 4778 | /* P must point into the block, and the buffer | ||
| 4779 | must not have been killed. */ | ||
| 4780 | if (m->type == MEM_TYPE_BUFFER) | ||
| 4781 | { | ||
| 4782 | struct buffer *b = m->start; | ||
| 4783 | char *cb = m->start; | ||
| 4784 | char *cp = p; | ||
| 4785 | ptrdiff_t offset = cp - cb; | ||
| 4786 | if (0 <= offset && offset < sizeof *b && !NILP (b->name_)) | ||
| 4787 | { | ||
| 4788 | Lisp_Object obj; | ||
| 4789 | XSETBUFFER (obj, b); | ||
| 4790 | return obj; | ||
| 4791 | } | ||
| 4792 | } | ||
| 4793 | return Qnil; | ||
| 4794 | } | ||
| 4712 | 4795 | ||
| 4713 | static bool | 4796 | static bool |
| 4714 | live_buffer_p (struct mem_node *m, void *p) | 4797 | live_buffer_p (struct mem_node *m, void *p) |
| 4715 | { | 4798 | { |
| 4716 | /* P must point to the start of the block, and the buffer | 4799 | return !NILP (live_buffer_holding (m, p)); |
| 4717 | must not have been killed. */ | ||
| 4718 | return (m->type == MEM_TYPE_BUFFER | ||
| 4719 | && p == m->start | ||
| 4720 | && !NILP (((struct buffer *) p)->name_)); | ||
| 4721 | } | 4800 | } |
| 4722 | 4801 | ||
| 4723 | /* Mark OBJ if we can prove it's a Lisp_Object. */ | 4802 | /* Mark OBJ if we can prove it's a Lisp_Object. */ |
| @@ -4743,34 +4822,28 @@ mark_maybe_object (Lisp_Object obj) | |||
| 4743 | switch (XTYPE (obj)) | 4822 | switch (XTYPE (obj)) |
| 4744 | { | 4823 | { |
| 4745 | case Lisp_String: | 4824 | case Lisp_String: |
| 4746 | mark_p = (live_string_p (m, po) | 4825 | mark_p = EQ (obj, live_string_holding (m, po)); |
| 4747 | && !STRING_MARKED_P ((struct Lisp_String *) po)); | ||
| 4748 | break; | 4826 | break; |
| 4749 | 4827 | ||
| 4750 | case Lisp_Cons: | 4828 | case Lisp_Cons: |
| 4751 | mark_p = (live_cons_p (m, po) && !CONS_MARKED_P (XCONS (obj))); | 4829 | mark_p = EQ (obj, live_cons_holding (m, po)); |
| 4752 | break; | 4830 | break; |
| 4753 | 4831 | ||
| 4754 | case Lisp_Symbol: | 4832 | case Lisp_Symbol: |
| 4755 | mark_p = (live_symbol_p (m, po) && !XSYMBOL (obj)->gcmarkbit); | 4833 | mark_p = EQ (obj, live_symbol_holding (m, po)); |
| 4756 | break; | 4834 | break; |
| 4757 | 4835 | ||
| 4758 | case Lisp_Float: | 4836 | case Lisp_Float: |
| 4759 | mark_p = (live_float_p (m, po) && !FLOAT_MARKED_P (XFLOAT (obj))); | 4837 | mark_p = live_float_p (m, po); |
| 4760 | break; | 4838 | break; |
| 4761 | 4839 | ||
| 4762 | case Lisp_Vectorlike: | 4840 | case Lisp_Vectorlike: |
| 4763 | /* Note: can't check BUFFERP before we know it's a | 4841 | mark_p = (EQ (obj, live_vector_holding (m, po)) |
| 4764 | buffer because checking that dereferences the pointer | 4842 | || EQ (obj, live_buffer_holding (m, po))); |
| 4765 | PO which might point anywhere. */ | ||
| 4766 | if (live_vector_p (m, po)) | ||
| 4767 | mark_p = !SUBRP (obj) && !VECTOR_MARKED_P (XVECTOR (obj)); | ||
| 4768 | else if (live_buffer_p (m, po)) | ||
| 4769 | mark_p = BUFFERP (obj) && !VECTOR_MARKED_P (XBUFFER (obj)); | ||
| 4770 | break; | 4843 | break; |
| 4771 | 4844 | ||
| 4772 | case Lisp_Misc: | 4845 | case Lisp_Misc: |
| 4773 | mark_p = (live_misc_p (m, po) && !XMISCANY (obj)->gcmarkbit); | 4846 | mark_p = EQ (obj, live_misc_holding (m, po)); |
| 4774 | break; | 4847 | break; |
| 4775 | 4848 | ||
| 4776 | default: | 4849 | default: |
| @@ -4834,45 +4907,33 @@ mark_maybe_pointer (void *p) | |||
| 4834 | break; | 4907 | break; |
| 4835 | 4908 | ||
| 4836 | case MEM_TYPE_BUFFER: | 4909 | case MEM_TYPE_BUFFER: |
| 4837 | if (live_buffer_p (m, p) && !VECTOR_MARKED_P ((struct buffer *)p)) | 4910 | obj = live_buffer_holding (m, p); |
| 4838 | XSETVECTOR (obj, p); | ||
| 4839 | break; | 4911 | break; |
| 4840 | 4912 | ||
| 4841 | case MEM_TYPE_CONS: | 4913 | case MEM_TYPE_CONS: |
| 4842 | if (live_cons_p (m, p) && !CONS_MARKED_P ((struct Lisp_Cons *) p)) | 4914 | obj = live_cons_holding (m, p); |
| 4843 | XSETCONS (obj, p); | ||
| 4844 | break; | 4915 | break; |
| 4845 | 4916 | ||
| 4846 | case MEM_TYPE_STRING: | 4917 | case MEM_TYPE_STRING: |
| 4847 | if (live_string_p (m, p) | 4918 | obj = live_string_holding (m, p); |
| 4848 | && !STRING_MARKED_P ((struct Lisp_String *) p)) | ||
| 4849 | XSETSTRING (obj, p); | ||
| 4850 | break; | 4919 | break; |
| 4851 | 4920 | ||
| 4852 | case MEM_TYPE_MISC: | 4921 | case MEM_TYPE_MISC: |
| 4853 | if (live_misc_p (m, p) && !((struct Lisp_Free *) p)->gcmarkbit) | 4922 | obj = live_misc_holding (m, p); |
| 4854 | XSETMISC (obj, p); | ||
| 4855 | break; | 4923 | break; |
| 4856 | 4924 | ||
| 4857 | case MEM_TYPE_SYMBOL: | 4925 | case MEM_TYPE_SYMBOL: |
| 4858 | if (live_symbol_p (m, p) && !((struct Lisp_Symbol *) p)->gcmarkbit) | 4926 | obj = live_symbol_holding (m, p); |
| 4859 | XSETSYMBOL (obj, p); | ||
| 4860 | break; | 4927 | break; |
| 4861 | 4928 | ||
| 4862 | case MEM_TYPE_FLOAT: | 4929 | case MEM_TYPE_FLOAT: |
| 4863 | if (live_float_p (m, p) && !FLOAT_MARKED_P (p)) | 4930 | if (live_float_p (m, p)) |
| 4864 | XSETFLOAT (obj, p); | 4931 | obj = make_lisp_ptr (p, Lisp_Float); |
| 4865 | break; | 4932 | break; |
| 4866 | 4933 | ||
| 4867 | case MEM_TYPE_VECTORLIKE: | 4934 | case MEM_TYPE_VECTORLIKE: |
| 4868 | case MEM_TYPE_VECTOR_BLOCK: | 4935 | case MEM_TYPE_VECTOR_BLOCK: |
| 4869 | if (live_vector_p (m, p)) | 4936 | obj = live_vector_holding (m, p); |
| 4870 | { | ||
| 4871 | Lisp_Object tem; | ||
| 4872 | XSETVECTOR (tem, p); | ||
| 4873 | if (!SUBRP (tem) && !VECTOR_MARKED_P (XVECTOR (tem))) | ||
| 4874 | obj = tem; | ||
| 4875 | } | ||
| 4876 | break; | 4937 | break; |
| 4877 | 4938 | ||
| 4878 | default: | 4939 | default: |