aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c393
1 files changed, 82 insertions, 311 deletions
diff --git a/src/alloc.c b/src/alloc.c
index c3e02c20f85..fea0cec383b 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -247,8 +247,8 @@ bool gc_in_progress;
247 247
248/* Number of live and free conses etc. */ 248/* Number of live and free conses etc. */
249 249
250static EMACS_INT total_conses, total_markers, total_symbols, total_buffers; 250static EMACS_INT total_conses, total_symbols, total_buffers;
251static EMACS_INT total_free_conses, total_free_markers, total_free_symbols; 251static EMACS_INT total_free_conses, total_free_symbols;
252static EMACS_INT total_free_floats, total_floats; 252static EMACS_INT total_free_floats, total_floats;
253 253
254/* Points to memory space allocated as "spare", to be freed if we run 254/* Points to memory space allocated as "spare", to be freed if we run
@@ -356,6 +356,7 @@ no_sanitize_memcpy (void *dest, void const *src, size_t size)
356 356
357#endif /* MAX_SAVE_STACK > 0 */ 357#endif /* MAX_SAVE_STACK > 0 */
358 358
359static void unchain_finalizer (struct Lisp_Finalizer *);
359static void mark_terminals (void); 360static void mark_terminals (void);
360static void gc_sweep (void); 361static void gc_sweep (void);
361static Lisp_Object make_pure_vector (ptrdiff_t); 362static Lisp_Object make_pure_vector (ptrdiff_t);
@@ -3197,7 +3198,12 @@ static void
3197cleanup_vector (struct Lisp_Vector *vector) 3198cleanup_vector (struct Lisp_Vector *vector)
3198{ 3199{
3199 detect_suspicious_free (vector); 3200 detect_suspicious_free (vector);
3200 if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT)) 3201
3202 if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BIGNUM))
3203 mpz_clear (PSEUDOVEC_STRUCT (vector, Lisp_Bignum)->value);
3204 else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FINALIZER))
3205 unchain_finalizer (PSEUDOVEC_STRUCT (vector, Lisp_Finalizer));
3206 else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT))
3201 { 3207 {
3202 if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX) 3208 if ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX)
3203 { 3209 {
@@ -3220,6 +3226,19 @@ cleanup_vector (struct Lisp_Vector *vector)
3220 finalize_one_mutex (PSEUDOVEC_STRUCT (vector, Lisp_Mutex)); 3226 finalize_one_mutex (PSEUDOVEC_STRUCT (vector, Lisp_Mutex));
3221 else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR)) 3227 else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_CONDVAR))
3222 finalize_one_condvar (PSEUDOVEC_STRUCT (vector, Lisp_CondVar)); 3228 finalize_one_condvar (PSEUDOVEC_STRUCT (vector, Lisp_CondVar));
3229 else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_MARKER))
3230 {
3231 /* sweep_buffer should already have unchained this from its buffer. */
3232 eassert (! PSEUDOVEC_STRUCT (vector, Lisp_Marker)->buffer);
3233 }
3234#ifdef HAVE_MODULES
3235 else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_USER_PTR))
3236 {
3237 struct Lisp_User_Ptr *uptr = PSEUDOVEC_STRUCT (vector, Lisp_User_Ptr);
3238 if (uptr->finalizer)
3239 uptr->finalizer (uptr->p);
3240 }
3241#endif
3223} 3242}
3224 3243
3225/* Reclaim space used by unmarked vectors. */ 3244/* Reclaim space used by unmarked vectors. */
@@ -3650,96 +3669,27 @@ Its value is void, and its function definition and property list are nil. */)
3650 3669
3651 3670
3652 3671
3653/***********************************************************************
3654 Marker (Misc) Allocation
3655 ***********************************************************************/
3656
3657/* Like union Lisp_Misc, but padded so that its size is a multiple of
3658 the required alignment. */
3659
3660union aligned_Lisp_Misc
3661{
3662 union Lisp_Misc m;
3663 unsigned char c[(sizeof (union Lisp_Misc) + LISP_ALIGNMENT - 1)
3664 & -LISP_ALIGNMENT];
3665};
3666
3667/* Allocation of markers and other objects that share that structure.
3668 Works like allocation of conses. */
3669
3670#define MARKER_BLOCK_SIZE \
3671 ((1020 - sizeof (struct marker_block *)) / sizeof (union aligned_Lisp_Misc))
3672
3673struct marker_block
3674{
3675 /* Place `markers' first, to preserve alignment. */
3676 union aligned_Lisp_Misc markers[MARKER_BLOCK_SIZE];
3677 struct marker_block *next;
3678};
3679
3680static struct marker_block *marker_block;
3681static int marker_block_index = MARKER_BLOCK_SIZE;
3682
3683static union Lisp_Misc *misc_free_list;
3684
3685/* Return a newly allocated Lisp_Misc object of specified TYPE. */
3686
3687static Lisp_Object
3688allocate_misc (enum Lisp_Misc_Type type)
3689{
3690 Lisp_Object val;
3691
3692 MALLOC_BLOCK_INPUT;
3693
3694 if (misc_free_list)
3695 {
3696 XSETMISC (val, misc_free_list);
3697 misc_free_list = misc_free_list->u_free.chain;
3698 }
3699 else
3700 {
3701 if (marker_block_index == MARKER_BLOCK_SIZE)
3702 {
3703 struct marker_block *new = lisp_malloc (sizeof *new, MEM_TYPE_MISC);
3704 new->next = marker_block;
3705 marker_block = new;
3706 marker_block_index = 0;
3707 total_free_markers += MARKER_BLOCK_SIZE;
3708 }
3709 XSETMISC (val, &marker_block->markers[marker_block_index].m);
3710 marker_block_index++;
3711 }
3712
3713 MALLOC_UNBLOCK_INPUT;
3714
3715 --total_free_markers;
3716 consing_since_gc += sizeof (union Lisp_Misc);
3717 misc_objects_consed++;
3718 XMISCANY (val)->type = type;
3719 XMISCANY (val)->gcmarkbit = 0;
3720 return val;
3721}
3722
3723Lisp_Object 3672Lisp_Object
3724make_misc_ptr (void *a) 3673make_misc_ptr (void *a)
3725{ 3674{
3726 Lisp_Object val = allocate_misc (Lisp_Misc_Ptr); 3675 struct Lisp_Misc_Ptr *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Misc_Ptr, pointer,
3727 XUNTAG (val, Lisp_Misc, struct Lisp_Misc_Ptr)->pointer = a; 3676 PVEC_MISC_PTR);
3728 return val; 3677 p->pointer = a;
3678 return make_lisp_ptr (p, Lisp_Vectorlike);
3729} 3679}
3730 3680
3731/* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ 3681/* Return a new overlay with specified START, END and PLIST. */
3732 3682
3733Lisp_Object 3683Lisp_Object
3734build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist) 3684build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist)
3735{ 3685{
3736 register Lisp_Object overlay; 3686 struct Lisp_Overlay *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Overlay, next,
3737 3687 PVEC_OVERLAY);
3738 overlay = allocate_misc (Lisp_Misc_Overlay); 3688 Lisp_Object overlay = make_lisp_ptr (p, Lisp_Vectorlike);
3739 OVERLAY_START (overlay) = start; 3689 OVERLAY_START (overlay) = start;
3740 OVERLAY_END (overlay) = end; 3690 OVERLAY_END (overlay) = end;
3741 set_overlay_plist (overlay, plist); 3691 set_overlay_plist (overlay, plist);
3742 XOVERLAY (overlay)->next = NULL; 3692 p->next = NULL;
3743 return overlay; 3693 return overlay;
3744} 3694}
3745 3695
@@ -3747,18 +3697,15 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
3747 doc: /* Return a newly allocated marker which does not point at any place. */) 3697 doc: /* Return a newly allocated marker which does not point at any place. */)
3748 (void) 3698 (void)
3749{ 3699{
3750 register Lisp_Object val; 3700 struct Lisp_Marker *p = ALLOCATE_PSEUDOVECTOR (struct Lisp_Marker, buffer,
3751 register struct Lisp_Marker *p; 3701 PVEC_MARKER);
3752
3753 val = allocate_misc (Lisp_Misc_Marker);
3754 p = XMARKER (val);
3755 p->buffer = 0; 3702 p->buffer = 0;
3756 p->bytepos = 0; 3703 p->bytepos = 0;
3757 p->charpos = 0; 3704 p->charpos = 0;
3758 p->next = NULL; 3705 p->next = NULL;
3759 p->insertion_type = 0; 3706 p->insertion_type = 0;
3760 p->need_adjustment = 0; 3707 p->need_adjustment = 0;
3761 return val; 3708 return make_lisp_ptr (p, Lisp_Vectorlike);
3762} 3709}
3763 3710
3764/* Return a newly allocated marker which points into BUF 3711/* Return a newly allocated marker which points into BUF
@@ -3767,17 +3714,14 @@ DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0,
3767Lisp_Object 3714Lisp_Object
3768build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) 3715build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos)
3769{ 3716{
3770 Lisp_Object obj;
3771 struct Lisp_Marker *m;
3772
3773 /* No dead buffers here. */ 3717 /* No dead buffers here. */
3774 eassert (BUFFER_LIVE_P (buf)); 3718 eassert (BUFFER_LIVE_P (buf));
3775 3719
3776 /* Every character is at least one byte. */ 3720 /* Every character is at least one byte. */
3777 eassert (charpos <= bytepos); 3721 eassert (charpos <= bytepos);
3778 3722
3779 obj = allocate_misc (Lisp_Misc_Marker); 3723 struct Lisp_Marker *m = ALLOCATE_PSEUDOVECTOR (struct Lisp_Marker, buffer,
3780 m = XMARKER (obj); 3724 PVEC_MARKER);
3781 m->buffer = buf; 3725 m->buffer = buf;
3782 m->charpos = charpos; 3726 m->charpos = charpos;
3783 m->bytepos = bytepos; 3727 m->bytepos = bytepos;
@@ -3785,7 +3729,7 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos)
3785 m->need_adjustment = 0; 3729 m->need_adjustment = 0;
3786 m->next = BUF_MARKERS (buf); 3730 m->next = BUF_MARKERS (buf);
3787 BUF_MARKERS (buf) = m; 3731 BUF_MARKERS (buf) = m;
3788 return obj; 3732 return make_lisp_ptr (m, Lisp_Vectorlike);
3789} 3733}
3790 3734
3791 3735
@@ -3793,16 +3737,12 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos)
3793Lisp_Object 3737Lisp_Object
3794make_bignum_str (const char *num, int base) 3738make_bignum_str (const char *num, int base)
3795{ 3739{
3796 Lisp_Object obj; 3740 struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value,
3797 struct Lisp_Bignum *b; 3741 PVEC_BIGNUM);
3798 int check;
3799
3800 obj = allocate_misc (Lisp_Misc_Bignum);
3801 b = XBIGNUM (obj);
3802 mpz_init (b->value); 3742 mpz_init (b->value);
3803 check = mpz_set_str (b->value, num, base); 3743 int check = mpz_set_str (b->value, num, base);
3804 eassert (check == 0); 3744 eassert (check == 0);
3805 return obj; 3745 return make_lisp_ptr (b, Lisp_Vectorlike);
3806} 3746}
3807 3747
3808/* Given an mpz_t, make a number. This may return a bignum or a 3748/* Given an mpz_t, make a number. This may return a bignum or a
@@ -3811,17 +3751,11 @@ make_bignum_str (const char *num, int base)
3811Lisp_Object 3751Lisp_Object
3812make_number (mpz_t value) 3752make_number (mpz_t value)
3813{ 3753{
3814 Lisp_Object obj;
3815 struct Lisp_Bignum *b;
3816
3817 if (mpz_fits_slong_p (value)) 3754 if (mpz_fits_slong_p (value))
3818 { 3755 {
3819 long l = mpz_get_si (value); 3756 long l = mpz_get_si (value);
3820 if (!FIXNUM_OVERFLOW_P (l)) 3757 if (!FIXNUM_OVERFLOW_P (l))
3821 { 3758 return make_fixnum (l);
3822 XSETINT (obj, l);
3823 return obj;
3824 }
3825 } 3759 }
3826 3760
3827 /* Check if fixnum can be larger than long. */ 3761 /* Check if fixnum can be larger than long. */
@@ -3845,20 +3779,17 @@ make_number (mpz_t value)
3845 v = -v; 3779 v = -v;
3846 3780
3847 if (!FIXNUM_OVERFLOW_P (v)) 3781 if (!FIXNUM_OVERFLOW_P (v))
3848 { 3782 return make_fixnum (v);
3849 XSETINT (obj, v);
3850 return obj;
3851 }
3852 } 3783 }
3853 } 3784 }
3854 3785
3855 obj = allocate_misc (Lisp_Misc_Bignum); 3786 struct Lisp_Bignum *b = ALLOCATE_PSEUDOVECTOR (struct Lisp_Bignum, value,
3856 b = XBIGNUM (obj); 3787 PVEC_BIGNUM);
3857 /* We could mpz_init + mpz_swap here, to avoid a copy, but the 3788 /* We could mpz_init + mpz_swap here, to avoid a copy, but the
3858 resulting API seemed possibly confusing. */ 3789 resulting API seemed possibly confusing. */
3859 mpz_init_set (b->value, value); 3790 mpz_init_set (b->value, value);
3860 3791
3861 return obj; 3792 return make_lisp_ptr (b, Lisp_Vectorlike);
3862} 3793}
3863 3794
3864void 3795void
@@ -3934,14 +3865,11 @@ make_event_array (ptrdiff_t nargs, Lisp_Object *args)
3934Lisp_Object 3865Lisp_Object
3935make_user_ptr (void (*finalizer) (void *), void *p) 3866make_user_ptr (void (*finalizer) (void *), void *p)
3936{ 3867{
3937 Lisp_Object obj; 3868 struct Lisp_User_Ptr *uptr = ALLOCATE_PSEUDOVECTOR (struct Lisp_User_Ptr,
3938 struct Lisp_User_Ptr *uptr; 3869 finalizer, PVEC_USER_PTR);
3939
3940 obj = allocate_misc (Lisp_Misc_User_Ptr);
3941 uptr = XUSER_PTR (obj);
3942 uptr->finalizer = finalizer; 3870 uptr->finalizer = finalizer;
3943 uptr->p = p; 3871 uptr->p = p;
3944 return obj; 3872 return make_lisp_ptr (uptr, Lisp_Vectorlike);
3945} 3873}
3946#endif 3874#endif
3947 3875
@@ -3984,7 +3912,7 @@ mark_finalizer_list (struct Lisp_Finalizer *head)
3984 finalizer != head; 3912 finalizer != head;
3985 finalizer = finalizer->next) 3913 finalizer = finalizer->next)
3986 { 3914 {
3987 finalizer->base.gcmarkbit = true; 3915 VECTOR_MARK (finalizer);
3988 mark_object (finalizer->function); 3916 mark_object (finalizer->function);
3989 } 3917 }
3990} 3918}
@@ -4001,7 +3929,7 @@ queue_doomed_finalizers (struct Lisp_Finalizer *dest,
4001 while (finalizer != src) 3929 while (finalizer != src)
4002 { 3930 {
4003 struct Lisp_Finalizer *next = finalizer->next; 3931 struct Lisp_Finalizer *next = finalizer->next;
4004 if (!finalizer->base.gcmarkbit && !NILP (finalizer->function)) 3932 if (!VECTOR_MARKED_P (finalizer) && !NILP (finalizer->function))
4005 { 3933 {
4006 unchain_finalizer (finalizer); 3934 unchain_finalizer (finalizer);
4007 finalizer_insert (dest, finalizer); 3935 finalizer_insert (dest, finalizer);
@@ -4037,7 +3965,6 @@ run_finalizers (struct Lisp_Finalizer *finalizers)
4037 while (finalizers->next != finalizers) 3965 while (finalizers->next != finalizers)
4038 { 3966 {
4039 finalizer = finalizers->next; 3967 finalizer = finalizers->next;
4040 eassert (finalizer->base.type == Lisp_Misc_Finalizer);
4041 unchain_finalizer (finalizer); 3968 unchain_finalizer (finalizer);
4042 function = finalizer->function; 3969 function = finalizer->function;
4043 if (!NILP (function)) 3970 if (!NILP (function))
@@ -4057,12 +3984,12 @@ count as reachable for the purpose of deciding whether to run
4057FUNCTION. FUNCTION will be run once per finalizer object. */) 3984FUNCTION. FUNCTION will be run once per finalizer object. */)
4058 (Lisp_Object function) 3985 (Lisp_Object function)
4059{ 3986{
4060 Lisp_Object val = allocate_misc (Lisp_Misc_Finalizer); 3987 struct Lisp_Finalizer *finalizer
4061 struct Lisp_Finalizer *finalizer = XFINALIZER (val); 3988 = ALLOCATE_PSEUDOVECTOR (struct Lisp_Finalizer, prev, PVEC_FINALIZER);
4062 finalizer->function = function; 3989 finalizer->function = function;
4063 finalizer->prev = finalizer->next = NULL; 3990 finalizer->prev = finalizer->next = NULL;
4064 finalizer_insert (&finalizers, finalizer); 3991 finalizer_insert (&finalizers, finalizer);
4065 return val; 3992 return make_lisp_ptr (finalizer, Lisp_Vectorlike);
4066} 3993}
4067 3994
4068 3995
@@ -4683,41 +4610,6 @@ live_float_p (struct mem_node *m, void *p)
4683 return 0; 4610 return 0;
4684} 4611}
4685 4612
4686
4687/* If P is a pointer to a live Lisp Misc on the heap, return the object.
4688 Otherwise, return nil. M is a pointer to the mem_block for P. */
4689
4690static Lisp_Object
4691live_misc_holding (struct mem_node *m, void *p)
4692{
4693 if (m->type == MEM_TYPE_MISC)
4694 {
4695 struct marker_block *b = m->start;
4696 char *cp = p;
4697 ptrdiff_t offset = cp - (char *) &b->markers[0];
4698
4699 /* P must point into a Lisp_Misc, not be
4700 one of the unused cells in the current misc block,
4701 and not be on the free-list. */
4702 if (0 <= offset && offset < MARKER_BLOCK_SIZE * sizeof b->markers[0]
4703 && (b != marker_block
4704 || offset / sizeof b->markers[0] < marker_block_index))
4705 {
4706 cp = ptr_bounds_copy (cp, b);
4707 union Lisp_Misc *s = p = cp -= offset % sizeof b->markers[0];
4708 if (s->u_any.type != Lisp_Misc_Free)
4709 return make_lisp_ptr (s, Lisp_Misc);
4710 }
4711 }
4712 return Qnil;
4713}
4714
4715static bool
4716live_misc_p (struct mem_node *m, void *p)
4717{
4718 return !NILP (live_misc_holding (m, p));
4719}
4720
4721/* If P is a pointer to a live vector-like object, return the object. 4613/* If P is a pointer to a live vector-like object, return the object.
4722 Otherwise, return nil. 4614 Otherwise, return nil.
4723 M is a pointer to the mem_block for P. */ 4615 M is a pointer to the mem_block for P. */
@@ -4836,10 +4728,6 @@ mark_maybe_object (Lisp_Object obj)
4836 || EQ (obj, live_buffer_holding (m, po))); 4728 || EQ (obj, live_buffer_holding (m, po)));
4837 break; 4729 break;
4838 4730
4839 case Lisp_Misc:
4840 mark_p = EQ (obj, live_misc_holding (m, po));
4841 break;
4842
4843 default: 4731 default:
4844 break; 4732 break;
4845 } 4733 }
@@ -4921,10 +4809,6 @@ mark_maybe_pointer (void *p)
4921 obj = live_string_holding (m, p); 4809 obj = live_string_holding (m, p);
4922 break; 4810 break;
4923 4811
4924 case MEM_TYPE_MISC:
4925 obj = live_misc_holding (m, p);
4926 break;
4927
4928 case MEM_TYPE_SYMBOL: 4812 case MEM_TYPE_SYMBOL:
4929 obj = live_symbol_holding (m, p); 4813 obj = live_symbol_holding (m, p);
4930 break; 4814 break;
@@ -5325,9 +5209,6 @@ valid_lisp_object_p (Lisp_Object obj)
5325 case MEM_TYPE_STRING: 5209 case MEM_TYPE_STRING:
5326 return live_string_p (m, p); 5210 return live_string_p (m, p);
5327 5211
5328 case MEM_TYPE_MISC:
5329 return live_misc_p (m, p);
5330
5331 case MEM_TYPE_SYMBOL: 5212 case MEM_TYPE_SYMBOL:
5332 return live_symbol_p (m, p); 5213 return live_symbol_p (m, p);
5333 5214
@@ -5550,14 +5431,13 @@ make_pure_float (double num)
5550static Lisp_Object 5431static Lisp_Object
5551make_pure_bignum (struct Lisp_Bignum *value) 5432make_pure_bignum (struct Lisp_Bignum *value)
5552{ 5433{
5553 Lisp_Object new;
5554 size_t i, nlimbs = mpz_size (value->value); 5434 size_t i, nlimbs = mpz_size (value->value);
5555 size_t nbytes = nlimbs * sizeof (mp_limb_t); 5435 size_t nbytes = nlimbs * sizeof (mp_limb_t);
5556 mp_limb_t *pure_limbs; 5436 mp_limb_t *pure_limbs;
5557 mp_size_t new_size; 5437 mp_size_t new_size;
5558 5438
5559 struct Lisp_Bignum *b = pure_alloc (sizeof (struct Lisp_Bignum), Lisp_Misc); 5439 struct Lisp_Bignum *b = pure_alloc (sizeof *b, Lisp_Vectorlike);
5560 b->type = Lisp_Misc_Bignum; 5440 XSETPVECTYPESIZE (b, PVEC_BIGNUM, 0, VECSIZE (struct Lisp_Bignum));
5561 5441
5562 pure_limbs = pure_alloc (nbytes, -1); 5442 pure_limbs = pure_alloc (nbytes, -1);
5563 for (i = 0; i < nlimbs; ++i) 5443 for (i = 0; i < nlimbs; ++i)
@@ -5569,8 +5449,7 @@ make_pure_bignum (struct Lisp_Bignum *value)
5569 5449
5570 mpz_roinit_n (b->value, pure_limbs, new_size); 5450 mpz_roinit_n (b->value, pure_limbs, new_size);
5571 5451
5572 XSETMISC (new, b); 5452 return make_lisp_ptr (b, Lisp_Vectorlike);
5573 return new;
5574} 5453}
5575 5454
5576/* Return a vector with room for LEN Lisp_Objects allocated from 5455/* Return a vector with room for LEN Lisp_Objects allocated from
@@ -5777,7 +5656,6 @@ total_bytes_of_live_objects (void)
5777 size_t tot = 0; 5656 size_t tot = 0;
5778 tot += total_conses * sizeof (struct Lisp_Cons); 5657 tot += total_conses * sizeof (struct Lisp_Cons);
5779 tot += total_symbols * sizeof (struct Lisp_Symbol); 5658 tot += total_symbols * sizeof (struct Lisp_Symbol);
5780 tot += total_markers * sizeof (union Lisp_Misc);
5781 tot += total_string_bytes; 5659 tot += total_string_bytes;
5782 tot += total_vector_slots * word_size; 5660 tot += total_vector_slots * word_size;
5783 tot += total_floats * sizeof (struct Lisp_Float); 5661 tot += total_floats * sizeof (struct Lisp_Float);
@@ -5898,7 +5776,7 @@ compact_undo_list (Lisp_Object list)
5898 { 5776 {
5899 if (CONSP (XCAR (tail)) 5777 if (CONSP (XCAR (tail))
5900 && MARKERP (XCAR (XCAR (tail))) 5778 && MARKERP (XCAR (XCAR (tail)))
5901 && !XMARKER (XCAR (XCAR (tail)))->gcmarkbit) 5779 && !VECTOR_MARKED_P (XMARKER (XCAR (XCAR (tail)))))
5902 *prev = XCDR (tail); 5780 *prev = XCDR (tail);
5903 else 5781 else
5904 prev = xcdr_addr (tail); 5782 prev = xcdr_addr (tail);
@@ -6125,9 +6003,6 @@ garbage_collect_1 (void *end)
6125 list4 (Qsymbols, make_fixnum (sizeof (struct Lisp_Symbol)), 6003 list4 (Qsymbols, make_fixnum (sizeof (struct Lisp_Symbol)),
6126 bounded_number (total_symbols), 6004 bounded_number (total_symbols),
6127 bounded_number (total_free_symbols)), 6005 bounded_number (total_free_symbols)),
6128 list4 (Qmiscs, make_fixnum (sizeof (union Lisp_Misc)),
6129 bounded_number (total_markers),
6130 bounded_number (total_free_markers)),
6131 list4 (Qstrings, make_fixnum (sizeof (struct Lisp_String)), 6006 list4 (Qstrings, make_fixnum (sizeof (struct Lisp_String)),
6132 bounded_number (total_strings), 6007 bounded_number (total_strings),
6133 bounded_number (total_free_strings)), 6008 bounded_number (total_free_strings)),
@@ -6314,12 +6189,12 @@ mark_compiled (struct Lisp_Vector *ptr)
6314static void 6189static void
6315mark_overlay (struct Lisp_Overlay *ptr) 6190mark_overlay (struct Lisp_Overlay *ptr)
6316{ 6191{
6317 for (; ptr && !ptr->gcmarkbit; ptr = ptr->next) 6192 for (; ptr && !VECTOR_MARKED_P (ptr); ptr = ptr->next)
6318 { 6193 {
6319 ptr->gcmarkbit = 1; 6194 VECTOR_MARK (ptr);
6320 /* These two are always markers and can be marked fast. */ 6195 /* These two are always markers and can be marked fast. */
6321 XMARKER (ptr->start)->gcmarkbit = 1; 6196 VECTOR_MARK (XMARKER (ptr->start));
6322 XMARKER (ptr->end)->gcmarkbit = 1; 6197 VECTOR_MARK (XMARKER (ptr->end));
6323 mark_object (ptr->plist); 6198 mark_object (ptr->plist);
6324 } 6199 }
6325} 6200}
@@ -6620,9 +6495,26 @@ mark_object (Lisp_Object arg)
6620 mark_char_table (ptr, (enum pvec_type) pvectype); 6495 mark_char_table (ptr, (enum pvec_type) pvectype);
6621 break; 6496 break;
6622 6497
6498 case PVEC_MARKER:
6499 /* DO NOT mark thru the marker's chain.
6500 The buffer's markers chain does not preserve markers from gc;
6501 instead, markers are removed from the chain when freed by gc. */
6623 case PVEC_BOOL_VECTOR: 6502 case PVEC_BOOL_VECTOR:
6624 /* No Lisp_Objects to mark in a bool vector. */ 6503 case PVEC_MISC_PTR:
6504#ifdef HAVE_MODULES
6505 case PVEC_USER_PTR:
6506#endif
6507 /* No Lisp_Objects to mark in these. */
6508 VECTOR_MARK (ptr);
6509 break;
6510
6511 case PVEC_OVERLAY:
6512 mark_overlay (XOVERLAY (obj));
6513 break;
6514
6515 case PVEC_FINALIZER:
6625 VECTOR_MARK (ptr); 6516 VECTOR_MARK (ptr);
6517 mark_object (XFINALIZER (obj)->function);
6626 break; 6518 break;
6627 6519
6628 case PVEC_SUBR: 6520 case PVEC_SUBR:
@@ -6680,49 +6572,9 @@ mark_object (Lisp_Object arg)
6680 } 6572 }
6681 break; 6573 break;
6682 6574
6683 case Lisp_Misc:
6684 CHECK_ALLOCATED_AND_LIVE (live_misc_p);
6685
6686 if (XMISCANY (obj)->gcmarkbit)
6687 break;
6688
6689 switch (XMISCTYPE (obj))
6690 {
6691 case Lisp_Misc_Marker:
6692 /* DO NOT mark thru the marker's chain.
6693 The buffer's markers chain does not preserve markers from gc;
6694 instead, markers are removed from the chain when freed by gc. */
6695 XMISCANY (obj)->gcmarkbit = 1;
6696 break;
6697
6698 case Lisp_Misc_Ptr:
6699 case Lisp_Misc_Bignum:
6700 XMISCANY (obj)->gcmarkbit = true;
6701 break;
6702
6703 case Lisp_Misc_Overlay:
6704 mark_overlay (XOVERLAY (obj));
6705 break;
6706
6707 case Lisp_Misc_Finalizer:
6708 XMISCANY (obj)->gcmarkbit = true;
6709 mark_object (XFINALIZER (obj)->function);
6710 break;
6711
6712#ifdef HAVE_MODULES
6713 case Lisp_Misc_User_Ptr:
6714 XMISCANY (obj)->gcmarkbit = true;
6715 break;
6716#endif
6717
6718 default:
6719 emacs_abort ();
6720 }
6721 break;
6722
6723 case Lisp_Cons: 6575 case Lisp_Cons:
6724 { 6576 {
6725 register struct Lisp_Cons *ptr = XCONS (obj); 6577 struct Lisp_Cons *ptr = XCONS (obj);
6726 if (CONS_MARKED_P (ptr)) 6578 if (CONS_MARKED_P (ptr))
6727 break; 6579 break;
6728 CHECK_ALLOCATED_AND_LIVE (live_cons_p); 6580 CHECK_ALLOCATED_AND_LIVE (live_cons_p);
@@ -6799,10 +6651,6 @@ survives_gc_p (Lisp_Object obj)
6799 survives_p = XSYMBOL (obj)->u.s.gcmarkbit; 6651 survives_p = XSYMBOL (obj)->u.s.gcmarkbit;
6800 break; 6652 break;
6801 6653
6802 case Lisp_Misc:
6803 survives_p = XMISCANY (obj)->gcmarkbit;
6804 break;
6805
6806 case Lisp_String: 6654 case Lisp_String:
6807 survives_p = STRING_MARKED_P (XSTRING (obj)); 6655 survives_p = STRING_MARKED_P (XSTRING (obj));
6808 break; 6656 break;
@@ -7079,81 +6927,6 @@ sweep_symbols (void)
7079 total_free_symbols = num_free; 6927 total_free_symbols = num_free;
7080} 6928}
7081 6929
7082NO_INLINE /* For better stack traces. */
7083static void
7084sweep_misc (void)
7085{
7086 register struct marker_block *mblk;
7087 struct marker_block **mprev = &marker_block;
7088 register int lim = marker_block_index;
7089 EMACS_INT num_free = 0, num_used = 0;
7090
7091 /* Put all unmarked misc's on free list. For a marker, first
7092 unchain it from the buffer it points into. */
7093
7094 misc_free_list = 0;
7095
7096 for (mblk = marker_block; mblk; mblk = *mprev)
7097 {
7098 register int i;
7099 int this_free = 0;
7100
7101 for (i = 0; i < lim; i++)
7102 {
7103 if (!mblk->markers[i].m.u_any.gcmarkbit)
7104 {
7105 if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker)
7106 /* Make sure markers have been unchained from their buffer
7107 in sweep_buffer before we collect them. */
7108 eassert (!mblk->markers[i].m.u_marker.buffer);
7109 else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Finalizer)
7110 unchain_finalizer (&mblk->markers[i].m.u_finalizer);
7111#ifdef HAVE_MODULES
7112 else if (mblk->markers[i].m.u_any.type == Lisp_Misc_User_Ptr)
7113 {
7114 struct Lisp_User_Ptr *uptr = &mblk->markers[i].m.u_user_ptr;
7115 if (uptr->finalizer)
7116 uptr->finalizer (uptr->p);
7117 }
7118#endif
7119 else if (mblk->markers[i].m.u_any.type == Lisp_Misc_Bignum)
7120 mpz_clear (mblk->markers[i].m.u_bignum.value);
7121 /* Set the type of the freed object to Lisp_Misc_Free.
7122 We could leave the type alone, since nobody checks it,
7123 but this might catch bugs faster. */
7124 mblk->markers[i].m.u_marker.type = Lisp_Misc_Free;
7125 mblk->markers[i].m.u_free.chain = misc_free_list;
7126 misc_free_list = &mblk->markers[i].m;
7127 this_free++;
7128 }
7129 else
7130 {
7131 num_used++;
7132 mblk->markers[i].m.u_any.gcmarkbit = 0;
7133 }
7134 }
7135 lim = MARKER_BLOCK_SIZE;
7136 /* If this block contains only free markers and we have already
7137 seen more than two blocks worth of free markers then deallocate
7138 this block. */
7139 if (this_free == MARKER_BLOCK_SIZE && num_free > MARKER_BLOCK_SIZE)
7140 {
7141 *mprev = mblk->next;
7142 /* Unhook from the free list. */
7143 misc_free_list = mblk->markers[0].m.u_free.chain;
7144 lisp_free (mblk);
7145 }
7146 else
7147 {
7148 num_free += this_free;
7149 mprev = &mblk->next;
7150 }
7151 }
7152
7153 total_markers = num_used;
7154 total_free_markers = num_free;
7155}
7156
7157/* Remove BUFFER's markers that are due to be swept. This is needed since 6930/* Remove BUFFER's markers that are due to be swept. This is needed since
7158 we treat BUF_MARKERS and markers's `next' field as weak pointers. */ 6931 we treat BUF_MARKERS and markers's `next' field as weak pointers. */
7159static void 6932static void
@@ -7162,7 +6935,7 @@ unchain_dead_markers (struct buffer *buffer)
7162 struct Lisp_Marker *this, **prev = &BUF_MARKERS (buffer); 6935 struct Lisp_Marker *this, **prev = &BUF_MARKERS (buffer);
7163 6936
7164 while ((this = *prev)) 6937 while ((this = *prev))
7165 if (this->gcmarkbit) 6938 if (VECTOR_MARKED_P (this))
7166 prev = &this->next; 6939 prev = &this->next;
7167 else 6940 else
7168 { 6941 {
@@ -7210,7 +6983,6 @@ gc_sweep (void)
7210 sweep_intervals (); 6983 sweep_intervals ();
7211 sweep_symbols (); 6984 sweep_symbols ();
7212 sweep_buffers (); 6985 sweep_buffers ();
7213 sweep_misc ();
7214 sweep_vectors (); 6986 sweep_vectors ();
7215 check_string_bytes (!noninteractive); 6987 check_string_bytes (!noninteractive);
7216} 6988}
@@ -7585,7 +7357,6 @@ do hash-consing of the objects allocated to pure space. */);
7585 7357
7586 DEFSYM (Qconses, "conses"); 7358 DEFSYM (Qconses, "conses");
7587 DEFSYM (Qsymbols, "symbols"); 7359 DEFSYM (Qsymbols, "symbols");
7588 DEFSYM (Qmiscs, "miscs");
7589 DEFSYM (Qstrings, "strings"); 7360 DEFSYM (Qstrings, "strings");
7590 DEFSYM (Qvectors, "vectors"); 7361 DEFSYM (Qvectors, "vectors");
7591 DEFSYM (Qfloats, "floats"); 7362 DEFSYM (Qfloats, "floats");