aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert2018-08-08 19:46:29 -0700
committerPaul Eggert2018-08-11 18:50:25 -0700
commitd614e4a8cd2d5fe37b38bb4d8191013a7d917731 (patch)
treef27e866dc009cba536575c9a30af362296a9b60e /src/alloc.c
parentd3ec5117da3146573cad5c1f8d01ab2e58f21e92 (diff)
downloademacs-d614e4a8cd2d5fe37b38bb4d8191013a7d917731.tar.gz
emacs-d614e4a8cd2d5fe37b38bb4d8191013a7d917731.zip
Turn misc objects into pseudovectors
Eliminate the category of miscellaneous objects, and turn all such objects into pseudovectors. The immediate motivation for this change is to free up an enum Lisp_Type tag value, a scarce resource that can be better used elsewhere. However, this change is worthwhile in its own right, as it improves performance slightly on my platform, 0.3% faster for 'make compile-always' on Fedora 28, and it simplifies the garbage collector and interpreter (Bug#32405). * doc/lispref/internals.texi (Garbage Collection): * etc/NEWS: Document change to garbage-collect return value. * src/alloc.c (total_markers, total_free_markers): (union aligned_Lisp_Misc, MARKER_BLOCK_SIZE) (struct marker_block, marker_block, marker_block_index) (misc_free_list, allocate_misc, live_misc_holding) (live_misc_p, sweep_misc): * src/lisp.h (lisp_h_MARKERP, lisp_h_MISCP, MARKERP, MISCP) (Lisp_Misc, enum Lisp_Misc_Type, Lisp_Misc_Free) (Lisp_Misc_Marker, Lisp_Misc_Overlay, Lisp_Misc_Finalizer) (Lisp_Misc_Ptr, Lisp_Misc_User_Ptr, Lisp_Misc_Limit) (Lisp_Misc_Bignum) (XSETMISC, struct Lisp_Misc_Any, XMISCANY, XMISCTYPE) (struct Lisp_Free, union Lisp_Misc, XMISC): Remove. All uses removed. (cleanup_vector): Clean up objects that were formerly misc and are now pseudovectors. (make_misc_ptr, build_overlay, Fmake_marker, build_marker) (make_bignum_str, make_number, make_pure_bignum) (make_user_ptr, Fmake_finalizer): Build as pseudovectors, not as misc objects. (mark_finalizer_list, queue_doomed_finalizers) (compact_undo_list, mark_overlay, mark_object) (unchain_dead_markers): Mark as vector-like objects, not as misc objects. (mark_maybe_object, mark_maybe_pointer, valid_lisp_object_p) (total_bytes_of_live_objects, survives_gc_p): * src/fns.c (sxhash): No need to worry about misc objects. (garbage_collect_1): Do not generate a 'misc' component. (syms_of_alloc): No need for 'misc' symbol. * src/buffer.c (overlays_at, overlays_in, overlay_touches_p) (overlay_strings, recenter_overlay_lists) (fix_start_end_in_overlays, fix_overlays_before) (Foverlay_lists, report_overlay_modification) (evaporate_overlays): * src/editfns.c (overlays_around): * src/data.c (Ftype_of): * src/fns.c (internal_equal): * src/lisp.h (mint_ptrp, xmint_pointer, FINALIZERP) (XFINALIZER, MARKERP, XMARKER, OVERLAYP, XOVERLAY, USER_PTRP) (XUSER_PTR, BIGNUMP, XBIGNUM): * src/print.c (print_vectorlike, print_object): * src/undo.c (record_marker_adjustments): * src/xdisp.c (load_overlay_strings): Formerly misc objects are now pseudovectors. * src/lisp.h (PVEC_MARKER, PVEC_OVERLAY, PVEC_FINALIZER) (PVEC_BIGNUM, PVEC_MISC_PTR, PVEC_USER_PTR): New constants, replacing their misc versions. All uses changed. (struct Lisp_Marker, struct Lisp_Overlay, struct Lisp_Misc_Ptr) (struct Lisp_Bignum, struct Lisp_User_Ptr, struct Lisp_Finalizer): Make usable as a pseudovector by using a pseudovector header, replacing any DIY components, and putting Lisp_Object members first. All uses changed.
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");