diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 393 |
1 files changed, 82 insertions, 311 deletions
diff --git a/src/alloc.c b/src/alloc.c index c3e02c20f85..fea0cec383b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -247,8 +247,8 @@ bool gc_in_progress; | |||
| 247 | 247 | ||
| 248 | /* Number of live and free conses etc. */ | 248 | /* Number of live and free conses etc. */ |
| 249 | 249 | ||
| 250 | static EMACS_INT total_conses, total_markers, total_symbols, total_buffers; | 250 | static EMACS_INT total_conses, total_symbols, total_buffers; |
| 251 | static EMACS_INT total_free_conses, total_free_markers, total_free_symbols; | 251 | static EMACS_INT total_free_conses, total_free_symbols; |
| 252 | static EMACS_INT total_free_floats, total_floats; | 252 | static 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 | ||
| 359 | static void unchain_finalizer (struct Lisp_Finalizer *); | ||
| 359 | static void mark_terminals (void); | 360 | static void mark_terminals (void); |
| 360 | static void gc_sweep (void); | 361 | static void gc_sweep (void); |
| 361 | static Lisp_Object make_pure_vector (ptrdiff_t); | 362 | static Lisp_Object make_pure_vector (ptrdiff_t); |
| @@ -3197,7 +3198,12 @@ static void | |||
| 3197 | cleanup_vector (struct Lisp_Vector *vector) | 3198 | cleanup_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 | |||
| 3660 | union 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 | |||
| 3673 | struct 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 | |||
| 3680 | static struct marker_block *marker_block; | ||
| 3681 | static int marker_block_index = MARKER_BLOCK_SIZE; | ||
| 3682 | |||
| 3683 | static union Lisp_Misc *misc_free_list; | ||
| 3684 | |||
| 3685 | /* Return a newly allocated Lisp_Misc object of specified TYPE. */ | ||
| 3686 | |||
| 3687 | static Lisp_Object | ||
| 3688 | allocate_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 | |||
| 3723 | Lisp_Object | 3672 | Lisp_Object |
| 3724 | make_misc_ptr (void *a) | 3673 | make_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 | ||
| 3733 | Lisp_Object | 3683 | Lisp_Object |
| 3734 | build_overlay (Lisp_Object start, Lisp_Object end, Lisp_Object plist) | 3684 | build_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, | |||
| 3767 | Lisp_Object | 3714 | Lisp_Object |
| 3768 | build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | 3715 | build_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) | |||
| 3793 | Lisp_Object | 3737 | Lisp_Object |
| 3794 | make_bignum_str (const char *num, int base) | 3738 | make_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) | |||
| 3811 | Lisp_Object | 3751 | Lisp_Object |
| 3812 | make_number (mpz_t value) | 3752 | make_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 | ||
| 3864 | void | 3795 | void |
| @@ -3934,14 +3865,11 @@ make_event_array (ptrdiff_t nargs, Lisp_Object *args) | |||
| 3934 | Lisp_Object | 3865 | Lisp_Object |
| 3935 | make_user_ptr (void (*finalizer) (void *), void *p) | 3866 | make_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 | |||
| 4057 | FUNCTION. FUNCTION will be run once per finalizer object. */) | 3984 | FUNCTION. 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 | |||
| 4690 | static Lisp_Object | ||
| 4691 | live_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 | |||
| 4715 | static bool | ||
| 4716 | live_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) | |||
| 5550 | static Lisp_Object | 5431 | static Lisp_Object |
| 5551 | make_pure_bignum (struct Lisp_Bignum *value) | 5432 | make_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) | |||
| 6314 | static void | 6189 | static void |
| 6315 | mark_overlay (struct Lisp_Overlay *ptr) | 6190 | mark_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 | ||
| 7082 | NO_INLINE /* For better stack traces. */ | ||
| 7083 | static void | ||
| 7084 | sweep_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. */ |
| 7159 | static void | 6932 | static 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"); |