comparison src/lrecord.h @ 424:11054d720c21 r21-2-20

Import from CVS: tag r21-2-20
author cvs
date Mon, 13 Aug 2007 11:26:11 +0200
parents 41dbb7a9d5f2
children
comparison
equal deleted inserted replaced
423:28d9c139be4c 424:11054d720c21
117 struct lcrecord_header lcheader; 117 struct lcrecord_header lcheader;
118 Lisp_Object chain; 118 Lisp_Object chain;
119 }; 119 };
120 120
121 /* see alloc.c for an explanation */ 121 /* see alloc.c for an explanation */
122 Lisp_Object this_one_is_unmarkable (Lisp_Object obj, 122 Lisp_Object this_one_is_unmarkable (Lisp_Object obj);
123 void (*markobj) (Lisp_Object));
124 123
125 struct lrecord_implementation 124 struct lrecord_implementation
126 { 125 {
127 CONST char *name; 126 CONST char *name;
128 /* This function is called at GC time, to make sure that all Lisp_Objects 127 /* This function is called at GC time, to make sure that all Lisp_Objects
132 marked (don't call the mark_object function explicitly on it, 131 marked (don't call the mark_object function explicitly on it,
133 because the GC routines will do this). Doing it this way reduces 132 because the GC routines will do this). Doing it this way reduces
134 recursion, so the object returned should preferably be the one 133 recursion, so the object returned should preferably be the one
135 with the deepest level of Lisp_Object pointers. This function 134 with the deepest level of Lisp_Object pointers. This function
136 can be NULL, meaning no GC marking is necessary. */ 135 can be NULL, meaning no GC marking is necessary. */
137 Lisp_Object (*marker) (Lisp_Object, void (*mark_object) (Lisp_Object)); 136 Lisp_Object (*marker) (Lisp_Object);
138 /* This can be NULL if the object is an lcrecord; the 137 /* This can be NULL if the object is an lcrecord; the
139 default_object_printer() in print.c will be used. */ 138 default_object_printer() in print.c will be used. */
140 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag); 139 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag);
141 /* This function is called at GC time when the object is about to 140 /* This function is called at GC time when the object is about to
142 be freed, and at dump time (FOR_DISKSAVE will be non-zero in this 141 be freed, and at dump time (FOR_DISKSAVE will be non-zero in this
206 A lrecord external description is an array of values. The first 205 A lrecord external description is an array of values. The first
207 value of each line is a type, the second the offset in the lrecord 206 value of each line is a type, the second the offset in the lrecord
208 structure. Following values are parameters, their presence, type 207 structure. Following values are parameters, their presence, type
209 and number is type-dependant. 208 and number is type-dependant.
210 209
211 The description ends with a "XD_END" record. 210 The description ends with a "XD_END" or "XD_SPECIFIER_END" record.
212 211
213 Some example descriptions : 212 Some example descriptions :
214 static const struct lrecord_description cons_description[] = { 213 static const struct lrecord_description cons_description[] = {
215 { XD_LISP_OBJECT, offsetof(struct Lisp_Cons, car), 2 }, 214 { XD_LISP_OBJECT, offsetof(struct Lisp_Cons, car), 2 },
216 { XD_END } 215 { XD_END }
217 }; 216 };
218 217
219 Which means "two lisp objects starting at the 'car' element" 218 Which means "two lisp objects starting at the 'car' element"
220 219
221 static const struct lrecord_description string_description[] = { 220 static const struct lrecord_description string_description[] = {
222 { XD_STRING_DATA, offsetof(Lisp_String, data) }, 221 { XD_BYTECOUNT, offsetof(Lisp_String, size) },
223 { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 }, 222 { XD_OPAQUE_DATA_PTR, offsetof(Lisp_String, data), XD_INDIRECT(0, 1) },
223 { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 },
224 { XD_END } 224 { XD_END }
225 }; 225 };
226 "A string data pointer at 'data', one lisp object at 'plist'" 226 "A pointer to string data at 'data', the size of the pointed array being the value
227 of the size variable plus 1, and one lisp object at 'plist'"
227 228
228 The existing types : 229 The existing types :
229 XD_LISP_OBJECT 230 XD_LISP_OBJECT
230 Lisp objects. The third element is the count. This is also the type to use 231 Lisp objects. The third element is the count. This is also the type to use
231 for pointers to other lrecords. 232 for pointers to other lrecords.
232 233
233 XD_STRING_DATA 234 XD_LO_RESET_NIL
234 Pointer to string data. 235 Lisp objects which will be reset to Qnil when dumping. Useful for cleaning
235 236 up caches.
237
238 XD_LO_LINK
239 Link in a linked list of objects of the same type.
240
236 XD_OPAQUE_PTR 241 XD_OPAQUE_PTR
237 Pointer to undumpable data. Must be NULL when dumping. 242 Pointer to undumpable data. Must be NULL when dumping.
238 243
239 XD_STRUCT_PTR 244 XD_STRUCT_PTR
240 Pointer to described struct. Parameters are number of structures and 245 Pointer to described struct. Parameters are number of structures and
242 247
243 XD_OPAQUE_DATA_PTR 248 XD_OPAQUE_DATA_PTR
244 Pointer to dumpable opaque data. Parameter is the size of the data. 249 Pointer to dumpable opaque data. Parameter is the size of the data.
245 Pointed data must be relocatable without changes. 250 Pointed data must be relocatable without changes.
246 251
252 XD_C_STRING
253 Pointer to a C string.
254
255 XD_DOC_STRING
256 Pointer to a doc string (C string if positive, opaque value if negative)
257
258 XD_INT_RESET
259 An integer which will be reset to a given value in the dump file.
260
261
247 XD_SIZE_T 262 XD_SIZE_T
248 size_t value. Used for counts. 263 size_t value. Used for counts.
249 264
250 XD_INT 265 XD_INT
251 int value. Used for counts. 266 int value. Used for counts.
252 267
253 XD_LONG 268 XD_LONG
254 long value. Used for counts. 269 long value. Used for counts.
255 270
271 XD_BYTECOUNT
272 bytecount value. Used for counts.
273
256 XD_END 274 XD_END
257 Special type indicating the end of the array. 275 Special type indicating the end of the array.
258 276
277 XD_SPECIFIER_END
278 Special type indicating the end of the array for a specifier. Extra
279 description is going to be fetched from the specifier methods.
280
259 281
260 Special macros: 282 Special macros:
261 XD_INDIRECT(line) 283 XD_INDIRECT(line, delta)
262 Usable where a "count" or "size" is requested. Gives the value of the element 284 Usable where a "count" or "size" is requested. Gives the value of
263 which is at line number 'line' in the description (count starts at zero). 285 the element which is at line number 'line' in the description (count
264 286 starts at zero) and adds delta to it.
265 XD_PARENT_INDIRECT(line)
266 Same as XD_INDIRECT but the element number refers to the parent structure.
267 Usable only in struct descriptions.
268 */ 287 */
269 288
270 enum lrecord_description_type { 289 enum lrecord_description_type {
271 XD_LISP_OBJECT, 290 XD_LISP_OBJECT,
272 XD_STRING_DATA, 291 XD_LO_RESET_NIL,
292 XD_LO_LINK,
273 XD_OPAQUE_PTR, 293 XD_OPAQUE_PTR,
274 XD_STRUCT_PTR, 294 XD_STRUCT_PTR,
275 XD_OPAQUE_DATA_PTR, 295 XD_OPAQUE_DATA_PTR,
296 XD_C_STRING,
297 XD_DOC_STRING,
298 XD_INT_RESET,
276 XD_SIZE_T, 299 XD_SIZE_T,
277 XD_INT, 300 XD_INT,
278 XD_LONG, 301 XD_LONG,
279 XD_END 302 XD_BYTECOUNT,
303 XD_END,
304 XD_SPECIFIER_END
280 }; 305 };
281 306
282 struct lrecord_description { 307 struct lrecord_description {
283 enum lrecord_description_type type; 308 enum lrecord_description_type type;
284 int offset; 309 int offset;
289 struct struct_description { 314 struct struct_description {
290 size_t size; 315 size_t size;
291 const struct lrecord_description *description; 316 const struct lrecord_description *description;
292 }; 317 };
293 318
294 #define XD_INDIRECT(count) (-1-(count)) 319 #define XD_INDIRECT(val, delta) (-1-((val)|(delta<<8)))
295 #define XD_PARENT_INDIRECT(count) (-1000-(count)) 320
321 #define XD_IS_INDIRECT(code) (code<0)
322 #define XD_INDIRECT_VAL(code) ((-1-code) & 255)
323 #define XD_INDIRECT_DELTA(code) (((-1-code)>>8) & 255)
296 324
297 #define XD_DYNARR_DESC(base_type, sub_desc) \ 325 #define XD_DYNARR_DESC(base_type, sub_desc) \
298 { XD_STRUCT_PTR, offsetof(base_type, base), XD_INDIRECT(1), sub_desc }, \ 326 { XD_STRUCT_PTR, offsetof(base_type, base), XD_INDIRECT(1, 0), sub_desc }, \
299 { XD_INT, offsetof(base_type, max) } 327 { XD_INT, offsetof(base_type, cur) }, \
328 { XD_INT_RESET, offsetof(base_type, max), XD_INDIRECT(1, 0) }
300 329
301 /* Declaring the following structures as const puts them in the 330 /* Declaring the following structures as const puts them in the
302 text (read-only) segment, which makes debugging inconvenient 331 text (read-only) segment, which makes debugging inconvenient
303 because this segment is not mapped when processing a core- 332 because this segment is not mapped when processing a core-
304 dump file */ 333 dump file */
343 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name = \ 372 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name = \
344 { name, marker, printer, nuker, equal, hash, desc, \ 373 { name, marker, printer, nuker, equal, hash, desc, \
345 getprop, putprop, remprop, props, size, sizer, \ 374 getprop, putprop, remprop, props, size, sizer, \
346 &(lrecord_##c_name##_lrecord_type_index), basic_p } \ 375 &(lrecord_##c_name##_lrecord_type_index), basic_p } \
347 376
348 #define LRECORDP(a) (XTYPE ((a)) == Lisp_Type_Record) 377 #define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record)
349 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a)) 378 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a))
350 379
351 #define RECORD_TYPEP(x, ty) \ 380 #define RECORD_TYPEP(x, ty) \
352 (LRECORDP (x) && \ 381 (LRECORDP (x) && \
353 lrecord_implementations_table[XRECORD_LHEADER (x)->type] == (ty)) 382 lrecord_implementations_table[XRECORD_LHEADER (x)->type] == (ty))
368 lrecord_##c_name; \ 397 lrecord_##c_name; \
369 INLINE structtype *error_check_##c_name (Lisp_Object obj); \ 398 INLINE structtype *error_check_##c_name (Lisp_Object obj); \
370 INLINE structtype * \ 399 INLINE structtype * \
371 error_check_##c_name (Lisp_Object obj) \ 400 error_check_##c_name (Lisp_Object obj) \
372 { \ 401 { \
373 assert (RECORD_TYPEP (obj, &lrecord_##c_name) || \ 402 assert (RECORD_TYPEP (obj, &lrecord_##c_name)); \
374 MARKED_RECORD_P (obj)); \
375 return (structtype *) XPNTR (obj); \ 403 return (structtype *) XPNTR (obj); \
376 } \ 404 } \
377 extern Lisp_Object Q##c_name##p 405 extern Lisp_Object Q##c_name##p
378 406
379 # define DECLARE_NONRECORD(c_name, type_enum, structtype) \ 407 # define DECLARE_NONRECORD(c_name, type_enum, structtype) \
380 INLINE structtype *error_check_##c_name (Lisp_Object obj); \ 408 INLINE structtype *error_check_##c_name (Lisp_Object obj); \
381 INLINE structtype * \ 409 INLINE structtype * \
382 error_check_##c_name (Lisp_Object obj) \ 410 error_check_##c_name (Lisp_Object obj) \
383 { \ 411 { \
384 assert (XGCTYPE (obj) == type_enum); \ 412 assert (XTYPE (obj) == type_enum); \
385 return (structtype *) XPNTR (obj); \ 413 return (structtype *) XPNTR (obj); \
386 } \ 414 } \
387 extern Lisp_Object Q##c_name##p 415 extern Lisp_Object Q##c_name##p
388 416
389 # define XRECORD(x, c_name, structtype) error_check_##c_name (x) 417 # define XRECORD(x, c_name, structtype) error_check_##c_name (x)
390 # define XNONRECORD(x, c_name, type_enum, structtype) error_check_##c_name (x) 418 # define XNONRECORD(x, c_name, type_enum, structtype) error_check_##c_name (x)
391 419
392 # define XSETRECORD(var, p, c_name) do \ 420 # define XSETRECORD(var, p, c_name) do \
393 { \ 421 { \
394 XSETOBJ (var, Lisp_Type_Record, p); \ 422 XSETOBJ (var, Lisp_Type_Record, p); \
395 assert (RECORD_TYPEP (var, &lrecord_##c_name) || \ 423 assert (RECORD_TYPEP (var, &lrecord_##c_name)); \
396 MARKED_RECORD_P (var)); \
397 } while (0) 424 } while (0)
398 425
399 #else /* not ERROR_CHECK_TYPECHECK */ 426 #else /* not ERROR_CHECK_TYPECHECK */
400 427
401 # define DECLARE_LRECORD(c_name, structtype) \ 428 # define DECLARE_LRECORD(c_name, structtype) \
410 # define XSETRECORD(var, p, c_name) XSETOBJ (var, Lisp_Type_Record, p) 437 # define XSETRECORD(var, p, c_name) XSETOBJ (var, Lisp_Type_Record, p)
411 438
412 #endif /* not ERROR_CHECK_TYPECHECK */ 439 #endif /* not ERROR_CHECK_TYPECHECK */
413 440
414 #define RECORDP(x, c_name) RECORD_TYPEP (x, &lrecord_##c_name) 441 #define RECORDP(x, c_name) RECORD_TYPEP (x, &lrecord_##c_name)
415 #define GC_RECORDP(x, c_name) gc_record_type_p (x, &lrecord_##c_name)
416 442
417 /* Note: we now have two different kinds of type-checking macros. 443 /* Note: we now have two different kinds of type-checking macros.
418 The "old" kind has now been renamed CONCHECK_foo. The reason for 444 The "old" kind has now been renamed CONCHECK_foo. The reason for
419 this is that the CONCHECK_foo macros signal a continuable error, 445 this is that the CONCHECK_foo macros signal a continuable error,
420 allowing the user (through debug-on-error) to substitute a different 446 allowing the user (through debug-on-error) to substitute a different
457 void *alloc_lcrecord (size_t size, CONST struct lrecord_implementation *); 483 void *alloc_lcrecord (size_t size, CONST struct lrecord_implementation *);
458 484
459 #define alloc_lcrecord_type(type, lrecord_implementation) \ 485 #define alloc_lcrecord_type(type, lrecord_implementation) \
460 ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation)) 486 ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation))
461 487
462 int gc_record_type_p (Lisp_Object frob,
463 CONST struct lrecord_implementation *type);
464
465 /* Copy the data from one lcrecord structure into another, but don't 488 /* Copy the data from one lcrecord structure into another, but don't
466 overwrite the header information. */ 489 overwrite the header information. */
467 490
468 #define copy_lcrecord(dst, src) \ 491 #define copy_lcrecord(dst, src) \
469 memcpy ((char *) dst + sizeof (struct lcrecord_header), \ 492 memcpy ((char *) dst + sizeof (struct lcrecord_header), \