comparison src/lrecord.h @ 272:c5d627a313b1 r21-0b34

Import from CVS: tag r21-0b34
author cvs
date Mon, 13 Aug 2007 10:28:48 +0200
parents f220cc83d72e
children 8626e4521993
comparison
equal deleted inserted replaced
271:c7b7086b0a39 272:c5d627a313b1
32 four bytes of all lrecords is either a pointer to a struct 32 four bytes of all lrecords is either a pointer to a struct
33 lrecord_implementation, which contains methods describing how 33 lrecord_implementation, which contains methods describing how
34 to process this object, or an index into an array of pointers 34 to process this object, or an index into an array of pointers
35 to struct lrecord_implementations plus some other data bits. 35 to struct lrecord_implementations plus some other data bits.
36 36
37 lrecords are of two types: straight lrecords, and lcrecords. 37 Lrecords are of two types: straight lrecords, and lcrecords.
38 Straight lrecords are used for those types of objects that 38 Straight lrecords are used for those types of objects that have
39 have their own allocation routines (typically allocated out of 39 their own allocation routines (typically allocated out of 2K chunks
40 2K chunks of memory). These objects have a `struct 40 of memory called `frob blocks'). These objects have a `struct
41 lrecord_header' at the top, containing only the bits needed to 41 lrecord_header' at the top, containing only the bits needed to find
42 find the lrecord_implementation for the object. There are 42 the lrecord_implementation for the object. There are special
43 special routines in alloc.c to deal with each such object 43 routines in alloc.c to deal with each such object type.
44 type.
45 44
46 Lcrecords are used for less common sorts of objects that don't 45 Lcrecords are used for less common sorts of objects that don't
47 do their own allocation. Each such object is malloc()ed 46 do their own allocation. Each such object is malloc()ed
48 individually, and the objects are chained together through 47 individually, and the objects are chained together through
49 a `next' pointer. Lcrecords have a `struct lcrecord_header' 48 a `next' pointer. Lcrecords have a `struct lcrecord_header'
91 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION 90 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION
92 /* index into lrecord_implementations_table[] */ 91 /* index into lrecord_implementations_table[] */
93 unsigned type:8; 92 unsigned type:8;
94 /* 1 if the object is marked during GC, 0 otherwise. */ 93 /* 1 if the object is marked during GC, 0 otherwise. */
95 unsigned mark:1; 94 unsigned mark:1;
96 /* 1 if the object was resides in pure (read-only) space */ 95 /* 1 if the object resides in pure (read-only) space */
97 unsigned pure:1; 96 unsigned pure:1;
98 #else 97 #else
99 CONST struct lrecord_implementation *implementation; 98 CONST struct lrecord_implementation *implementation;
100 #endif 99 #endif
101 }; 100 };
102 101
103
104 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION
105 struct lrecord_implementation; 102 struct lrecord_implementation;
106 int lrecord_type_index (CONST struct lrecord_implementation *implementation); 103 int lrecord_type_index (CONST struct lrecord_implementation *implementation);
104
105 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION
106 # define set_lheader_implementation(header,imp) do \
107 { \
108 (header)->type = lrecord_type_index (imp); \
109 (header)->mark = 0; \
110 (header)->pure = 0; \
111 } while (0)
112 #else
107 # define set_lheader_implementation(header,imp) \ 113 # define set_lheader_implementation(header,imp) \
108 do { (header)->type = lrecord_type_index((imp)); \ 114 ((void) ((header)->implementation = (imp)))
109 (header)->mark = 0; \
110 (header)->pure = 0; \
111 } while (0)
112 #else
113 # define set_lheader_implementation(header,imp) (header)->implementation=(imp)
114 #endif 115 #endif
115 116
116 struct lcrecord_header 117 struct lcrecord_header
117 { 118 {
118 struct lrecord_header lheader; 119 struct lrecord_header lheader;
147 Lisp_Object chain; 148 Lisp_Object chain;
148 }; 149 };
149 150
150 /* This as the value of lheader->implementation->finalizer 151 /* This as the value of lheader->implementation->finalizer
151 * means that this record is already marked */ 152 * means that this record is already marked */
152 extern void this_marks_a_marked_record (void *, int); 153 void this_marks_a_marked_record (void *, int);
153 154
154 /* see alloc.c for an explanation */ 155 /* see alloc.c for an explanation */
155 extern Lisp_Object this_one_is_unmarkable (Lisp_Object obj, 156 Lisp_Object this_one_is_unmarkable (Lisp_Object obj,
156 void (*markobj) (Lisp_Object)); 157 void (*markobj) (Lisp_Object));
157 158
158 struct lrecord_implementation 159 struct lrecord_implementation
159 { 160 {
160 CONST char *name; 161 CONST char *name;
161 /* This function is called at GC time, to make sure that all Lisp_Objects 162 /* This function is called at GC time, to make sure that all Lisp_Objects
192 int (*remprop) (Lisp_Object obj, Lisp_Object prop); 193 int (*remprop) (Lisp_Object obj, Lisp_Object prop);
193 Lisp_Object (*plist) (Lisp_Object obj); 194 Lisp_Object (*plist) (Lisp_Object obj);
194 195
195 /* Only one of these is non-0. If both are 0, it means that this type 196 /* Only one of these is non-0. If both are 0, it means that this type
196 is not instantiable by alloc_lcrecord(). */ 197 is not instantiable by alloc_lcrecord(). */
197 unsigned int static_size; 198 size_t static_size;
198 unsigned int (*size_in_bytes_method) (CONST void *header); 199 size_t (*size_in_bytes_method) (CONST void *header);
199 /* A unique subtag-code (dynamically) assigned to this datatype. */ 200 /* A unique subtag-code (dynamically) assigned to this datatype. */
200 /* (This is a pointer so the rest of this structure can be read-only.) */ 201 /* (This is a pointer so the rest of this structure can be read-only.) */
201 int *lrecord_type_index; 202 int *lrecord_type_index;
202 /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e. 203 /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e.
203 one that does not have an lcrecord_header at the front and which 204 one that does not have an lcrecord_header at the front and which
205 some consistency checking, and that only when error-checking is 206 some consistency checking, and that only when error-checking is
206 enabled. */ 207 enabled. */
207 int basic_p; 208 int basic_p;
208 }; 209 };
209 210
211 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION
210 extern CONST struct lrecord_implementation *lrecord_implementations_table[]; 212 extern CONST struct lrecord_implementation *lrecord_implementations_table[];
211 213
212 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION
213 # define XRECORD_LHEADER_IMPLEMENTATION(obj) \ 214 # define XRECORD_LHEADER_IMPLEMENTATION(obj) \
214 (lrecord_implementations_table[XRECORD_LHEADER (obj)->type]) 215 (lrecord_implementations_table[XRECORD_LHEADER (obj)->type])
215 # define LHEADER_IMPLEMENTATION(lh) (lrecord_implementations_table[(lh)->type]) 216 # define LHEADER_IMPLEMENTATION(lh) (lrecord_implementations_table[(lh)->type])
216 #else 217 #else
217 # define XRECORD_LHEADER_IMPLEMENTATION(obj) \ 218 # define XRECORD_LHEADER_IMPLEMENTATION(obj) \
222 extern int gc_in_progress; 223 extern int gc_in_progress;
223 224
224 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION 225 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION
225 # define MARKED_RECORD_P(obj) (gc_in_progress && XRECORD_LHEADER (obj)->mark) 226 # define MARKED_RECORD_P(obj) (gc_in_progress && XRECORD_LHEADER (obj)->mark)
226 #else 227 #else
227 # define MARKED_RECORD_P(obj) (gc_in_progress && \ 228 # define MARKED_RECORD_P(obj) (gc_in_progress && \
228 XRECORD_LHEADER (obj)->implementation->finalizer == \ 229 XRECORD_LHEADER (obj)->implementation->finalizer == \
229 this_marks_a_marked_record) 230 this_marks_a_marked_record)
230 #endif 231 #endif
231 232
232 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION 233 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION
233 234
270 #else 271 #else
271 # define DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) 272 # define DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype)
272 #endif 273 #endif
273 274
274 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,structtype) \ 275 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,structtype) \
275 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ 276 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,structtype)
276 static int lrecord_##c_name##_lrecord_type_index; \
277 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name[2] = \
278 { { name, marker, printer, nuker, equal, hash, \
279 0, 0, 0, 0, sizeof (structtype), 0, \
280 &(lrecord_##c_name##_lrecord_type_index), 1 }, \
281 { 0, 0, 0, this_marks_a_marked_record, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }
282 277
283 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,structtype) \ 278 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,structtype) \
284 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ 279 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizeof(structtype),0,1,structtype)
285 static int lrecord_##c_name##_lrecord_type_index; \
286 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name[2] = \
287 { { name, marker, printer, nuker, equal, hash, \
288 getprop, putprop, remprop, props, sizeof (structtype), 0, \
289 &(lrecord_##c_name##_lrecord_type_index), 1 }, \
290 { 0, 0, 0, this_marks_a_marked_record, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } }
291 280
292 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,structtype) \ 281 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,structtype) \
293 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ 282 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,structtype)
294 static int lrecord_##c_name##_lrecord_type_index; \
295 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name[2] = \
296 { { name, marker, printer, nuker, equal, hash, \
297 0, 0, 0, 0, sizeof (structtype), 0, \
298 &(lrecord_##c_name##_lrecord_type_index), 0 }, \
299 { 0, 0, 0, this_marks_a_marked_record, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
300 283
301 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,structtype) \ 284 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,structtype) \
302 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ 285 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizeof (structtype),0,0,structtype)
303 static int lrecord_##c_name##_lrecord_type_index; \
304 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name[2] = \
305 { { name, marker, printer, nuker, equal, hash, \
306 getprop, putprop, remprop, props, sizeof (structtype), 0, \
307 &(lrecord_##c_name##_lrecord_type_index), 0 }, \
308 { 0, 0, 0, this_marks_a_marked_record, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
309 286
310 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,sizer,structtype) \ 287 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,sizer,structtype) \
288 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,sizer,structtype)
289
290 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizer,structtype) \
291 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,0,sizer,0,structtype) \
292
293 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,size,sizer,basic_p,structtype) \
311 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ 294 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \
312 static int lrecord_##c_name##_lrecord_type_index; \ 295 static int lrecord_##c_name##_lrecord_type_index; \
313 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name[2] = \ 296 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name[2] = \
314 { { name, marker, printer, nuker, equal, hash, \ 297 { { name, marker, printer, nuker, equal, hash, \
315 0, 0, 0, 0, 0, sizer, \ 298 getprop, putprop, remprop, props, size, sizer, \
316 &(lrecord_##c_name##_lrecord_type_index), 0 }, \ 299 &(lrecord_##c_name##_lrecord_type_index), basic_p }, \
317 { 0, 0, 0, this_marks_a_marked_record, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } 300 { 0, 0, 0, this_marks_a_marked_record, 0, 0, 0, 0, 0, 0, 0, 0, 0, basic_p } }
318
319 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizer,structtype) \
320 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \
321 static int lrecord_##c_name##_lrecord_type_index; \
322 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name[2] = \
323 { { name, marker, printer, nuker, equal, hash, \
324 getprop, putprop, remprop, props, 0, sizer, \
325 &(lrecord_##c_name##_lrecord_type_index), 0 }, \
326 { 0, 0, 0, this_marks_a_marked_record, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
327 301
328 #define LRECORDP(a) (XTYPE ((a)) == Lisp_Type_Record) 302 #define LRECORDP(a) (XTYPE ((a)) == Lisp_Type_Record)
329 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a)) 303 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a))
330 304
331 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION 305 #ifdef USE_INDEXED_LRECORD_IMPLEMENTATION
439 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \ 413 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \
440 if (XTYPE (x) != lisp_enum) \ 414 if (XTYPE (x) != lisp_enum) \
441 dead_wrong_type_argument (predicate, x); \ 415 dead_wrong_type_argument (predicate, x); \
442 } while (0) 416 } while (0)
443 417
444 void *alloc_lcrecord (int size, CONST struct lrecord_implementation *); 418 void *alloc_lcrecord (size_t size, CONST struct lrecord_implementation *);
445 419
446 #define alloc_lcrecord_type(type, lrecord_implementation) \ 420 #define alloc_lcrecord_type(type, lrecord_implementation) \
447 ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation)) 421 ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation))
448 422
449 int gc_record_type_p (Lisp_Object frob, 423 int gc_record_type_p (Lisp_Object frob,