aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c325
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))) 2964static struct Lisp_Vector *
2965ADVANCE (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) 2975static ptrdiff_t
2969 2976VINDEX (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
3042static EMACS_INT total_vector_slots, total_free_vector_slots; 3040static EMACS_INT total_vector_slots, total_free_vector_slots;
3043 3041
3042/* Common shortcut to setup vector on a free list. */
3043
3044static void
3045setup_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
3046static struct vector_block * 3060static 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
4555static bool 4567 This and other *_holding functions look for a pointer anywhere into
4556live_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
4572static Lisp_Object
4573live_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
4593static bool
4594live_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
4578static bool 4603static Lisp_Object
4579live_cons_p (struct mem_node *m, void *p) 4604live_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
4627static bool
4628live_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
4604static bool 4634/* If P is a pointer into a live Lisp symbol object on the heap,
4605live_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
4638static Lisp_Object
4639live_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
4662static bool
4663live_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
4630static bool 4672static 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
4654static bool 4697static Lisp_Object
4655live_misc_p (struct mem_node *m, void *p) 4698live_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
4721static bool
4722live_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
4680static bool 4731static Lisp_Object
4681live_vector_p (struct mem_node *m, void *p) 4732live_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
4766static bool
4767live_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
4775static Lisp_Object
4776live_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
4713static bool 4796static bool
4714live_buffer_p (struct mem_node *m, void *p) 4797live_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: