diff options
| author | Gerd Moellmann | 2000-06-19 15:58:43 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-06-19 15:58:43 +0000 |
| commit | 4f5c1376093d5820a0e1e460f6275871a2412e67 (patch) | |
| tree | f198a07b7b48549f9728390ff55c4bb5ca9e6c96 /src/alloc.c | |
| parent | c8bb816774000f1f139eded53827673db6f64bed (diff) | |
| download | emacs-4f5c1376093d5820a0e1e460f6275871a2412e67.tar.gz emacs-4f5c1376093d5820a0e1e460f6275871a2412e67.zip | |
(mark_object) [GC_CHECK_MARKED_OBJECTS]: Check that no
bogus objects are marked. This slows down GC by ~80 percent, but
it might be worth trying when debugging GC-related problems.
This feature requires conservative stack marking to be enabled.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/src/alloc.c b/src/alloc.c index 0c58f3cc1be..0c568f5fa70 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3785,6 +3785,10 @@ mark_object (argptr) | |||
| 3785 | { | 3785 | { |
| 3786 | Lisp_Object *objptr = argptr; | 3786 | Lisp_Object *objptr = argptr; |
| 3787 | register Lisp_Object obj; | 3787 | register Lisp_Object obj; |
| 3788 | #ifdef GC_CHECK_MARKED_OBJECTS | ||
| 3789 | void *po; | ||
| 3790 | struct mem_node *m; | ||
| 3791 | #endif | ||
| 3788 | 3792 | ||
| 3789 | loop: | 3793 | loop: |
| 3790 | obj = *objptr; | 3794 | obj = *objptr; |
| @@ -3798,21 +3802,81 @@ mark_object (argptr) | |||
| 3798 | if (last_marked_index == LAST_MARKED_SIZE) | 3802 | if (last_marked_index == LAST_MARKED_SIZE) |
| 3799 | last_marked_index = 0; | 3803 | last_marked_index = 0; |
| 3800 | 3804 | ||
| 3805 | /* Perform some sanity checks on the objects marked here. Abort if | ||
| 3806 | we encounter an object we know is bogus. This increases GC time | ||
| 3807 | by ~80%, and requires compilation with GC_MARK_STACK != 0. */ | ||
| 3808 | #ifdef GC_CHECK_MARKED_OBJECTS | ||
| 3809 | |||
| 3810 | po = (void *) XPNTR (obj); | ||
| 3811 | |||
| 3812 | /* Check that the object pointed to by PO is known to be a Lisp | ||
| 3813 | structure allocated from the heap. */ | ||
| 3814 | #define CHECK_ALLOCATED() \ | ||
| 3815 | do { \ | ||
| 3816 | m = mem_find (po); \ | ||
| 3817 | if (m == MEM_NIL) \ | ||
| 3818 | abort (); \ | ||
| 3819 | } while (0) | ||
| 3820 | |||
| 3821 | /* Check that the object pointed to by PO is live, using predicate | ||
| 3822 | function LIVEP. */ | ||
| 3823 | #define CHECK_LIVE(LIVEP) \ | ||
| 3824 | do { \ | ||
| 3825 | if (!LIVEP (m, po)) \ | ||
| 3826 | abort (); \ | ||
| 3827 | } while (0) | ||
| 3828 | |||
| 3829 | /* Check both of the above conditions. */ | ||
| 3830 | #define CHECK_ALLOCATED_AND_LIVE(LIVEP) \ | ||
| 3831 | do { \ | ||
| 3832 | CHECK_ALLOCATED (); \ | ||
| 3833 | CHECK_LIVE (LIVEP); \ | ||
| 3834 | } while (0) \ | ||
| 3835 | |||
| 3836 | #else /* not GC_CHECK_MARKED_OBJECTS */ | ||
| 3837 | |||
| 3838 | #define CHECK_ALLOCATED() (void) 0 | ||
| 3839 | #define CHECK_LIVE(LIVEP) (void) 0 | ||
| 3840 | #define CHECK_ALLOCATED_AND_LIVE(LIVEP) (void) 0 | ||
| 3841 | |||
| 3842 | #endif /* not GC_CHECK_MARKED_OBJECTS */ | ||
| 3843 | |||
| 3801 | switch (SWITCH_ENUM_CAST (XGCTYPE (obj))) | 3844 | switch (SWITCH_ENUM_CAST (XGCTYPE (obj))) |
| 3802 | { | 3845 | { |
| 3803 | case Lisp_String: | 3846 | case Lisp_String: |
| 3804 | { | 3847 | { |
| 3805 | register struct Lisp_String *ptr = XSTRING (obj); | 3848 | register struct Lisp_String *ptr = XSTRING (obj); |
| 3849 | CHECK_ALLOCATED_AND_LIVE (live_string_p); | ||
| 3806 | MARK_INTERVAL_TREE (ptr->intervals); | 3850 | MARK_INTERVAL_TREE (ptr->intervals); |
| 3807 | MARK_STRING (ptr); | 3851 | MARK_STRING (ptr); |
| 3808 | } | 3852 | } |
| 3809 | break; | 3853 | break; |
| 3810 | 3854 | ||
| 3811 | case Lisp_Vectorlike: | 3855 | case Lisp_Vectorlike: |
| 3856 | #ifdef GC_CHECK_MARKED_OBJECTS | ||
| 3857 | m = mem_find (po); | ||
| 3858 | if (m == MEM_NIL && !GC_SUBRP (obj) | ||
| 3859 | && po != &buffer_defaults | ||
| 3860 | && po != &buffer_local_symbols) | ||
| 3861 | abort (); | ||
| 3862 | #endif /* GC_CHECK_MARKED_OBJECTS */ | ||
| 3863 | |||
| 3812 | if (GC_BUFFERP (obj)) | 3864 | if (GC_BUFFERP (obj)) |
| 3813 | { | 3865 | { |
| 3814 | if (!XMARKBIT (XBUFFER (obj)->name)) | 3866 | if (!XMARKBIT (XBUFFER (obj)->name)) |
| 3815 | mark_buffer (obj); | 3867 | { |
| 3868 | #ifdef GC_CHECK_MARKED_OBJECTS | ||
| 3869 | if (po != &buffer_defaults && po != &buffer_local_symbols) | ||
| 3870 | { | ||
| 3871 | struct buffer *b; | ||
| 3872 | for (b = all_buffers; b && b != po; b = b->next) | ||
| 3873 | ; | ||
| 3874 | if (b == NULL) | ||
| 3875 | abort (); | ||
| 3876 | } | ||
| 3877 | #endif /* GC_CHECK_MARKED_OBJECTS */ | ||
| 3878 | mark_buffer (obj); | ||
| 3879 | } | ||
| 3816 | } | 3880 | } |
| 3817 | else if (GC_SUBRP (obj)) | 3881 | else if (GC_SUBRP (obj)) |
| 3818 | break; | 3882 | break; |
| @@ -3829,6 +3893,8 @@ mark_object (argptr) | |||
| 3829 | 3893 | ||
| 3830 | if (size & ARRAY_MARK_FLAG) | 3894 | if (size & ARRAY_MARK_FLAG) |
| 3831 | break; /* Already marked */ | 3895 | break; /* Already marked */ |
| 3896 | |||
| 3897 | CHECK_LIVE (live_vector_p); | ||
| 3832 | ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | 3898 | ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
| 3833 | size &= PSEUDOVECTOR_SIZE_MASK; | 3899 | size &= PSEUDOVECTOR_SIZE_MASK; |
| 3834 | for (i = 0; i < size; i++) /* and then mark its elements */ | 3900 | for (i = 0; i < size; i++) /* and then mark its elements */ |
| @@ -3850,6 +3916,7 @@ mark_object (argptr) | |||
| 3850 | if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | 3916 | if (size & ARRAY_MARK_FLAG) break; /* Already marked */ |
| 3851 | ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | 3917 | ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
| 3852 | 3918 | ||
| 3919 | CHECK_LIVE (live_vector_p); | ||
| 3853 | mark_object (&ptr->name); | 3920 | mark_object (&ptr->name); |
| 3854 | mark_object (&ptr->icon_name); | 3921 | mark_object (&ptr->icon_name); |
| 3855 | mark_object (&ptr->title); | 3922 | mark_object (&ptr->title); |
| @@ -3881,6 +3948,7 @@ mark_object (argptr) | |||
| 3881 | 3948 | ||
| 3882 | if (ptr->size & ARRAY_MARK_FLAG) | 3949 | if (ptr->size & ARRAY_MARK_FLAG) |
| 3883 | break; /* Already marked */ | 3950 | break; /* Already marked */ |
| 3951 | CHECK_LIVE (live_vector_p); | ||
| 3884 | ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | 3952 | ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
| 3885 | } | 3953 | } |
| 3886 | else if (GC_WINDOWP (obj)) | 3954 | else if (GC_WINDOWP (obj)) |
| @@ -3902,6 +3970,7 @@ mark_object (argptr) | |||
| 3902 | break; | 3970 | break; |
| 3903 | 3971 | ||
| 3904 | /* Mark it. */ | 3972 | /* Mark it. */ |
| 3973 | CHECK_LIVE (live_vector_p); | ||
| 3905 | ptr->size |= ARRAY_MARK_FLAG; | 3974 | ptr->size |= ARRAY_MARK_FLAG; |
| 3906 | 3975 | ||
| 3907 | /* There is no Lisp data above The member CURRENT_MATRIX in | 3976 | /* There is no Lisp data above The member CURRENT_MATRIX in |
| @@ -3930,8 +3999,9 @@ mark_object (argptr) | |||
| 3930 | /* Stop if already marked. */ | 3999 | /* Stop if already marked. */ |
| 3931 | if (size & ARRAY_MARK_FLAG) | 4000 | if (size & ARRAY_MARK_FLAG) |
| 3932 | break; | 4001 | break; |
| 3933 | 4002 | ||
| 3934 | /* Mark it. */ | 4003 | /* Mark it. */ |
| 4004 | CHECK_LIVE (live_vector_p); | ||
| 3935 | h->size |= ARRAY_MARK_FLAG; | 4005 | h->size |= ARRAY_MARK_FLAG; |
| 3936 | 4006 | ||
| 3937 | /* Mark contents. */ | 4007 | /* Mark contents. */ |
| @@ -3967,6 +4037,7 @@ mark_object (argptr) | |||
| 3967 | register int i; | 4037 | register int i; |
| 3968 | 4038 | ||
| 3969 | if (size & ARRAY_MARK_FLAG) break; /* Already marked */ | 4039 | if (size & ARRAY_MARK_FLAG) break; /* Already marked */ |
| 4040 | CHECK_LIVE (live_vector_p); | ||
| 3970 | ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ | 4041 | ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
| 3971 | if (size & PSEUDOVECTOR_FLAG) | 4042 | if (size & PSEUDOVECTOR_FLAG) |
| 3972 | size &= PSEUDOVECTOR_SIZE_MASK; | 4043 | size &= PSEUDOVECTOR_SIZE_MASK; |
| @@ -3983,6 +4054,7 @@ mark_object (argptr) | |||
| 3983 | struct Lisp_Symbol *ptrx; | 4054 | struct Lisp_Symbol *ptrx; |
| 3984 | 4055 | ||
| 3985 | if (XMARKBIT (ptr->plist)) break; | 4056 | if (XMARKBIT (ptr->plist)) break; |
| 4057 | CHECK_ALLOCATED_AND_LIVE (live_symbol_p); | ||
| 3986 | XMARK (ptr->plist); | 4058 | XMARK (ptr->plist); |
| 3987 | mark_object ((Lisp_Object *) &ptr->value); | 4059 | mark_object ((Lisp_Object *) &ptr->value); |
| 3988 | mark_object (&ptr->function); | 4060 | mark_object (&ptr->function); |
| @@ -4010,6 +4082,7 @@ mark_object (argptr) | |||
| 4010 | break; | 4082 | break; |
| 4011 | 4083 | ||
| 4012 | case Lisp_Misc: | 4084 | case Lisp_Misc: |
| 4085 | CHECK_ALLOCATED_AND_LIVE (live_misc_p); | ||
| 4013 | switch (XMISCTYPE (obj)) | 4086 | switch (XMISCTYPE (obj)) |
| 4014 | { | 4087 | { |
| 4015 | case Lisp_Misc_Marker: | 4088 | case Lisp_Misc_Marker: |
| @@ -4074,6 +4147,7 @@ mark_object (argptr) | |||
| 4074 | { | 4147 | { |
| 4075 | register struct Lisp_Cons *ptr = XCONS (obj); | 4148 | register struct Lisp_Cons *ptr = XCONS (obj); |
| 4076 | if (XMARKBIT (ptr->car)) break; | 4149 | if (XMARKBIT (ptr->car)) break; |
| 4150 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); | ||
| 4077 | XMARK (ptr->car); | 4151 | XMARK (ptr->car); |
| 4078 | /* If the cdr is nil, avoid recursion for the car. */ | 4152 | /* If the cdr is nil, avoid recursion for the car. */ |
| 4079 | if (EQ (ptr->cdr, Qnil)) | 4153 | if (EQ (ptr->cdr, Qnil)) |
| @@ -4088,6 +4162,7 @@ mark_object (argptr) | |||
| 4088 | } | 4162 | } |
| 4089 | 4163 | ||
| 4090 | case Lisp_Float: | 4164 | case Lisp_Float: |
| 4165 | CHECK_ALLOCATED_AND_LIVE (live_float_p); | ||
| 4091 | XMARK (XFLOAT (obj)->type); | 4166 | XMARK (XFLOAT (obj)->type); |
| 4092 | break; | 4167 | break; |
| 4093 | 4168 | ||
| @@ -4097,6 +4172,10 @@ mark_object (argptr) | |||
| 4097 | default: | 4172 | default: |
| 4098 | abort (); | 4173 | abort (); |
| 4099 | } | 4174 | } |
| 4175 | |||
| 4176 | #undef CHECK_LIVE | ||
| 4177 | #undef CHECK_ALLOCATED | ||
| 4178 | #undef CHECK_ALLOCATED_AND_LIVE | ||
| 4100 | } | 4179 | } |
| 4101 | 4180 | ||
| 4102 | /* Mark the pointers in a buffer structure. */ | 4181 | /* Mark the pointers in a buffer structure. */ |