aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorGerd Moellmann2000-06-19 15:58:43 +0000
committerGerd Moellmann2000-06-19 15:58:43 +0000
commit4f5c1376093d5820a0e1e460f6275871a2412e67 (patch)
treef198a07b7b48549f9728390ff55c4bb5ca9e6c96 /src/alloc.c
parentc8bb816774000f1f139eded53827673db6f64bed (diff)
downloademacs-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.c83
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. */