comparison src/alloc.c @ 29743:1d802b332e0d

(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.
author Gerd Moellmann <gerd@gnu.org>
date Mon, 19 Jun 2000 15:58:43 +0000
parents fc8d42f77d4f
children 4a3b0c2cbcd5
comparison
equal deleted inserted replaced
29742:47ad175d6357 29743:1d802b332e0d
3783 mark_object (argptr) 3783 mark_object (argptr)
3784 Lisp_Object *argptr; 3784 Lisp_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;
3791 loop2: 3795 loop2:
3792 XUNMARK (obj); 3796 XUNMARK (obj);
3796 3800
3797 last_marked[last_marked_index++] = objptr; 3801 last_marked[last_marked_index++] = objptr;
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;
3819 else if (GC_COMPILEDP (obj)) 3883 else if (GC_COMPILEDP (obj))
3820 /* We could treat this just like a vector, but it is better to 3884 /* We could treat this just like a vector, but it is better to
3827 struct Lisp_Vector *volatile ptr1 = ptr; 3891 struct Lisp_Vector *volatile ptr1 = ptr;
3828 register int i; 3892 register int i;
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 */
3835 { 3901 {
3836 if (i != COMPILED_CONSTANTS) 3902 if (i != COMPILED_CONSTANTS)
3848 register EMACS_INT size = ptr->size; 3914 register EMACS_INT size = ptr->size;
3849 3915
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);
3856 mark_object (&ptr->focus_frame); 3923 mark_object (&ptr->focus_frame);
3857 mark_object (&ptr->selected_window); 3924 mark_object (&ptr->selected_window);
3879 { 3946 {
3880 register struct Lisp_Vector *ptr = XVECTOR (obj); 3947 register struct Lisp_Vector *ptr = XVECTOR (obj);
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))
3887 { 3955 {
3888 register struct Lisp_Vector *ptr = XVECTOR (obj); 3956 register struct Lisp_Vector *ptr = XVECTOR (obj);
3900 /* Stop if already marked. */ 3968 /* Stop if already marked. */
3901 if (size & ARRAY_MARK_FLAG) 3969 if (size & ARRAY_MARK_FLAG)
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
3908 struct WINDOW. Stop marking when that slot is reached. */ 3977 struct WINDOW. Stop marking when that slot is reached. */
3909 for (i = 0; 3978 for (i = 0;
3928 EMACS_INT size = h->size; 3997 EMACS_INT size = h->size;
3929 3998
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. */
3938 mark_object (&h->test); 4008 mark_object (&h->test);
3939 mark_object (&h->weak); 4009 mark_object (&h->weak);
3965 Yes, this is a crock, but we have to do it. */ 4035 Yes, this is a crock, but we have to do it. */
3966 struct Lisp_Vector *volatile ptr1 = ptr; 4036 struct Lisp_Vector *volatile ptr1 = ptr;
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;
3973 4044
3974 for (i = 0; i < size; i++) /* and then mark its elements */ 4045 for (i = 0; i < size; i++) /* and then mark its elements */
3981 /* See comment above under Lisp_Vector for why this is volatile. */ 4052 /* See comment above under Lisp_Vector for why this is volatile. */
3982 register struct Lisp_Symbol *volatile ptr = XSYMBOL (obj); 4053 register struct Lisp_Symbol *volatile ptr = XSYMBOL (obj);
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);
3989 mark_object (&ptr->plist); 4061 mark_object (&ptr->plist);
3990 4062
4008 } 4080 }
4009 } 4081 }
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:
4016 XMARK (XMARKER (obj)->chain); 4089 XMARK (XMARKER (obj)->chain);
4017 /* DO NOT mark thru the marker's chain. 4090 /* DO NOT mark thru the marker's chain.
4072 4145
4073 case Lisp_Cons: 4146 case Lisp_Cons:
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))
4080 { 4154 {
4081 objptr = &ptr->car; 4155 objptr = &ptr->car;
4086 objptr = &XCDR (obj); 4160 objptr = &XCDR (obj);
4087 goto loop; 4161 goto loop;
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
4094 case Lisp_Int: 4169 case Lisp_Int:
4095 break; 4170 break;
4096 4171
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. */
4103 4182
4104 static void 4183 static void