aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/alloc.c393
-rw-r--r--src/buffer.c250
-rw-r--r--src/data.c27
-rw-r--r--src/editfns.c31
-rw-r--r--src/fns.c58
-rw-r--r--src/lisp.h218
-rw-r--r--src/print.c165
-rw-r--r--src/undo.c14
-rw-r--r--src/xdisp.c45
9 files changed, 395 insertions, 806 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");
diff --git a/src/buffer.c b/src/buffer.c
index ec6f4647119..878844dd020 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2789,8 +2789,6 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr,
2789 ptrdiff_t *len_ptr, 2789 ptrdiff_t *len_ptr,
2790 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req) 2790 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr, bool change_req)
2791{ 2791{
2792 Lisp_Object overlay, start, end;
2793 struct Lisp_Overlay *tail;
2794 ptrdiff_t idx = 0; 2792 ptrdiff_t idx = 0;
2795 ptrdiff_t len = *len_ptr; 2793 ptrdiff_t len = *len_ptr;
2796 Lisp_Object *vec = *vec_ptr; 2794 Lisp_Object *vec = *vec_ptr;
@@ -2798,22 +2796,20 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr,
2798 ptrdiff_t prev = BEGV; 2796 ptrdiff_t prev = BEGV;
2799 bool inhibit_storing = 0; 2797 bool inhibit_storing = 0;
2800 2798
2801 for (tail = current_buffer->overlays_before; tail; tail = tail->next) 2799 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
2800 tail; tail = tail->next)
2802 { 2801 {
2803 ptrdiff_t startpos, endpos; 2802 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
2804 2803 Lisp_Object start = OVERLAY_START (overlay);
2805 XSETMISC (overlay, tail); 2804 Lisp_Object end = OVERLAY_END (overlay);
2806 2805 ptrdiff_t endpos = OVERLAY_POSITION (end);
2807 start = OVERLAY_START (overlay);
2808 end = OVERLAY_END (overlay);
2809 endpos = OVERLAY_POSITION (end);
2810 if (endpos < pos) 2806 if (endpos < pos)
2811 { 2807 {
2812 if (prev < endpos) 2808 if (prev < endpos)
2813 prev = endpos; 2809 prev = endpos;
2814 break; 2810 break;
2815 } 2811 }
2816 startpos = OVERLAY_POSITION (start); 2812 ptrdiff_t startpos = OVERLAY_POSITION (start);
2817 /* This one ends at or after POS 2813 /* This one ends at or after POS
2818 so its start counts for PREV_PTR if it's before POS. */ 2814 so its start counts for PREV_PTR if it's before POS. */
2819 if (prev < startpos && startpos < pos) 2815 if (prev < startpos && startpos < pos)
@@ -2846,22 +2842,20 @@ overlays_at (EMACS_INT pos, bool extend, Lisp_Object **vec_ptr,
2846 next = startpos; 2842 next = startpos;
2847 } 2843 }
2848 2844
2849 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 2845 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
2846 tail; tail = tail->next)
2850 { 2847 {
2851 ptrdiff_t startpos, endpos; 2848 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
2852 2849 Lisp_Object start = OVERLAY_START (overlay);
2853 XSETMISC (overlay, tail); 2850 Lisp_Object end = OVERLAY_END (overlay);
2854 2851 ptrdiff_t startpos = OVERLAY_POSITION (start);
2855 start = OVERLAY_START (overlay);
2856 end = OVERLAY_END (overlay);
2857 startpos = OVERLAY_POSITION (start);
2858 if (pos < startpos) 2852 if (pos < startpos)
2859 { 2853 {
2860 if (startpos < next) 2854 if (startpos < next)
2861 next = startpos; 2855 next = startpos;
2862 break; 2856 break;
2863 } 2857 }
2864 endpos = OVERLAY_POSITION (end); 2858 ptrdiff_t endpos = OVERLAY_POSITION (end);
2865 if (pos < endpos) 2859 if (pos < endpos)
2866 { 2860 {
2867 if (idx == len) 2861 if (idx == len)
@@ -2923,8 +2917,6 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend,
2923 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr, 2917 Lisp_Object **vec_ptr, ptrdiff_t *len_ptr,
2924 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr) 2918 ptrdiff_t *next_ptr, ptrdiff_t *prev_ptr)
2925{ 2919{
2926 Lisp_Object overlay, ostart, oend;
2927 struct Lisp_Overlay *tail;
2928 ptrdiff_t idx = 0; 2920 ptrdiff_t idx = 0;
2929 ptrdiff_t len = *len_ptr; 2921 ptrdiff_t len = *len_ptr;
2930 Lisp_Object *vec = *vec_ptr; 2922 Lisp_Object *vec = *vec_ptr;
@@ -2933,22 +2925,20 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend,
2933 bool inhibit_storing = 0; 2925 bool inhibit_storing = 0;
2934 bool end_is_Z = end == Z; 2926 bool end_is_Z = end == Z;
2935 2927
2936 for (tail = current_buffer->overlays_before; tail; tail = tail->next) 2928 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
2929 tail; tail = tail->next)
2937 { 2930 {
2938 ptrdiff_t startpos, endpos; 2931 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
2939 2932 Lisp_Object ostart = OVERLAY_START (overlay);
2940 XSETMISC (overlay, tail); 2933 Lisp_Object oend = OVERLAY_END (overlay);
2941 2934 ptrdiff_t endpos = OVERLAY_POSITION (oend);
2942 ostart = OVERLAY_START (overlay);
2943 oend = OVERLAY_END (overlay);
2944 endpos = OVERLAY_POSITION (oend);
2945 if (endpos < beg) 2935 if (endpos < beg)
2946 { 2936 {
2947 if (prev < endpos) 2937 if (prev < endpos)
2948 prev = endpos; 2938 prev = endpos;
2949 break; 2939 break;
2950 } 2940 }
2951 startpos = OVERLAY_POSITION (ostart); 2941 ptrdiff_t startpos = OVERLAY_POSITION (ostart);
2952 /* Count an interval if it overlaps the range, is empty at the 2942 /* Count an interval if it overlaps the range, is empty at the
2953 start of the range, or is empty at END provided END denotes the 2943 start of the range, or is empty at END provided END denotes the
2954 end of the buffer. */ 2944 end of the buffer. */
@@ -2980,22 +2970,20 @@ overlays_in (EMACS_INT beg, EMACS_INT end, bool extend,
2980 next = startpos; 2970 next = startpos;
2981 } 2971 }
2982 2972
2983 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 2973 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
2974 tail; tail = tail->next)
2984 { 2975 {
2985 ptrdiff_t startpos, endpos; 2976 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
2986 2977 Lisp_Object ostart = OVERLAY_START (overlay);
2987 XSETMISC (overlay, tail); 2978 Lisp_Object oend = OVERLAY_END (overlay);
2988 2979 ptrdiff_t startpos = OVERLAY_POSITION (ostart);
2989 ostart = OVERLAY_START (overlay);
2990 oend = OVERLAY_END (overlay);
2991 startpos = OVERLAY_POSITION (ostart);
2992 if (end < startpos) 2980 if (end < startpos)
2993 { 2981 {
2994 if (startpos < next) 2982 if (startpos < next)
2995 next = startpos; 2983 next = startpos;
2996 break; 2984 break;
2997 } 2985 }
2998 endpos = OVERLAY_POSITION (oend); 2986 ptrdiff_t endpos = OVERLAY_POSITION (oend);
2999 /* Count an interval if it overlaps the range, is empty at the 2987 /* Count an interval if it overlaps the range, is empty at the
3000 start of the range, or is empty at END provided END denotes the 2988 start of the range, or is empty at END provided END denotes the
3001 end of the buffer. */ 2989 end of the buffer. */
@@ -3097,31 +3085,26 @@ disable_line_numbers_overlay_at_eob (void)
3097bool 3085bool
3098overlay_touches_p (ptrdiff_t pos) 3086overlay_touches_p (ptrdiff_t pos)
3099{ 3087{
3100 Lisp_Object overlay; 3088 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
3101 struct Lisp_Overlay *tail; 3089 tail; tail = tail->next)
3102
3103 for (tail = current_buffer->overlays_before; tail; tail = tail->next)
3104 { 3090 {
3105 ptrdiff_t endpos; 3091 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3106
3107 XSETMISC (overlay ,tail);
3108 eassert (OVERLAYP (overlay)); 3092 eassert (OVERLAYP (overlay));
3109 3093
3110 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3094 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3111 if (endpos < pos) 3095 if (endpos < pos)
3112 break; 3096 break;
3113 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos) 3097 if (endpos == pos || OVERLAY_POSITION (OVERLAY_START (overlay)) == pos)
3114 return 1; 3098 return 1;
3115 } 3099 }
3116 3100
3117 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 3101 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
3102 tail; tail = tail->next)
3118 { 3103 {
3119 ptrdiff_t startpos; 3104 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3120
3121 XSETMISC (overlay, tail);
3122 eassert (OVERLAYP (overlay)); 3105 eassert (OVERLAYP (overlay));
3123 3106
3124 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3107 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3125 if (pos < startpos) 3108 if (pos < startpos)
3126 break; 3109 break;
3127 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos) 3110 if (startpos == pos || OVERLAY_POSITION (OVERLAY_END (overlay)) == pos)
@@ -3337,27 +3320,26 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
3337ptrdiff_t 3320ptrdiff_t
3338overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) 3321overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3339{ 3322{
3340 Lisp_Object overlay, window, str;
3341 struct Lisp_Overlay *ov;
3342 ptrdiff_t startpos, endpos;
3343 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters)); 3323 bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
3344 3324
3345 overlay_heads.used = overlay_heads.bytes = 0; 3325 overlay_heads.used = overlay_heads.bytes = 0;
3346 overlay_tails.used = overlay_tails.bytes = 0; 3326 overlay_tails.used = overlay_tails.bytes = 0;
3347 for (ov = current_buffer->overlays_before; ov; ov = ov->next) 3327 for (struct Lisp_Overlay *ov = current_buffer->overlays_before;
3328 ov; ov = ov->next)
3348 { 3329 {
3349 XSETMISC (overlay, ov); 3330 Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
3350 eassert (OVERLAYP (overlay)); 3331 eassert (OVERLAYP (overlay));
3351 3332
3352 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3333 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3353 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3334 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3354 if (endpos < pos) 3335 if (endpos < pos)
3355 break; 3336 break;
3356 if (endpos != pos && startpos != pos) 3337 if (endpos != pos && startpos != pos)
3357 continue; 3338 continue;
3358 window = Foverlay_get (overlay, Qwindow); 3339 Lisp_Object window = Foverlay_get (overlay, Qwindow);
3359 if (WINDOWP (window) && XWINDOW (window) != w) 3340 if (WINDOWP (window) && XWINDOW (window) != w)
3360 continue; 3341 continue;
3342 Lisp_Object str;
3361 if (startpos == pos 3343 if (startpos == pos
3362 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) 3344 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3363 record_overlay_string (&overlay_heads, str, 3345 record_overlay_string (&overlay_heads, str,
@@ -3372,20 +3354,22 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3372 Foverlay_get (overlay, Qpriority), 3354 Foverlay_get (overlay, Qpriority),
3373 endpos - startpos); 3355 endpos - startpos);
3374 } 3356 }
3375 for (ov = current_buffer->overlays_after; ov; ov = ov->next) 3357 for (struct Lisp_Overlay *ov = current_buffer->overlays_after;
3358 ov; ov = ov->next)
3376 { 3359 {
3377 XSETMISC (overlay, ov); 3360 Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
3378 eassert (OVERLAYP (overlay)); 3361 eassert (OVERLAYP (overlay));
3379 3362
3380 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3363 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3381 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3364 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3382 if (startpos > pos) 3365 if (startpos > pos)
3383 break; 3366 break;
3384 if (endpos != pos && startpos != pos) 3367 if (endpos != pos && startpos != pos)
3385 continue; 3368 continue;
3386 window = Foverlay_get (overlay, Qwindow); 3369 Lisp_Object window = Foverlay_get (overlay, Qwindow);
3387 if (WINDOWP (window) && XWINDOW (window) != w) 3370 if (WINDOWP (window) && XWINDOW (window) != w)
3388 continue; 3371 continue;
3372 Lisp_Object str;
3389 if (startpos == pos 3373 if (startpos == pos
3390 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))) 3374 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)))
3391 record_overlay_string (&overlay_heads, str, 3375 record_overlay_string (&overlay_heads, str,
@@ -3460,8 +3444,7 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
3460void 3444void
3461recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos) 3445recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
3462{ 3446{
3463 Lisp_Object overlay, beg, end; 3447 struct Lisp_Overlay *prev, *next;
3464 struct Lisp_Overlay *prev, *tail, *next;
3465 3448
3466 /* See if anything in overlays_before should move to overlays_after. */ 3449 /* See if anything in overlays_before should move to overlays_after. */
3467 3450
@@ -3469,14 +3452,15 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
3469 But we use it for symmetry and in case that should cease to be true 3452 But we use it for symmetry and in case that should cease to be true
3470 with some future change. */ 3453 with some future change. */
3471 prev = NULL; 3454 prev = NULL;
3472 for (tail = buf->overlays_before; tail; prev = tail, tail = next) 3455 for (struct Lisp_Overlay *tail = buf->overlays_before;
3456 tail; prev = tail, tail = next)
3473 { 3457 {
3474 next = tail->next; 3458 next = tail->next;
3475 XSETMISC (overlay, tail); 3459 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3476 eassert (OVERLAYP (overlay)); 3460 eassert (OVERLAYP (overlay));
3477 3461
3478 beg = OVERLAY_START (overlay); 3462 Lisp_Object beg = OVERLAY_START (overlay);
3479 end = OVERLAY_END (overlay); 3463 Lisp_Object end = OVERLAY_END (overlay);
3480 3464
3481 if (OVERLAY_POSITION (end) > pos) 3465 if (OVERLAY_POSITION (end) > pos)
3482 { 3466 {
@@ -3495,12 +3479,10 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
3495 for (other = buf->overlays_after; other; 3479 for (other = buf->overlays_after; other;
3496 other_prev = other, other = other->next) 3480 other_prev = other, other = other->next)
3497 { 3481 {
3498 Lisp_Object otherbeg, otheroverlay; 3482 Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
3499
3500 XSETMISC (otheroverlay, other);
3501 eassert (OVERLAYP (otheroverlay)); 3483 eassert (OVERLAYP (otheroverlay));
3502 3484
3503 otherbeg = OVERLAY_START (otheroverlay); 3485 Lisp_Object otherbeg = OVERLAY_START (otheroverlay);
3504 if (OVERLAY_POSITION (otherbeg) >= where) 3486 if (OVERLAY_POSITION (otherbeg) >= where)
3505 break; 3487 break;
3506 } 3488 }
@@ -3522,14 +3504,15 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
3522 3504
3523 /* See if anything in overlays_after should be in overlays_before. */ 3505 /* See if anything in overlays_after should be in overlays_before. */
3524 prev = NULL; 3506 prev = NULL;
3525 for (tail = buf->overlays_after; tail; prev = tail, tail = next) 3507 for (struct Lisp_Overlay *tail = buf->overlays_after;
3508 tail; prev = tail, tail = next)
3526 { 3509 {
3527 next = tail->next; 3510 next = tail->next;
3528 XSETMISC (overlay, tail); 3511 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3529 eassert (OVERLAYP (overlay)); 3512 eassert (OVERLAYP (overlay));
3530 3513
3531 beg = OVERLAY_START (overlay); 3514 Lisp_Object beg = OVERLAY_START (overlay);
3532 end = OVERLAY_END (overlay); 3515 Lisp_Object end = OVERLAY_END (overlay);
3533 3516
3534 /* Stop looking, when we know that nothing further 3517 /* Stop looking, when we know that nothing further
3535 can possibly end before POS. */ 3518 can possibly end before POS. */
@@ -3553,12 +3536,10 @@ recenter_overlay_lists (struct buffer *buf, ptrdiff_t pos)
3553 for (other = buf->overlays_before; other; 3536 for (other = buf->overlays_before; other;
3554 other_prev = other, other = other->next) 3537 other_prev = other, other = other->next)
3555 { 3538 {
3556 Lisp_Object otherend, otheroverlay; 3539 Lisp_Object otheroverlay = make_lisp_ptr (other, Lisp_Vectorlike);
3557
3558 XSETMISC (otheroverlay, other);
3559 eassert (OVERLAYP (otheroverlay)); 3540 eassert (OVERLAYP (otheroverlay));
3560 3541
3561 otherend = OVERLAY_END (otheroverlay); 3542 Lisp_Object otherend = OVERLAY_END (otheroverlay);
3562 if (OVERLAY_POSITION (otherend) <= where) 3543 if (OVERLAY_POSITION (otherend) <= where)
3563 break; 3544 break;
3564 } 3545 }
@@ -3613,7 +3594,6 @@ adjust_overlays_for_delete (ptrdiff_t pos, ptrdiff_t length)
3613void 3594void
3614fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) 3595fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
3615{ 3596{
3616 Lisp_Object overlay;
3617 struct Lisp_Overlay *before_list UNINIT; 3597 struct Lisp_Overlay *before_list UNINIT;
3618 struct Lisp_Overlay *after_list UNINIT; 3598 struct Lisp_Overlay *after_list UNINIT;
3619 /* These are either nil, indicating that before_list or after_list 3599 /* These are either nil, indicating that before_list or after_list
@@ -3623,8 +3603,7 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
3623 /* 'Parent', likewise, indicates a cons cell or 3603 /* 'Parent', likewise, indicates a cons cell or
3624 current_buffer->overlays_before or overlays_after, depending 3604 current_buffer->overlays_before or overlays_after, depending
3625 which loop we're in. */ 3605 which loop we're in. */
3626 struct Lisp_Overlay *tail, *parent; 3606 struct Lisp_Overlay *parent;
3627 ptrdiff_t startpos, endpos;
3628 3607
3629 /* This algorithm shifts links around instead of consing and GCing. 3608 /* This algorithm shifts links around instead of consing and GCing.
3630 The loop invariant is that before_list (resp. after_list) is a 3609 The loop invariant is that before_list (resp. after_list) is a
@@ -3633,12 +3612,14 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
3633 (after_list) if it is, is still uninitialized. So it's not a bug 3612 (after_list) if it is, is still uninitialized. So it's not a bug
3634 that before_list isn't initialized, although it may look 3613 that before_list isn't initialized, although it may look
3635 strange. */ 3614 strange. */
3636 for (parent = NULL, tail = current_buffer->overlays_before; tail;) 3615 parent = NULL;
3616 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
3617 tail; tail = tail->next)
3637 { 3618 {
3638 XSETMISC (overlay, tail); 3619 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3639 3620
3640 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3621 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3641 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3622 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3642 3623
3643 /* If the overlay is backwards, make it empty. */ 3624 /* If the overlay is backwards, make it empty. */
3644 if (endpos < startpos) 3625 if (endpos < startpos)
@@ -3676,17 +3657,18 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
3676 set_buffer_overlays_before (current_buffer, tail->next); 3657 set_buffer_overlays_before (current_buffer, tail->next);
3677 else 3658 else
3678 parent->next = tail->next; 3659 parent->next = tail->next;
3679 tail = tail->next;
3680 } 3660 }
3681 else 3661 else
3682 parent = tail, tail = parent->next; 3662 parent = tail;
3683 } 3663 }
3684 for (parent = NULL, tail = current_buffer->overlays_after; tail;) 3664 parent = NULL;
3665 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
3666 tail; tail = tail->next)
3685 { 3667 {
3686 XSETMISC (overlay, tail); 3668 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
3687 3669
3688 startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); 3670 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
3689 endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); 3671 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
3690 3672
3691 /* If the overlay is backwards, make it empty. */ 3673 /* If the overlay is backwards, make it empty. */
3692 if (endpos < startpos) 3674 if (endpos < startpos)
@@ -3722,10 +3704,9 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
3722 set_buffer_overlays_after (current_buffer, tail->next); 3704 set_buffer_overlays_after (current_buffer, tail->next);
3723 else 3705 else
3724 parent->next = tail->next; 3706 parent->next = tail->next;
3725 tail = tail->next;
3726 } 3707 }
3727 else 3708 else
3728 parent = tail, tail = parent->next; 3709 parent = tail;
3729 } 3710 }
3730 3711
3731 /* Splice the constructed (wrong) lists into the buffer's lists, 3712 /* Splice the constructed (wrong) lists into the buffer's lists,
@@ -3776,7 +3757,7 @@ fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
3776 overlay whose ending marker is after-insertion-marker if disorder 3757 overlay whose ending marker is after-insertion-marker if disorder
3777 exists). */ 3758 exists). */
3778 while (tail 3759 while (tail
3779 && (XSETMISC (tem, tail), 3760 && (tem = make_lisp_ptr (tail, Lisp_Vectorlike),
3780 (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos)) 3761 (end = OVERLAY_POSITION (OVERLAY_END (tem))) >= pos))
3781 { 3762 {
3782 parent = tail; 3763 parent = tail;
@@ -3801,7 +3782,7 @@ fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos)
3801 overlays are in correct order. */ 3782 overlays are in correct order. */
3802 while (tail) 3783 while (tail)
3803 { 3784 {
3804 XSETMISC (tem, tail); 3785 tem = make_lisp_ptr (tail, Lisp_Vectorlike);
3805 end = OVERLAY_POSITION (OVERLAY_END (tem)); 3786 end = OVERLAY_POSITION (OVERLAY_END (tem));
3806 3787
3807 if (end == pos) 3788 if (end == pos)
@@ -4308,19 +4289,14 @@ The lists you get are copies, so that changing them has no effect.
4308However, the overlays you get are the real objects that the buffer uses. */) 4289However, the overlays you get are the real objects that the buffer uses. */)
4309 (void) 4290 (void)
4310{ 4291{
4311 struct Lisp_Overlay *ol; 4292 Lisp_Object before = Qnil, after = Qnil;
4312 Lisp_Object before = Qnil, after = Qnil, tmp;
4313 4293
4314 for (ol = current_buffer->overlays_before; ol; ol = ol->next) 4294 for (struct Lisp_Overlay *ol = current_buffer->overlays_before;
4315 { 4295 ol; ol = ol->next)
4316 XSETMISC (tmp, ol); 4296 before = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), before);
4317 before = Fcons (tmp, before); 4297 for (struct Lisp_Overlay *ol = current_buffer->overlays_after;
4318 } 4298 ol; ol = ol->next)
4319 for (ol = current_buffer->overlays_after; ol; ol = ol->next) 4299 after = Fcons (make_lisp_ptr (ol, Lisp_Vectorlike), after);
4320 {
4321 XSETMISC (tmp, ol);
4322 after = Fcons (tmp, after);
4323 }
4324 4300
4325 return Fcons (Fnreverse (before), Fnreverse (after)); 4301 return Fcons (Fnreverse (before), Fnreverse (after));
4326} 4302}
@@ -4439,14 +4415,9 @@ void
4439report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after, 4415report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4440 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3) 4416 Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3)
4441{ 4417{
4442 Lisp_Object prop, overlay;
4443 struct Lisp_Overlay *tail;
4444 /* True if this change is an insertion. */ 4418 /* True if this change is an insertion. */
4445 bool insertion = (after ? XFIXNAT (arg3) == 0 : EQ (start, end)); 4419 bool insertion = (after ? XFIXNAT (arg3) == 0 : EQ (start, end));
4446 4420
4447 overlay = Qnil;
4448 tail = NULL;
4449
4450 /* We used to run the functions as soon as we found them and only register 4421 /* We used to run the functions as soon as we found them and only register
4451 them in last_overlay_modification_hooks for the purpose of the `after' 4422 them in last_overlay_modification_hooks for the purpose of the `after'
4452 case. But running elisp code as we traverse the list of overlays is 4423 case. But running elisp code as we traverse the list of overlays is
@@ -4460,12 +4431,13 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4460 /* We are being called before a change. 4431 /* We are being called before a change.
4461 Scan the overlays to find the functions to call. */ 4432 Scan the overlays to find the functions to call. */
4462 last_overlay_modification_hooks_used = 0; 4433 last_overlay_modification_hooks_used = 0;
4463 for (tail = current_buffer->overlays_before; tail; tail = tail->next) 4434 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
4435 tail; tail = tail->next)
4464 { 4436 {
4465 ptrdiff_t startpos, endpos; 4437 ptrdiff_t startpos, endpos;
4466 Lisp_Object ostart, oend; 4438 Lisp_Object ostart, oend;
4467 4439
4468 XSETMISC (overlay, tail); 4440 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4469 4441
4470 ostart = OVERLAY_START (overlay); 4442 ostart = OVERLAY_START (overlay);
4471 oend = OVERLAY_END (overlay); 4443 oend = OVERLAY_END (overlay);
@@ -4476,14 +4448,14 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4476 if (insertion && (XFIXNAT (start) == startpos 4448 if (insertion && (XFIXNAT (start) == startpos
4477 || XFIXNAT (end) == startpos)) 4449 || XFIXNAT (end) == startpos))
4478 { 4450 {
4479 prop = Foverlay_get (overlay, Qinsert_in_front_hooks); 4451 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4480 if (!NILP (prop)) 4452 if (!NILP (prop))
4481 add_overlay_mod_hooklist (prop, overlay); 4453 add_overlay_mod_hooklist (prop, overlay);
4482 } 4454 }
4483 if (insertion && (XFIXNAT (start) == endpos 4455 if (insertion && (XFIXNAT (start) == endpos
4484 || XFIXNAT (end) == endpos)) 4456 || XFIXNAT (end) == endpos))
4485 { 4457 {
4486 prop = Foverlay_get (overlay, Qinsert_behind_hooks); 4458 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4487 if (!NILP (prop)) 4459 if (!NILP (prop))
4488 add_overlay_mod_hooklist (prop, overlay); 4460 add_overlay_mod_hooklist (prop, overlay);
4489 } 4461 }
@@ -4491,18 +4463,19 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4491 for both insertion and deletion. */ 4463 for both insertion and deletion. */
4492 if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos) 4464 if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
4493 { 4465 {
4494 prop = Foverlay_get (overlay, Qmodification_hooks); 4466 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
4495 if (!NILP (prop)) 4467 if (!NILP (prop))
4496 add_overlay_mod_hooklist (prop, overlay); 4468 add_overlay_mod_hooklist (prop, overlay);
4497 } 4469 }
4498 } 4470 }
4499 4471
4500 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 4472 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
4473 tail; tail = tail->next)
4501 { 4474 {
4502 ptrdiff_t startpos, endpos; 4475 ptrdiff_t startpos, endpos;
4503 Lisp_Object ostart, oend; 4476 Lisp_Object ostart, oend;
4504 4477
4505 XSETMISC (overlay, tail); 4478 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4506 4479
4507 ostart = OVERLAY_START (overlay); 4480 ostart = OVERLAY_START (overlay);
4508 oend = OVERLAY_END (overlay); 4481 oend = OVERLAY_END (overlay);
@@ -4513,14 +4486,14 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4513 if (insertion && (XFIXNAT (start) == startpos 4486 if (insertion && (XFIXNAT (start) == startpos
4514 || XFIXNAT (end) == startpos)) 4487 || XFIXNAT (end) == startpos))
4515 { 4488 {
4516 prop = Foverlay_get (overlay, Qinsert_in_front_hooks); 4489 Lisp_Object prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
4517 if (!NILP (prop)) 4490 if (!NILP (prop))
4518 add_overlay_mod_hooklist (prop, overlay); 4491 add_overlay_mod_hooklist (prop, overlay);
4519 } 4492 }
4520 if (insertion && (XFIXNAT (start) == endpos 4493 if (insertion && (XFIXNAT (start) == endpos
4521 || XFIXNAT (end) == endpos)) 4494 || XFIXNAT (end) == endpos))
4522 { 4495 {
4523 prop = Foverlay_get (overlay, Qinsert_behind_hooks); 4496 Lisp_Object prop = Foverlay_get (overlay, Qinsert_behind_hooks);
4524 if (!NILP (prop)) 4497 if (!NILP (prop))
4525 add_overlay_mod_hooklist (prop, overlay); 4498 add_overlay_mod_hooklist (prop, overlay);
4526 } 4499 }
@@ -4528,7 +4501,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
4528 for both insertion and deletion. */ 4501 for both insertion and deletion. */
4529 if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos) 4502 if (XFIXNAT (end) > startpos && XFIXNAT (start) < endpos)
4530 { 4503 {
4531 prop = Foverlay_get (overlay, Qmodification_hooks); 4504 Lisp_Object prop = Foverlay_get (overlay, Qmodification_hooks);
4532 if (!NILP (prop)) 4505 if (!NILP (prop))
4533 add_overlay_mod_hooklist (prop, overlay); 4506 add_overlay_mod_hooklist (prop, overlay);
4534 } 4507 }
@@ -4596,16 +4569,13 @@ call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, bool after,
4596void 4569void
4597evaporate_overlays (ptrdiff_t pos) 4570evaporate_overlays (ptrdiff_t pos)
4598{ 4571{
4599 Lisp_Object overlay, hit_list; 4572 Lisp_Object hit_list = Qnil;
4600 struct Lisp_Overlay *tail;
4601
4602 hit_list = Qnil;
4603 if (pos <= current_buffer->overlay_center) 4573 if (pos <= current_buffer->overlay_center)
4604 for (tail = current_buffer->overlays_before; tail; tail = tail->next) 4574 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
4575 tail; tail = tail->next)
4605 { 4576 {
4606 ptrdiff_t endpos; 4577 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4607 XSETMISC (overlay, tail); 4578 ptrdiff_t endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
4608 endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
4609 if (endpos < pos) 4579 if (endpos < pos)
4610 break; 4580 break;
4611 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos 4581 if (endpos == pos && OVERLAY_POSITION (OVERLAY_START (overlay)) == pos
@@ -4613,11 +4583,11 @@ evaporate_overlays (ptrdiff_t pos)
4613 hit_list = Fcons (overlay, hit_list); 4583 hit_list = Fcons (overlay, hit_list);
4614 } 4584 }
4615 else 4585 else
4616 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 4586 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
4587 tail; tail = tail->next)
4617 { 4588 {
4618 ptrdiff_t startpos; 4589 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
4619 XSETMISC (overlay, tail); 4590 ptrdiff_t startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
4620 startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
4621 if (startpos > pos) 4591 if (startpos > pos)
4622 break; 4592 break;
4623 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos 4593 if (startpos == pos && OVERLAY_POSITION (OVERLAY_END (overlay)) == pos
diff --git a/src/data.c b/src/data.c
index 7d701fde0e2..c8a9c6b3783 100644
--- a/src/data.c
+++ b/src/data.c
@@ -221,29 +221,17 @@ for example, (type-of 1) returns `integer'. */)
221 case Lisp_Cons: 221 case Lisp_Cons:
222 return Qcons; 222 return Qcons;
223 223
224 case Lisp_Misc:
225 switch (XMISCTYPE (object))
226 {
227 case Lisp_Misc_Marker:
228 return Qmarker;
229 case Lisp_Misc_Overlay:
230 return Qoverlay;
231 case Lisp_Misc_Finalizer:
232 return Qfinalizer;
233#ifdef HAVE_MODULES
234 case Lisp_Misc_User_Ptr:
235 return Quser_ptr;
236#endif
237 case Lisp_Misc_Bignum:
238 return Qinteger;
239 default:
240 emacs_abort ();
241 }
242
243 case Lisp_Vectorlike: 224 case Lisp_Vectorlike:
244 switch (PSEUDOVECTOR_TYPE (XVECTOR (object))) 225 switch (PSEUDOVECTOR_TYPE (XVECTOR (object)))
245 { 226 {
246 case PVEC_NORMAL_VECTOR: return Qvector; 227 case PVEC_NORMAL_VECTOR: return Qvector;
228 case PVEC_BIGNUM: return Qinteger;
229 case PVEC_MARKER: return Qmarker;
230 case PVEC_OVERLAY: return Qoverlay;
231 case PVEC_FINALIZER: return Qfinalizer;
232#ifdef HAVE_MODULES
233 case PVEC_USER_PTR: return Quser_ptr;
234#endif
247 case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration; 235 case PVEC_WINDOW_CONFIGURATION: return Qwindow_configuration;
248 case PVEC_PROCESS: return Qprocess; 236 case PVEC_PROCESS: return Qprocess;
249 case PVEC_WINDOW: return Qwindow; 237 case PVEC_WINDOW: return Qwindow;
@@ -279,6 +267,7 @@ for example, (type-of 1) returns `integer'. */)
279 case PVEC_MODULE_FUNCTION: 267 case PVEC_MODULE_FUNCTION:
280 return Qmodule_function; 268 return Qmodule_function;
281 /* "Impossible" cases. */ 269 /* "Impossible" cases. */
270 case PVEC_MISC_PTR:
282 case PVEC_XWIDGET: 271 case PVEC_XWIDGET:
283 case PVEC_OTHER: 272 case PVEC_OTHER:
284 case PVEC_XWIDGET_VIEW: 273 case PVEC_XWIDGET_VIEW:
diff --git a/src/editfns.c b/src/editfns.c
index a0a66bd19ab..92566fe3bbe 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -484,21 +484,18 @@ If you set the marker not to point anywhere, the buffer will have no mark. */)
484static ptrdiff_t 484static ptrdiff_t
485overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len) 485overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len)
486{ 486{
487 Lisp_Object overlay, start, end;
488 struct Lisp_Overlay *tail;
489 ptrdiff_t startpos, endpos;
490 ptrdiff_t idx = 0; 487 ptrdiff_t idx = 0;
491 488
492 for (tail = current_buffer->overlays_before; tail; tail = tail->next) 489 for (struct Lisp_Overlay *tail = current_buffer->overlays_before;
490 tail; tail = tail->next)
493 { 491 {
494 XSETMISC (overlay, tail); 492 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
495 493 Lisp_Object end = OVERLAY_END (overlay);
496 end = OVERLAY_END (overlay); 494 ptrdiff_t endpos = OVERLAY_POSITION (end);
497 endpos = OVERLAY_POSITION (end);
498 if (endpos < pos) 495 if (endpos < pos)
499 break; 496 break;
500 start = OVERLAY_START (overlay); 497 Lisp_Object start = OVERLAY_START (overlay);
501 startpos = OVERLAY_POSITION (start); 498 ptrdiff_t startpos = OVERLAY_POSITION (start);
502 if (startpos <= pos) 499 if (startpos <= pos)
503 { 500 {
504 if (idx < len) 501 if (idx < len)
@@ -508,16 +505,16 @@ overlays_around (EMACS_INT pos, Lisp_Object *vec, ptrdiff_t len)
508 } 505 }
509 } 506 }
510 507
511 for (tail = current_buffer->overlays_after; tail; tail = tail->next) 508 for (struct Lisp_Overlay *tail = current_buffer->overlays_after;
509 tail; tail = tail->next)
512 { 510 {
513 XSETMISC (overlay, tail); 511 Lisp_Object overlay = make_lisp_ptr (tail, Lisp_Vectorlike);
514 512 Lisp_Object start = OVERLAY_START (overlay);
515 start = OVERLAY_START (overlay); 513 ptrdiff_t startpos = OVERLAY_POSITION (start);
516 startpos = OVERLAY_POSITION (start);
517 if (pos < startpos) 514 if (pos < startpos)
518 break; 515 break;
519 end = OVERLAY_END (overlay); 516 Lisp_Object end = OVERLAY_END (overlay);
520 endpos = OVERLAY_POSITION (end); 517 ptrdiff_t endpos = OVERLAY_POSITION (end);
521 if (pos <= endpos) 518 if (pos <= endpos)
522 { 519 {
523 if (idx < len) 520 if (idx < len)
diff --git a/src/fns.c b/src/fns.c
index 825880643ac..ac5edc2cdbd 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2287,7 +2287,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind,
2287 ht = CALLN (Fmake_hash_table, QCtest, Qeq); 2287 ht = CALLN (Fmake_hash_table, QCtest, Qeq);
2288 switch (XTYPE (o1)) 2288 switch (XTYPE (o1))
2289 { 2289 {
2290 case Lisp_Cons: case Lisp_Misc: case Lisp_Vectorlike: 2290 case Lisp_Cons: case Lisp_Vectorlike:
2291 { 2291 {
2292 struct Lisp_Hash_Table *h = XHASH_TABLE (ht); 2292 struct Lisp_Hash_Table *h = XHASH_TABLE (ht);
2293 EMACS_UINT hash; 2293 EMACS_UINT hash;
@@ -2344,31 +2344,6 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind,
2344 depth++; 2344 depth++;
2345 goto tail_recurse; 2345 goto tail_recurse;
2346 2346
2347 case Lisp_Misc:
2348 if (XMISCTYPE (o1) != XMISCTYPE (o2))
2349 return false;
2350 if (OVERLAYP (o1))
2351 {
2352 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
2353 equal_kind, depth + 1, ht)
2354 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
2355 equal_kind, depth + 1, ht))
2356 return false;
2357 o1 = XOVERLAY (o1)->plist;
2358 o2 = XOVERLAY (o2)->plist;
2359 depth++;
2360 goto tail_recurse;
2361 }
2362 if (MARKERP (o1))
2363 {
2364 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
2365 && (XMARKER (o1)->buffer == 0
2366 || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
2367 }
2368 if (BIGNUMP (o1))
2369 return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0;
2370 break;
2371
2372 case Lisp_Vectorlike: 2347 case Lisp_Vectorlike:
2373 { 2348 {
2374 register int i; 2349 register int i;
@@ -2378,6 +2353,26 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind,
2378 same size. */ 2353 same size. */
2379 if (ASIZE (o2) != size) 2354 if (ASIZE (o2) != size)
2380 return false; 2355 return false;
2356 if (BIGNUMP (o1))
2357 return mpz_cmp (XBIGNUM (o1)->value, XBIGNUM (o2)->value) == 0;
2358 if (OVERLAYP (o1))
2359 {
2360 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
2361 equal_kind, depth + 1, ht)
2362 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
2363 equal_kind, depth + 1, ht))
2364 return false;
2365 o1 = XOVERLAY (o1)->plist;
2366 o2 = XOVERLAY (o2)->plist;
2367 depth++;
2368 goto tail_recurse;
2369 }
2370 if (MARKERP (o1))
2371 {
2372 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
2373 && (XMARKER (o1)->buffer == 0
2374 || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
2375 }
2381 /* Boolvectors are compared much like strings. */ 2376 /* Boolvectors are compared much like strings. */
2382 if (BOOL_VECTOR_P (o1)) 2377 if (BOOL_VECTOR_P (o1))
2383 { 2378 {
@@ -4477,13 +4472,6 @@ sxhash (Lisp_Object obj, int depth)
4477 hash = XUFIXNUM (obj); 4472 hash = XUFIXNUM (obj);
4478 break; 4473 break;
4479 4474
4480 case Lisp_Misc:
4481 if (XMISCTYPE (obj) == Lisp_Misc_Bignum)
4482 {
4483 hash = sxhash_bignum (XBIGNUM (obj));
4484 break;
4485 }
4486 FALLTHROUGH;
4487 case Lisp_Symbol: 4475 case Lisp_Symbol:
4488 hash = XHASH (obj); 4476 hash = XHASH (obj);
4489 break; 4477 break;
@@ -4494,7 +4482,9 @@ sxhash (Lisp_Object obj, int depth)
4494 4482
4495 /* This can be everything from a vector to an overlay. */ 4483 /* This can be everything from a vector to an overlay. */
4496 case Lisp_Vectorlike: 4484 case Lisp_Vectorlike:
4497 if (VECTORP (obj) || RECORDP (obj)) 4485 if (BIGNUMP (obj))
4486 hash = sxhash_bignum (XBIGNUM (obj));
4487 else if (VECTORP (obj) || RECORDP (obj))
4498 /* According to the CL HyperSpec, two arrays are equal only if 4488 /* According to the CL HyperSpec, two arrays are equal only if
4499 they are `eq', except for strings and bit-vectors. In 4489 they are `eq', except for strings and bit-vectors. In
4500 Emacs, this works differently. We have to compare element 4490 Emacs, this works differently. We have to compare element
diff --git a/src/lisp.h b/src/lisp.h
index 6ca34168928..c080cc6b146 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -365,8 +365,6 @@ typedef EMACS_INT Lisp_Word;
365#define lisp_h_EQ(x, y) (XLI (x) == XLI (y)) 365#define lisp_h_EQ(x, y) (XLI (x) == XLI (y))
366#define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float) 366#define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float)
367#define lisp_h_FIXNUMP(x) ((XTYPE (x) & (Lisp_Int0 | ~Lisp_Int1)) == Lisp_Int0) 367#define lisp_h_FIXNUMP(x) ((XTYPE (x) & (Lisp_Int0 | ~Lisp_Int1)) == Lisp_Int0)
368#define lisp_h_MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
369#define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc)
370#define lisp_h_NILP(x) EQ (x, Qnil) 368#define lisp_h_NILP(x) EQ (x, Qnil)
371#define lisp_h_SET_SYMBOL_VAL(sym, v) \ 369#define lisp_h_SET_SYMBOL_VAL(sym, v) \
372 (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \ 370 (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \
@@ -430,8 +428,6 @@ typedef EMACS_INT Lisp_Word;
430# define EQ(x, y) lisp_h_EQ (x, y) 428# define EQ(x, y) lisp_h_EQ (x, y)
431# define FLOATP(x) lisp_h_FLOATP (x) 429# define FLOATP(x) lisp_h_FLOATP (x)
432# define FIXNUMP(x) lisp_h_FIXNUMP (x) 430# define FIXNUMP(x) lisp_h_FIXNUMP (x)
433# define MARKERP(x) lisp_h_MARKERP (x)
434# define MISCP(x) lisp_h_MISCP (x)
435# define NILP(x) lisp_h_NILP (x) 431# define NILP(x) lisp_h_NILP (x)
436# define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v) 432# define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v)
437# define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym) 433# define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym)
@@ -482,11 +478,9 @@ enum Lisp_Type
482 /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ 478 /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */
483 Lisp_Symbol = 0, 479 Lisp_Symbol = 0,
484 480
485 /* Miscellaneous. XMISC (object) points to a union Lisp_Misc, 481 /* Type 1 is currently unused. */
486 whose first member indicates the subtype. */
487 Lisp_Misc = 1,
488 482
489 /* Integer. XFIXNUM (obj) is the integer value. */ 483 /* Fixnum. XFIXNUM (obj) is the integer value. */
490 Lisp_Int0 = 2, 484 Lisp_Int0 = 2,
491 Lisp_Int1 = USE_LSB_TAG ? 6 : 3, 485 Lisp_Int1 = USE_LSB_TAG ? 6 : 3,
492 486
@@ -506,26 +500,6 @@ enum Lisp_Type
506 Lisp_Float = 7 500 Lisp_Float = 7
507 }; 501 };
508 502
509/* This is the set of data types that share a common structure.
510 The first member of the structure is a type code from this set.
511 The enum values are arbitrary, but we'll use large numbers to make it
512 more likely that we'll spot the error if a random word in memory is
513 mistakenly interpreted as a Lisp_Misc. */
514enum Lisp_Misc_Type
515 {
516 Lisp_Misc_Free = 0x5eab,
517 Lisp_Misc_Marker,
518 Lisp_Misc_Overlay,
519 Lisp_Misc_Finalizer,
520 Lisp_Misc_Ptr,
521#ifdef HAVE_MODULES
522 Lisp_Misc_User_Ptr,
523#endif
524 Lisp_Misc_Bignum,
525 /* This is not a type code. It is for range checking. */
526 Lisp_Misc_Limit
527 };
528
529/* These are the types of forwarding objects used in the value slot 503/* These are the types of forwarding objects used in the value slot
530 of symbols for special built-in variables whose value is stored in 504 of symbols for special built-in variables whose value is stored in
531 C variables. */ 505 C variables. */
@@ -539,14 +513,12 @@ enum Lisp_Fwd_Type
539 }; 513 };
540 514
541/* If you want to define a new Lisp data type, here are some 515/* If you want to define a new Lisp data type, here are some
542 instructions. See the thread at 516 instructions.
543 https://lists.gnu.org/r/emacs-devel/2012-10/msg00561.html
544 for more info.
545 517
546 First, there are already a couple of Lisp types that can be used if 518 First, there are already a couple of Lisp types that can be used if
547 your new type does not need to be exposed to Lisp programs nor 519 your new type does not need to be exposed to Lisp programs nor
548 displayed to users. These are Lisp_Misc_Ptr, a Lisp_Misc 520 displayed to users. These are Lisp_Misc_Ptr and PVEC_OTHER,
549 subtype; and PVEC_OTHER, a kind of vectorlike object. The former 521 which are both vectorlike objects. The former
550 is suitable for stashing a pointer in a Lisp object; the pointer 522 is suitable for stashing a pointer in a Lisp object; the pointer
551 might be to some low-level C object that contains auxiliary 523 might be to some low-level C object that contains auxiliary
552 information. The latter is useful for vector-like Lisp objects 524 information. The latter is useful for vector-like Lisp objects
@@ -557,30 +529,14 @@ enum Lisp_Fwd_Type
557 These two types don't look pretty when printed, so they are 529 These two types don't look pretty when printed, so they are
558 unsuitable for Lisp objects that can be exposed to users. 530 unsuitable for Lisp objects that can be exposed to users.
559 531
560 To define a new data type, add one more Lisp_Misc subtype or one 532 To define a new data type, add a pseudovector subtype by extending
561 more pseudovector subtype. Pseudovectors are more suitable for 533 the pvec_type enumeration. A pseudovector provides one or more
562 objects with several slots that need to support fast random access, 534 slots for Lisp objects, followed by struct members that are
563 while Lisp_Misc types are for everything else. A pseudovector object 535 accessible only from C.
564 provides one or more slots for Lisp objects, followed by struct
565 members that are accessible only from C. A Lisp_Misc object is a
566 wrapper for a C struct that can contain anything you like.
567 536
568 There is no way to explicitly free a Lisp Object; only the garbage 537 There is no way to explicitly free a Lisp Object; only the garbage
569 collector frees them. 538 collector frees them.
570 539
571 To add a new pseudovector type, extend the pvec_type enumeration;
572 to add a new Lisp_Misc, extend the Lisp_Misc_Type enumeration.
573
574 For a Lisp_Misc, you will also need to add your entry to union
575 Lisp_Misc, but make sure the first word has the same structure as
576 the others, starting with a 16-bit member of the Lisp_Misc_Type
577 enumeration and a 1-bit GC markbit. Also make sure the overall
578 size of the union is not increased by your addition. The latter
579 requirement is to keep Lisp_Misc objects small enough, so they
580 are handled faster: since all Lisp_Misc types use the same space,
581 enlarging any of them will affect all the rest. If you really
582 need a larger object, it is best to use Lisp_Vectorlike instead.
583
584 For a new pseudovector, it's highly desirable to limit the size 540 For a new pseudovector, it's highly desirable to limit the size
585 of your data type by VBLOCK_BYTES_MAX bytes (defined in alloc.c). 541 of your data type by VBLOCK_BYTES_MAX bytes (defined in alloc.c).
586 Otherwise you will need to change sweep_vectors (also in alloc.c). 542 Otherwise you will need to change sweep_vectors (also in alloc.c).
@@ -973,6 +929,14 @@ enum pvec_type
973{ 929{
974 PVEC_NORMAL_VECTOR, 930 PVEC_NORMAL_VECTOR,
975 PVEC_FREE, 931 PVEC_FREE,
932 PVEC_BIGNUM,
933 PVEC_MARKER,
934 PVEC_OVERLAY,
935 PVEC_FINALIZER,
936 PVEC_MISC_PTR,
937#ifdef HAVE_MODULES
938 PVEC_USER_PTR,
939#endif
976 PVEC_PROCESS, 940 PVEC_PROCESS,
977 PVEC_FRAME, 941 PVEC_FRAME,
978 PVEC_WINDOW, 942 PVEC_WINDOW,
@@ -1173,7 +1137,6 @@ INLINE bool
1173#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) 1137#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
1174#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b)) 1138#define XSETSYMBOL(a, b) ((a) = make_lisp_symbol (b))
1175#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) 1139#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
1176#define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc))
1177 1140
1178/* Pseudovector types. */ 1141/* Pseudovector types. */
1179 1142
@@ -2273,46 +2236,10 @@ SXHASH_REDUCE (EMACS_UINT x)
2273 return (x ^ x >> (EMACS_INT_WIDTH - FIXNUM_BITS)) & INTMASK; 2236 return (x ^ x >> (EMACS_INT_WIDTH - FIXNUM_BITS)) & INTMASK;
2274} 2237}
2275 2238
2276/* These structures are used for various misc types. */
2277
2278struct Lisp_Misc_Any /* Supertype of all Misc types. */
2279{
2280 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_??? */
2281 bool_bf gcmarkbit : 1;
2282 unsigned spacer : 15;
2283};
2284
2285INLINE bool
2286(MISCP) (Lisp_Object x)
2287{
2288 return lisp_h_MISCP (x);
2289}
2290
2291INLINE struct Lisp_Misc_Any *
2292XMISCANY (Lisp_Object a)
2293{
2294 eassert (MISCP (a));
2295 return XUNTAG (a, Lisp_Misc, struct Lisp_Misc_Any);
2296}
2297
2298INLINE enum Lisp_Misc_Type
2299XMISCTYPE (Lisp_Object a)
2300{
2301 return XMISCANY (a)->type;
2302}
2303
2304struct Lisp_Marker 2239struct Lisp_Marker
2305{ 2240{
2306 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Marker */ 2241 union vectorlike_header header;
2307 bool_bf gcmarkbit : 1; 2242
2308 unsigned spacer : 13;
2309 /* This flag is temporarily used in the functions
2310 decode/encode_coding_object to record that the marker position
2311 must be adjusted after the conversion. */
2312 bool_bf need_adjustment : 1;
2313 /* True means normal insertion at the marker's position
2314 leaves the marker after the inserted text. */
2315 bool_bf insertion_type : 1;
2316 /* This is the buffer that the marker points into, or 0 if it points nowhere. 2243 /* This is the buffer that the marker points into, or 0 if it points nowhere.
2317 Note: a chain of markers can contain markers pointing into different 2244 Note: a chain of markers can contain markers pointing into different
2318 buffers (the chain is per buffer_text rather than per buffer, so it's 2245 buffers (the chain is per buffer_text rather than per buffer, so it's
@@ -2325,6 +2252,14 @@ struct Lisp_Marker
2325 */ 2252 */
2326 struct buffer *buffer; 2253 struct buffer *buffer;
2327 2254
2255 /* This flag is temporarily used in the functions
2256 decode/encode_coding_object to record that the marker position
2257 must be adjusted after the conversion. */
2258 bool_bf need_adjustment : 1;
2259 /* True means normal insertion at the marker's position
2260 leaves the marker after the inserted text. */
2261 bool_bf insertion_type : 1;
2262
2328 /* The remaining fields are meaningless in a marker that 2263 /* The remaining fields are meaningless in a marker that
2329 does not point anywhere. */ 2264 does not point anywhere. */
2330 2265
@@ -2357,20 +2292,16 @@ struct Lisp_Overlay
2357 I.e. 9words plus 2 bits, 3words of which are for external linked lists. 2292 I.e. 9words plus 2 bits, 3words of which are for external linked lists.
2358*/ 2293*/
2359 { 2294 {
2360 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Overlay */ 2295 union vectorlike_header header;
2361 bool_bf gcmarkbit : 1;
2362 unsigned spacer : 15;
2363 struct Lisp_Overlay *next;
2364 Lisp_Object start; 2296 Lisp_Object start;
2365 Lisp_Object end; 2297 Lisp_Object end;
2366 Lisp_Object plist; 2298 Lisp_Object plist;
2299 struct Lisp_Overlay *next;
2367 }; 2300 };
2368 2301
2369struct Lisp_Misc_Ptr 2302struct Lisp_Misc_Ptr
2370 { 2303 {
2371 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Ptr */ 2304 union vectorlike_header header;
2372 bool_bf gcmarkbit : 1;
2373 unsigned spacer : 15;
2374 void *pointer; 2305 void *pointer;
2375 }; 2306 };
2376 2307
@@ -2388,7 +2319,7 @@ extern Lisp_Object make_misc_ptr (void *);
2388 C code, it should not be given a mint_ptr generated from Lisp code 2319 C code, it should not be given a mint_ptr generated from Lisp code
2389 as that would allow Lisp code to coin pointers from integers and 2320 as that would allow Lisp code to coin pointers from integers and
2390 could lead to crashes. To package a C pointer into a Lisp-visible 2321 could lead to crashes. To package a C pointer into a Lisp-visible
2391 object you can put the pointer into a Lisp_Misc object instead; see 2322 object you can put the pointer into a pseudovector instead; see
2392 Lisp_User_Ptr for an example. */ 2323 Lisp_User_Ptr for an example. */
2393 2324
2394INLINE Lisp_Object 2325INLINE Lisp_Object
@@ -2401,7 +2332,7 @@ make_mint_ptr (void *a)
2401INLINE bool 2332INLINE bool
2402mint_ptrp (Lisp_Object x) 2333mint_ptrp (Lisp_Object x)
2403{ 2334{
2404 return FIXNUMP (x) || (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Ptr); 2335 return FIXNUMP (x) || PSEUDOVECTORP (x, PVEC_MISC_PTR);
2405} 2336}
2406 2337
2407INLINE void * 2338INLINE void *
@@ -2410,16 +2341,13 @@ xmint_pointer (Lisp_Object a)
2410 eassert (mint_ptrp (a)); 2341 eassert (mint_ptrp (a));
2411 if (FIXNUMP (a)) 2342 if (FIXNUMP (a))
2412 return XFIXNUMPTR (a); 2343 return XFIXNUMPTR (a);
2413 return XUNTAG (a, Lisp_Misc, struct Lisp_Misc_Ptr)->pointer; 2344 return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Misc_Ptr)->pointer;
2414} 2345}
2415 2346
2416#ifdef HAVE_MODULES 2347#ifdef HAVE_MODULES
2417struct Lisp_User_Ptr 2348struct Lisp_User_Ptr
2418{ 2349{
2419 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_User_Ptr */ 2350 union vectorlike_header header;
2420 bool_bf gcmarkbit : 1;
2421 unsigned spacer : 15;
2422
2423 void (*finalizer) (void *); 2351 void (*finalizer) (void *);
2424 void *p; 2352 void *p;
2425}; 2353};
@@ -2428,123 +2356,89 @@ struct Lisp_User_Ptr
2428/* A finalizer sentinel. */ 2356/* A finalizer sentinel. */
2429struct Lisp_Finalizer 2357struct Lisp_Finalizer
2430 { 2358 {
2431 struct Lisp_Misc_Any base; 2359 union vectorlike_header header;
2432
2433 /* Circular list of all active weak references. */
2434 struct Lisp_Finalizer *prev;
2435 struct Lisp_Finalizer *next;
2436 2360
2437 /* Call FUNCTION when the finalizer becomes unreachable, even if 2361 /* Call FUNCTION when the finalizer becomes unreachable, even if
2438 FUNCTION contains a reference to the finalizer; i.e., call 2362 FUNCTION contains a reference to the finalizer; i.e., call
2439 FUNCTION when it is reachable _only_ through finalizers. */ 2363 FUNCTION when it is reachable _only_ through finalizers. */
2440 Lisp_Object function; 2364 Lisp_Object function;
2365
2366 /* Circular list of all active weak references. */
2367 struct Lisp_Finalizer *prev;
2368 struct Lisp_Finalizer *next;
2441 }; 2369 };
2442 2370
2443INLINE bool 2371INLINE bool
2444FINALIZERP (Lisp_Object x) 2372FINALIZERP (Lisp_Object x)
2445{ 2373{
2446 return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Finalizer; 2374 return PSEUDOVECTORP (x, PVEC_FINALIZER);
2447} 2375}
2448 2376
2449INLINE struct Lisp_Finalizer * 2377INLINE struct Lisp_Finalizer *
2450XFINALIZER (Lisp_Object a) 2378XFINALIZER (Lisp_Object a)
2451{ 2379{
2452 eassert (FINALIZERP (a)); 2380 eassert (FINALIZERP (a));
2453 return XUNTAG (a, Lisp_Misc, struct Lisp_Finalizer); 2381 return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Finalizer);
2454}
2455
2456/* A miscellaneous object, when it's on the free list. */
2457struct Lisp_Free
2458 {
2459 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Free */
2460 bool_bf gcmarkbit : 1;
2461 unsigned spacer : 15;
2462 union Lisp_Misc *chain;
2463 };
2464
2465struct Lisp_Bignum
2466 {
2467 ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Bignum */
2468 bool_bf gcmarkbit : 1;
2469 unsigned spacer : 15;
2470 mpz_t value;
2471 };
2472
2473/* To get the type field of a union Lisp_Misc, use XMISCTYPE.
2474 It uses one of these struct subtypes to get the type field. */
2475
2476union Lisp_Misc
2477 {
2478 struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */
2479 struct Lisp_Free u_free;
2480 struct Lisp_Marker u_marker;
2481 struct Lisp_Overlay u_overlay;
2482 struct Lisp_Finalizer u_finalizer;
2483 struct Lisp_Misc_Ptr u_misc_ptr;
2484#ifdef HAVE_MODULES
2485 struct Lisp_User_Ptr u_user_ptr;
2486#endif
2487 struct Lisp_Bignum u_bignum;
2488 };
2489
2490INLINE union Lisp_Misc *
2491XMISC (Lisp_Object a)
2492{
2493 return XUNTAG (a, Lisp_Misc, union Lisp_Misc);
2494} 2382}
2495 2383
2496INLINE bool 2384INLINE bool
2497(MARKERP) (Lisp_Object x) 2385MARKERP (Lisp_Object x)
2498{ 2386{
2499 return lisp_h_MARKERP (x); 2387 return PSEUDOVECTORP (x, PVEC_MARKER);
2500} 2388}
2501 2389
2502INLINE struct Lisp_Marker * 2390INLINE struct Lisp_Marker *
2503XMARKER (Lisp_Object a) 2391XMARKER (Lisp_Object a)
2504{ 2392{
2505 eassert (MARKERP (a)); 2393 eassert (MARKERP (a));
2506 return XUNTAG (a, Lisp_Misc, struct Lisp_Marker); 2394 return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Marker);
2507} 2395}
2508 2396
2509INLINE bool 2397INLINE bool
2510OVERLAYP (Lisp_Object x) 2398OVERLAYP (Lisp_Object x)
2511{ 2399{
2512 return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay; 2400 return PSEUDOVECTORP (x, PVEC_OVERLAY);
2513} 2401}
2514 2402
2515INLINE struct Lisp_Overlay * 2403INLINE struct Lisp_Overlay *
2516XOVERLAY (Lisp_Object a) 2404XOVERLAY (Lisp_Object a)
2517{ 2405{
2518 eassert (OVERLAYP (a)); 2406 eassert (OVERLAYP (a));
2519 return XUNTAG (a, Lisp_Misc, struct Lisp_Overlay); 2407 return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Overlay);
2520} 2408}
2521 2409
2522#ifdef HAVE_MODULES 2410#ifdef HAVE_MODULES
2523INLINE bool 2411INLINE bool
2524USER_PTRP (Lisp_Object x) 2412USER_PTRP (Lisp_Object x)
2525{ 2413{
2526 return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_User_Ptr; 2414 return PSEUDOVECTORP (x, PVEC_USER_PTR);
2527} 2415}
2528 2416
2529INLINE struct Lisp_User_Ptr * 2417INLINE struct Lisp_User_Ptr *
2530XUSER_PTR (Lisp_Object a) 2418XUSER_PTR (Lisp_Object a)
2531{ 2419{
2532 eassert (USER_PTRP (a)); 2420 eassert (USER_PTRP (a));
2533 return XUNTAG (a, Lisp_Misc, struct Lisp_User_Ptr); 2421 return XUNTAG (a, Lisp_Vectorlike, struct Lisp_User_Ptr);
2534} 2422}
2535#endif 2423#endif
2536 2424
2425struct Lisp_Bignum
2426{
2427 union vectorlike_header header;
2428 mpz_t value;
2429};
2430
2537INLINE bool 2431INLINE bool
2538BIGNUMP (Lisp_Object x) 2432BIGNUMP (Lisp_Object x)
2539{ 2433{
2540 return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Bignum; 2434 return PSEUDOVECTORP (x, PVEC_BIGNUM);
2541} 2435}
2542 2436
2543INLINE struct Lisp_Bignum * 2437INLINE struct Lisp_Bignum *
2544XBIGNUM (Lisp_Object a) 2438XBIGNUM (Lisp_Object a)
2545{ 2439{
2546 eassert (BIGNUMP (a)); 2440 eassert (BIGNUMP (a));
2547 return XUNTAG (a, Lisp_Misc, struct Lisp_Bignum); 2441 return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Bignum);
2548} 2442}
2549 2443
2550INLINE bool 2444INLINE bool
diff --git a/src/print.c b/src/print.c
index 3819c505b12..824f8d75779 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1367,6 +1367,76 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
1367{ 1367{
1368 switch (PSEUDOVECTOR_TYPE (XVECTOR (obj))) 1368 switch (PSEUDOVECTOR_TYPE (XVECTOR (obj)))
1369 { 1369 {
1370 case PVEC_BIGNUM:
1371 {
1372 struct Lisp_Bignum *b = XBIGNUM (obj);
1373 char *str = mpz_get_str (NULL, 10, b->value);
1374 record_unwind_protect_ptr (xfree, str);
1375 print_c_string (str, printcharfun);
1376 }
1377 break;
1378
1379 case PVEC_MARKER:
1380 print_c_string ("#<marker ", printcharfun);
1381 /* Do you think this is necessary? */
1382 if (XMARKER (obj)->insertion_type != 0)
1383 print_c_string ("(moves after insertion) ", printcharfun);
1384 if (! XMARKER (obj)->buffer)
1385 print_c_string ("in no buffer", printcharfun);
1386 else
1387 {
1388 int len = sprintf (buf, "at %"pD"d in ", marker_position (obj));
1389 strout (buf, len, len, printcharfun);
1390 print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun);
1391 }
1392 printchar ('>', printcharfun);
1393 break;
1394
1395 case PVEC_OVERLAY:
1396 print_c_string ("#<overlay ", printcharfun);
1397 if (! XMARKER (OVERLAY_START (obj))->buffer)
1398 print_c_string ("in no buffer", printcharfun);
1399 else
1400 {
1401 int len = sprintf (buf, "from %"pD"d to %"pD"d in ",
1402 marker_position (OVERLAY_START (obj)),
1403 marker_position (OVERLAY_END (obj)));
1404 strout (buf, len, len, printcharfun);
1405 print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name),
1406 printcharfun);
1407 }
1408 printchar ('>', printcharfun);
1409 break;
1410
1411#ifdef HAVE_MODULES
1412 case PVEC_USER_PTR:
1413 {
1414 print_c_string ("#<user-ptr ", printcharfun);
1415 int i = sprintf (buf, "ptr=%p finalizer=%p",
1416 XUSER_PTR (obj)->p,
1417 XUSER_PTR (obj)->finalizer);
1418 strout (buf, i, i, printcharfun);
1419 printchar ('>', printcharfun);
1420 }
1421 break;
1422#endif
1423
1424 case PVEC_FINALIZER:
1425 print_c_string ("#<finalizer", printcharfun);
1426 if (NILP (XFINALIZER (obj)->function))
1427 print_c_string (" used", printcharfun);
1428 printchar ('>', printcharfun);
1429 break;
1430
1431 case PVEC_MISC_PTR:
1432 {
1433 /* This shouldn't happen in normal usage, but let's
1434 print it anyway for the benefit of the debugger. */
1435 int i = sprintf (buf, "#<ptr %p>", xmint_pointer (obj));
1436 strout (buf, i, i, printcharfun);
1437 }
1438 break;
1439
1370 case PVEC_PROCESS: 1440 case PVEC_PROCESS:
1371 if (escapeflag) 1441 if (escapeflag)
1372 { 1442 {
@@ -2096,103 +2166,16 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
2096 break; 2166 break;
2097 2167
2098 case Lisp_Vectorlike: 2168 case Lisp_Vectorlike:
2099 if (! print_vectorlike (obj, printcharfun, escapeflag, buf)) 2169 if (print_vectorlike (obj, printcharfun, escapeflag, buf))
2100 goto badtype; 2170 break;
2101 break; 2171 FALLTHROUGH;
2102
2103 case Lisp_Misc:
2104 switch (XMISCTYPE (obj))
2105 {
2106 case Lisp_Misc_Marker:
2107 print_c_string ("#<marker ", printcharfun);
2108 /* Do you think this is necessary? */
2109 if (XMARKER (obj)->insertion_type != 0)
2110 print_c_string ("(moves after insertion) ", printcharfun);
2111 if (! XMARKER (obj)->buffer)
2112 print_c_string ("in no buffer", printcharfun);
2113 else
2114 {
2115 int len = sprintf (buf, "at %"pD"d in ", marker_position (obj));
2116 strout (buf, len, len, printcharfun);
2117 print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun);
2118 }
2119 printchar ('>', printcharfun);
2120 break;
2121
2122 case Lisp_Misc_Overlay:
2123 print_c_string ("#<overlay ", printcharfun);
2124 if (! XMARKER (OVERLAY_START (obj))->buffer)
2125 print_c_string ("in no buffer", printcharfun);
2126 else
2127 {
2128 int len = sprintf (buf, "from %"pD"d to %"pD"d in ",
2129 marker_position (OVERLAY_START (obj)),
2130 marker_position (OVERLAY_END (obj)));
2131 strout (buf, len, len, printcharfun);
2132 print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name),
2133 printcharfun);
2134 }
2135 printchar ('>', printcharfun);
2136 break;
2137
2138#ifdef HAVE_MODULES
2139 case Lisp_Misc_User_Ptr:
2140 {
2141 print_c_string ("#<user-ptr ", printcharfun);
2142 int i = sprintf (buf, "ptr=%p finalizer=%p",
2143 XUSER_PTR (obj)->p,
2144 XUSER_PTR (obj)->finalizer);
2145 strout (buf, i, i, printcharfun);
2146 printchar ('>', printcharfun);
2147 break;
2148 }
2149#endif
2150
2151 case Lisp_Misc_Finalizer:
2152 print_c_string ("#<finalizer", printcharfun);
2153 if (NILP (XFINALIZER (obj)->function))
2154 print_c_string (" used", printcharfun);
2155 printchar ('>', printcharfun);
2156 break;
2157
2158 /* Remaining cases shouldn't happen in normal usage, but let's
2159 print them anyway for the benefit of the debugger. */
2160
2161 case Lisp_Misc_Free:
2162 print_c_string ("#<misc free cell>", printcharfun);
2163 break;
2164
2165 case Lisp_Misc_Ptr:
2166 {
2167 int i = sprintf (buf, "#<ptr %p>", xmint_pointer (obj));
2168 strout (buf, i, i, printcharfun);
2169 }
2170 break;
2171
2172 case Lisp_Misc_Bignum:
2173 {
2174 struct Lisp_Bignum *b = XBIGNUM (obj);
2175 char *str = mpz_get_str (NULL, 10, b->value);
2176 record_unwind_protect_ptr (xfree, str);
2177 print_c_string (str, printcharfun);
2178 }
2179 break;
2180
2181 default:
2182 goto badtype;
2183 }
2184 break;
2185
2186 default: 2172 default:
2187 badtype:
2188 { 2173 {
2189 int len; 2174 int len;
2190 /* We're in trouble if this happens! 2175 /* We're in trouble if this happens!
2191 Probably should just emacs_abort (). */ 2176 Probably should just emacs_abort (). */
2192 print_c_string ("#<EMACS BUG: INVALID DATATYPE ", printcharfun); 2177 print_c_string ("#<EMACS BUG: INVALID DATATYPE ", printcharfun);
2193 if (MISCP (obj)) 2178 if (VECTORLIKEP (obj))
2194 len = sprintf (buf, "(MISC 0x%04x)", (unsigned) XMISCTYPE (obj));
2195 else if (VECTORLIKEP (obj))
2196 len = sprintf (buf, "(PVEC 0x%08zx)", (size_t) ASIZE (obj)); 2179 len = sprintf (buf, "(PVEC 0x%08zx)", (size_t) ASIZE (obj));
2197 else 2180 else
2198 len = sprintf (buf, "(0x%02x)", (unsigned) XTYPE (obj)); 2181 len = sprintf (buf, "(0x%02x)", (unsigned) XTYPE (obj));
diff --git a/src/undo.c b/src/undo.c
index e80ec58ab09..1975e387e3f 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -126,15 +126,11 @@ record_insert (ptrdiff_t beg, ptrdiff_t length)
126static void 126static void
127record_marker_adjustments (ptrdiff_t from, ptrdiff_t to) 127record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
128{ 128{
129 Lisp_Object marker; 129 prepare_record ();
130 register struct Lisp_Marker *m;
131 register ptrdiff_t charpos, adjustment;
132
133 prepare_record();
134 130
135 for (m = BUF_MARKERS (current_buffer); m; m = m->next) 131 for (struct Lisp_Marker *m = BUF_MARKERS (current_buffer); m; m = m->next)
136 { 132 {
137 charpos = m->charpos; 133 ptrdiff_t charpos = m->charpos;
138 eassert (charpos <= Z); 134 eassert (charpos <= Z);
139 135
140 if (from <= charpos && charpos <= to) 136 if (from <= charpos && charpos <= to)
@@ -146,11 +142,11 @@ record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
146 insertion_type t markers will automatically move forward 142 insertion_type t markers will automatically move forward
147 upon re-inserting the deleted text, so we have to arrange 143 upon re-inserting the deleted text, so we have to arrange
148 for them to move backward to the correct position. */ 144 for them to move backward to the correct position. */
149 adjustment = (m->insertion_type ? to : from) - charpos; 145 ptrdiff_t adjustment = (m->insertion_type ? to : from) - charpos;
150 146
151 if (adjustment) 147 if (adjustment)
152 { 148 {
153 XSETMISC (marker, m); 149 Lisp_Object marker = make_lisp_ptr (m, Lisp_Vectorlike);
154 bset_undo_list 150 bset_undo_list
155 (current_buffer, 151 (current_buffer,
156 Fcons (Fcons (marker, make_fixnum (adjustment)), 152 Fcons (Fcons (marker, make_fixnum (adjustment)),
diff --git a/src/xdisp.c b/src/xdisp.c
index 76fde99f323..0835ccafd4d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -5819,11 +5819,7 @@ compare_overlay_entries (const void *e1, const void *e2)
5819static void 5819static void
5820load_overlay_strings (struct it *it, ptrdiff_t charpos) 5820load_overlay_strings (struct it *it, ptrdiff_t charpos)
5821{ 5821{
5822 Lisp_Object overlay, window, str, invisible; 5822 ptrdiff_t n = 0;
5823 struct Lisp_Overlay *ov;
5824 ptrdiff_t start, end;
5825 ptrdiff_t n = 0, i, j;
5826 int invis;
5827 struct overlay_entry entriesbuf[20]; 5823 struct overlay_entry entriesbuf[20];
5828 ptrdiff_t size = ARRAYELTS (entriesbuf); 5824 ptrdiff_t size = ARRAYELTS (entriesbuf);
5829 struct overlay_entry *entries = entriesbuf; 5825 struct overlay_entry *entries = entriesbuf;
@@ -5859,12 +5855,13 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
5859 while (false) 5855 while (false)
5860 5856
5861 /* Process overlay before the overlay center. */ 5857 /* Process overlay before the overlay center. */
5862 for (ov = current_buffer->overlays_before; ov; ov = ov->next) 5858 for (struct Lisp_Overlay *ov = current_buffer->overlays_before;
5859 ov; ov = ov->next)
5863 { 5860 {
5864 XSETMISC (overlay, ov); 5861 Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
5865 eassert (OVERLAYP (overlay)); 5862 eassert (OVERLAYP (overlay));
5866 start = OVERLAY_POSITION (OVERLAY_START (overlay)); 5863 ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
5867 end = OVERLAY_POSITION (OVERLAY_END (overlay)); 5864 ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
5868 5865
5869 if (end < charpos) 5866 if (end < charpos)
5870 break; 5867 break;
@@ -5875,17 +5872,18 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
5875 continue; 5872 continue;
5876 5873
5877 /* Skip this overlay if it doesn't apply to IT->w. */ 5874 /* Skip this overlay if it doesn't apply to IT->w. */
5878 window = Foverlay_get (overlay, Qwindow); 5875 Lisp_Object window = Foverlay_get (overlay, Qwindow);
5879 if (WINDOWP (window) && XWINDOW (window) != it->w) 5876 if (WINDOWP (window) && XWINDOW (window) != it->w)
5880 continue; 5877 continue;
5881 5878
5882 /* If the text ``under'' the overlay is invisible, both before- 5879 /* If the text ``under'' the overlay is invisible, both before-
5883 and after-strings from this overlay are visible; start and 5880 and after-strings from this overlay are visible; start and
5884 end position are indistinguishable. */ 5881 end position are indistinguishable. */
5885 invisible = Foverlay_get (overlay, Qinvisible); 5882 Lisp_Object invisible = Foverlay_get (overlay, Qinvisible);
5886 invis = TEXT_PROP_MEANS_INVISIBLE (invisible); 5883 int invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5887 5884
5888 /* If overlay has a non-empty before-string, record it. */ 5885 /* If overlay has a non-empty before-string, record it. */
5886 Lisp_Object str;
5889 if ((start == charpos || (end == charpos && invis != 0)) 5887 if ((start == charpos || (end == charpos && invis != 0))
5890 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) 5888 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5891 && SCHARS (str)) 5889 && SCHARS (str))
@@ -5899,12 +5897,13 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
5899 } 5897 }
5900 5898
5901 /* Process overlays after the overlay center. */ 5899 /* Process overlays after the overlay center. */
5902 for (ov = current_buffer->overlays_after; ov; ov = ov->next) 5900 for (struct Lisp_Overlay *ov = current_buffer->overlays_after;
5901 ov; ov = ov->next)
5903 { 5902 {
5904 XSETMISC (overlay, ov); 5903 Lisp_Object overlay = make_lisp_ptr (ov, Lisp_Vectorlike);
5905 eassert (OVERLAYP (overlay)); 5904 eassert (OVERLAYP (overlay));
5906 start = OVERLAY_POSITION (OVERLAY_START (overlay)); 5905 ptrdiff_t start = OVERLAY_POSITION (OVERLAY_START (overlay));
5907 end = OVERLAY_POSITION (OVERLAY_END (overlay)); 5906 ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
5908 5907
5909 if (start > charpos) 5908 if (start > charpos)
5910 break; 5909 break;
@@ -5915,16 +5914,17 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
5915 continue; 5914 continue;
5916 5915
5917 /* Skip this overlay if it doesn't apply to IT->w. */ 5916 /* Skip this overlay if it doesn't apply to IT->w. */
5918 window = Foverlay_get (overlay, Qwindow); 5917 Lisp_Object window = Foverlay_get (overlay, Qwindow);
5919 if (WINDOWP (window) && XWINDOW (window) != it->w) 5918 if (WINDOWP (window) && XWINDOW (window) != it->w)
5920 continue; 5919 continue;
5921 5920
5922 /* If the text ``under'' the overlay is invisible, it has a zero 5921 /* If the text ``under'' the overlay is invisible, it has a zero
5923 dimension, and both before- and after-strings apply. */ 5922 dimension, and both before- and after-strings apply. */
5924 invisible = Foverlay_get (overlay, Qinvisible); 5923 Lisp_Object invisible = Foverlay_get (overlay, Qinvisible);
5925 invis = TEXT_PROP_MEANS_INVISIBLE (invisible); 5924 int invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5926 5925
5927 /* If overlay has a non-empty before-string, record it. */ 5926 /* If overlay has a non-empty before-string, record it. */
5927 Lisp_Object str;
5928 if ((start == charpos || (end == charpos && invis != 0)) 5928 if ((start == charpos || (end == charpos && invis != 0))
5929 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) 5929 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5930 && SCHARS (str)) 5930 && SCHARS (str))
@@ -5950,12 +5950,11 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
5950 /* IT->current.overlay_string_index is the number of overlay strings 5950 /* IT->current.overlay_string_index is the number of overlay strings
5951 that have already been consumed by IT. Copy some of the 5951 that have already been consumed by IT. Copy some of the
5952 remaining overlay strings to IT->overlay_strings. */ 5952 remaining overlay strings to IT->overlay_strings. */
5953 i = 0; 5953 ptrdiff_t j = it->current.overlay_string_index;
5954 j = it->current.overlay_string_index; 5954 for (ptrdiff_t i = 0; i < OVERLAY_STRING_CHUNK_SIZE && j < n; i++, j++)
5955 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5956 { 5955 {
5957 it->overlay_strings[i] = entries[j].string; 5956 it->overlay_strings[i] = entries[j].string;
5958 it->string_overlays[i++] = entries[j++].overlay; 5957 it->string_overlays[i] = entries[j].overlay;
5959 } 5958 }
5960 5959
5961 CHECK_IT (it); 5960 CHECK_IT (it);