comparison src/lrecord.h @ 5157:1fae11d56ad2

redo memory-usage mechanism, add way of dynamically initializing Lisp objects -------------------- ChangeLog entries follow: -------------------- lisp/ChangeLog addition: 2010-03-18 Ben Wing <ben@xemacs.org> * diagnose.el (show-memory-usage): Rewrite to take into account API changes in memory-usage functions. src/ChangeLog addition: 2010-03-18 Ben Wing <ben@xemacs.org> * alloc.c: * alloc.c (disksave_object_finalization_1): * alloc.c (lisp_object_storage_size): * alloc.c (listu): * alloc.c (listn): * alloc.c (Fobject_memory_usage_stats): * alloc.c (compute_memusage_stats_length): * alloc.c (Fobject_memory_usage): * alloc.c (Ftotal_object_memory_usage): * alloc.c (malloced_storage_size): * alloc.c (common_init_alloc_early): * alloc.c (reinit_alloc_objects_early): * alloc.c (reinit_alloc_early): * alloc.c (init_alloc_once_early): * alloc.c (syms_of_alloc): * alloc.c (reinit_vars_of_alloc): * buffer.c: * buffer.c (struct buffer_stats): * buffer.c (compute_buffer_text_usage): * buffer.c (compute_buffer_usage): * buffer.c (buffer_memory_usage): * buffer.c (buffer_objects_create): * buffer.c (syms_of_buffer): * buffer.c (vars_of_buffer): * console-impl.h (struct console_methods): * dynarr.c (Dynarr_memory_usage): * emacs.c (main_1): * events.c (clear_event_resource): * extents.c: * extents.c (compute_buffer_extent_usage): * extents.c (extent_objects_create): * extents.h: * faces.c: * faces.c (compute_face_cachel_usage): * faces.c (face_objects_create): * faces.h: * general-slots.h: * glyphs.c: * glyphs.c (compute_glyph_cachel_usage): * glyphs.c (glyph_objects_create): * glyphs.h: * lisp.h: * lisp.h (struct usage_stats): * lrecord.h: * lrecord.h (enum lrecord_type): * lrecord.h (struct lrecord_implementation): * lrecord.h (MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE): * lrecord.h (DEFINE_DUMPABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_INTERNAL_LISP_OBJECT): * lrecord.h (MAKE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_SIZABLE_LISP_OBJECT): * lrecord.h (MAKE_MODULE_LISP_OBJECT): * lrecord.h (INIT_LISP_OBJECT): * lrecord.h (INIT_MODULE_LISP_OBJECT): * lrecord.h (UNDEF_LISP_OBJECT): * lrecord.h (UNDEF_MODULE_LISP_OBJECT): * lrecord.h (DECLARE_LISP_OBJECT): * lrecord.h (DECLARE_MODULE_API_LISP_OBJECT): * lrecord.h (DECLARE_MODULE_LISP_OBJECT): * lstream.c: * lstream.c (syms_of_lstream): * lstream.c (vars_of_lstream): * marker.c: * marker.c (compute_buffer_marker_usage): * mc-alloc.c (mc_alloced_storage_size): * mc-alloc.h: * mule-charset.c: * mule-charset.c (struct charset_stats): * mule-charset.c (compute_charset_usage): * mule-charset.c (charset_memory_usage): * mule-charset.c (mule_charset_objects_create): * mule-charset.c (syms_of_mule_charset): * mule-charset.c (vars_of_mule_charset): * redisplay.c: * redisplay.c (compute_rune_dynarr_usage): * redisplay.c (compute_display_block_dynarr_usage): * redisplay.c (compute_glyph_block_dynarr_usage): * redisplay.c (compute_display_line_dynarr_usage): * redisplay.c (compute_line_start_cache_dynarr_usage): * redisplay.h: * scrollbar-gtk.c (gtk_compute_scrollbar_instance_usage): * scrollbar-msw.c (mswindows_compute_scrollbar_instance_usage): * scrollbar-x.c (x_compute_scrollbar_instance_usage): * scrollbar.c (compute_scrollbar_instance_usage): * scrollbar.h: * symbols.c: * symbols.c (reinit_symbol_objects_early): * symbols.c (init_symbols_once_early): * symbols.c (reinit_symbols_early): * symbols.c (defsymbol_massage_name_1): * symsinit.h: * ui-gtk.c: * ui-gtk.c (emacs_gtk_object_getprop): * ui-gtk.c (emacs_gtk_object_putprop): * ui-gtk.c (ui_gtk_objects_create): * unicode.c (compute_from_unicode_table_size_1): * unicode.c (compute_to_unicode_table_size_1): * unicode.c (compute_from_unicode_table_size): * unicode.c (compute_to_unicode_table_size): * window.c: * window.c (struct window_stats): * window.c (compute_window_mirror_usage): * window.c (compute_window_usage): * window.c (window_memory_usage): * window.c (window_objects_create): * window.c (syms_of_window): * window.c (vars_of_window): * window.h: Redo memory-usage mechanism, make it general; add way of dynamically initializing Lisp object types -- OBJECT_HAS_METHOD(), similar to CONSOLE_HAS_METHOD(). (1) Create OBJECT_HAS_METHOD(), OBJECT_HAS_PROPERTY() etc. for specifying that a Lisp object type has a particular method or property. Call such methods with OBJECT_METH, MAYBE_OBJECT_METH, OBJECT_METH_OR_GIVEN; retrieve properties with OBJECT_PROPERTY. Methods that formerly required a DEFINE_*GENERAL_LISP_OBJECT() to specify them (getprop, putprop, remprop, plist, disksave) now instead use the dynamic-method mechanism. The main benefit of this is that new methods or properties can be added without requiring that the declaration statements of all existing methods be modified. We have to make the `struct lrecord_implementation' non-const, but I don't think this should have any effect on speed -- the only possible method that's really speed-critical is the mark method, and we already extract those out into a separate (non-const) array for increased cache locality. Object methods need to be reinitialized after pdump, so we put them in separate functions such as face_objects_create(), extent_objects_create() and call them appropriately from emacs.c The only current object property (`memusage_stats_list') that objects can specify is a Lisp object and gets staticpro()ed so it only needs to be set during dump time, but because it references symbols that might not exist in a syms_of_() function, we initialize it in vars_of_(). There is also an object property (`num_extra_memusage_stats') that is automatically initialized based on `memusage_stats_list'; we do that in reinit_vars_of_alloc(), which is called after all vars_of_() functions are called. `disksaver' method was renamed `disksave' to correspond with the name normally given to the function (e.g. disksave_lstream()). (2) Generalize the memory-usage mechanism in `buffer-memory-usage', `window-memory-usage', `charset-memory-usage' into an object-type- specific mechanism called by a single function `object-memory-usage'. (Former function `object-memory-usage' renamed to `total-object-memory-usage'). Generalize the mechanism of different "slices" so that we can have different "classes" of memory described and different "slices" onto each class; `t' separates classes, `nil' separates slices. Currently we have three classes defined: the memory of an object itself, non-Lisp-object memory associated with the object (e.g. arrays or dynarrs stored as fields in the object), and Lisp-object memory associated with the object (other internal Lisp objects stored in the object). This isn't completely finished yet and we might need to further separate the "other internal Lisp objects" class into two classes. The memory-usage mechanism uses a `struct usage_stats' (renamed from `struct overhead_stats') to describe a malloc-view onto a set of allocated memory (listing how much was requested and various types of overhead) and a more general `struct generic_usage_stats' (with a `struct usage_stats' in it) to hold all statistics about object memory. `struct generic_usage_stats' contains an array of 32 Bytecounts, which are statistics of unspecified semantics. The intention is that individual types declare a corresponding struct (e.g. `struct window_stats') with the same structure but with specific fields in place of the array, corresponding to specific statistics. The number of such statistics is an object property computed from the list of tags (Lisp symbols describing the statistics) stored in `memusage_stats_list'. The idea here is to allow particular object types to customize the number and semantics of the statistics where completely avoiding consing. This doesn't matter so much yet, but the intention is to have the memory usage of all objects computed at the end of GC, at the same time as other statistics are currently computed. The values for all statistics for a single type would be added up to compute aggregate values for all objects of a specific type. To make this efficient, we can't allow any memory allocation at all. (3) Create some additional functions for creating lists that specify the elements directly as args rather than indirectly through an array: listn() (number of args given), listu() (list terminated by Qunbound). (4) Delete a bit of remaining unused C window_config stuff, also unused lrecord_type_popup_data.
author Ben Wing <ben@xemacs.org>
date Thu, 18 Mar 2010 10:50:06 -0500
parents 88bd4f3ef8e4
children 9e0b43d3095c
comparison
equal deleted inserted replaced
5156:6bff4f219697 5157:1fae11d56ad2
362 lrecord_type_console, 362 lrecord_type_console,
363 lrecord_type_device, 363 lrecord_type_device,
364 lrecord_type_frame, 364 lrecord_type_frame,
365 lrecord_type_window, 365 lrecord_type_window,
366 lrecord_type_window_mirror, 366 lrecord_type_window_mirror,
367 lrecord_type_window_configuration,
368 lrecord_type_gui_item, 367 lrecord_type_gui_item,
369 lrecord_type_popup_data,
370 lrecord_type_toolbar_button, 368 lrecord_type_toolbar_button,
371 lrecord_type_scrollbar_instance, 369 lrecord_type_scrollbar_instance,
372 lrecord_type_color_instance, 370 lrecord_type_color_instance,
373 lrecord_type_font_instance, 371 lrecord_type_font_instance,
374 lrecord_type_image_instance, 372 lrecord_type_image_instance,
488 Hashcode (*hash) (Lisp_Object, int); 486 Hashcode (*hash) (Lisp_Object, int);
489 487
490 /* Data layout description for your object. See long comment below. */ 488 /* Data layout description for your object. See long comment below. */
491 const struct memory_description *description; 489 const struct memory_description *description;
492 490
491 /* Only one of `static_size' and `size_in_bytes_method' is non-0. If
492 `static_size' is 0, this type is not instantiable by
493 ALLOC_NORMAL_LISP_OBJECT(). If both are 0 (this should never happen),
494 this object cannot be instantiated; you will get an abort() if you
495 try.*/
496 Bytecount static_size;
497 Bytecount (*size_in_bytes_method) (Lisp_Object);
498
499 /* The (constant) index into lrecord_implementations_table */
500 enum lrecord_type lrecord_type_index;
501
502 #ifndef NEW_GC
503 /* A "frob-block" lrecord is any lrecord that's not an lcrecord, i.e.
504 one that does not have an old_lcrecord_header at the front and which
505 is (usually) allocated in frob blocks. */
506 unsigned int frob_block_p :1;
507 #endif /* not NEW_GC */
508
509 /**********************************************************************/
510 /* Remaining stuff is not assignable statically using
511 DEFINE_*_LISP_OBJECT, but must be assigned with OBJECT_HAS_METHOD
512 or the like. */
513
493 /* These functions allow any object type to have builtin property 514 /* These functions allow any object type to have builtin property
494 lists that can be manipulated from the lisp level with 515 lists that can be manipulated from the lisp level with
495 `get', `put', `remprop', and `object-plist'. */ 516 `get', `put', `remprop', and `object-plist'. */
496 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); 517 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop);
497 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); 518 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val);
498 int (*remprop) (Lisp_Object obj, Lisp_Object prop); 519 int (*remprop) (Lisp_Object obj, Lisp_Object prop);
499 Lisp_Object (*plist) (Lisp_Object obj); 520 Lisp_Object (*plist) (Lisp_Object obj);
500 521
501 /* `disksaver' is called at dump time. It is used for objects that 522 /* `disksave' is called at dump time. It is used for objects that
502 contain pointers or handles to objects created in external libraries, 523 contain pointers or handles to objects created in external libraries,
503 such as window-system windows or file handles. Such external objects 524 such as window-system windows or file handles. Such external objects
504 cannot be dumped, so it is necessary to release them at dump time and 525 cannot be dumped, so it is necessary to release them at dump time and
505 arrange somehow or other for them to be resurrected if necessary later 526 arrange somehow or other for them to be resurrected if necessary later
506 on. 527 on.
507 528
508 It seems that even non-dumpable objects may be around at dump time, 529 It seems that even non-dumpable objects may be around at dump time,
509 and a disksaver may be provided. (In fact, the only object currently 530 and a disksave may be provided. (In fact, the only object currently
510 with a disksaver, lstream, is non-dumpable.) 531 with a disksave, lstream, is non-dumpable.)
511 532
512 Objects rarely need to provide this method; most of the time it will 533 Objects rarely need to provide this method; most of the time it will
513 be NULL. */ 534 be NULL. */
514 void (*disksaver) (Lisp_Object); 535 void (*disksave) (Lisp_Object);
515 536
516 /* Only one of `static_size' and `size_in_bytes_method' is non-0. If 537 #ifdef MEMORY_USAGE_STATS
517 `static_size' is 0, this type is not instantiable by 538 /* Return memory-usage information about the object in question, stored
518 ALLOC_NORMAL_LISP_OBJECT(). If both are 0 (this should never happen), 539 into STATS. */
519 this object cannot be instantiated; you will get an abort() if you 540 void (*memory_usage) (Lisp_Object obj, struct generic_usage_stats *stats);
520 try.*/ 541
521 Bytecount static_size; 542 /* Number of additional type-specific statistics related to memory usage.
522 Bytecount (*size_in_bytes_method) (Lisp_Object); 543 Automatically calculated (see compute_memusage_stats_length()) based
523 544 on the value placed in `memusage_stats_list'. */
524 /* The (constant) index into lrecord_implementations_table */ 545 Elemcount num_extra_memusage_stats;
525 enum lrecord_type lrecord_type_index; 546
526 547 /* List of tags to be given to the extra statistics, one per statistic.
527 #ifndef NEW_GC 548 Qnil or Qt can be present to separate off different slices. Qnil
528 /* A "frob-block" lrecord is any lrecord that's not an lcrecord, i.e. 549 separates different slices within the same type of statistics.
529 one that does not have an old_lcrecord_header at the front and which 550 Qt separates slices corresponding to different types of statistics.
530 is (usually) allocated in frob blocks. */ 551 If Qt is not present, all slices describe extra non-Lisp-Object memory
531 unsigned int frob_block_p :1; 552 associated with a Lisp object. If Qt is present, slices after Qt
532 #endif /* not NEW_GC */ 553 describe non-Lisp-Object memory and slices before Qt describe
554 Lisp-Object memory logically associated with the object. For example,
555 if the object is a table, then Lisp-Object memory might be the entries
556 in the table. This info is only advisory since it will duplicate
557 memory described elsewhere and since it may not be possible to be
558 completely accurate if the same object occurs multiple times in the
559 table. */
560 Lisp_Object memusage_stats_list;
561 #endif /* MEMORY_USAGE_STATS */
533 }; 562 };
534 563
535 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. 564 /* All the built-in lisp object types are enumerated in `enum lrecord_type'.
536 Additional ones may be defined by a module (none yet). We leave some 565 Additional ones may be defined by a module (none yet). We leave some
537 room in `lrecord_implementations_table' for such new lisp object types. */ 566 room in `lrecord_implementations_table' for such new lisp object types. */
538 #define MODULE_DEFINABLE_TYPE_COUNT 32 567 #define MODULE_DEFINABLE_TYPE_COUNT 32
539 568
540 extern MODULE_API const struct lrecord_implementation * 569 extern MODULE_API struct lrecord_implementation *
541 lrecord_implementations_table[lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT]; 570 lrecord_implementations_table[lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT];
542 571
543 /* Given a Lisp object, return its implementation 572 /* Given a Lisp object, return its implementation
544 (struct lrecord_implementation) */ 573 (struct lrecord_implementation) */
545 #define XRECORD_LHEADER_IMPLEMENTATION(obj) \ 574 #define XRECORD_LHEADER_IMPLEMENTATION(obj) \
591 if (XRECORD_LHEADER (MCACF_obj) && LRECORDP (MCACF_obj) \ 620 if (XRECORD_LHEADER (MCACF_obj) && LRECORDP (MCACF_obj) \
592 && !LRECORD_FREE_P (MCACF_lheader) ) \ 621 && !LRECORD_FREE_P (MCACF_lheader) ) \
593 { \ 622 { \
594 const struct lrecord_implementation *MCACF_implementation \ 623 const struct lrecord_implementation *MCACF_implementation \
595 = LHEADER_IMPLEMENTATION (MCACF_lheader); \ 624 = LHEADER_IMPLEMENTATION (MCACF_lheader); \
596 if (MCACF_implementation && MCACF_implementation->disksaver) \ 625 if (MCACF_implementation && MCACF_implementation->disksave) \
597 MCACF_implementation->disksaver (MCACF_obj); \ 626 MCACF_implementation->disksave (MCACF_obj); \
598 } \ 627 } \
599 } while (0) 628 } while (0)
600 629
601 #define LRECORD_FREE_P(ptr) \ 630 #define LRECORD_FREE_P(ptr) \
602 (((struct lrecord_header *) ptr)->free) 631 (((struct lrecord_header *) ptr)->free)
1269 object is internal and shouldn't be visible externally). For internal 1298 object is internal and shouldn't be visible externally). For internal
1270 objects needing a finalizer, equal or hash method, or wanting to 1299 objects needing a finalizer, equal or hash method, or wanting to
1271 customize the print method, use the normal DEFINE_*_LISP_OBJECT 1300 customize the print method, use the normal DEFINE_*_LISP_OBJECT
1272 mechanism for defining these objects. 1301 mechanism for defining these objects.
1273 1302
1274 DEFINE_*_GENERAL_LISP_OBJECT is for objects that need to provide one of
1275 the less common methods that are omitted on most objects. These methods
1276 include the methods supporting the unified property interface using
1277 `get', `put', `remprop' and `object-plist', and (for dumpable objects
1278 only) the `disksaver' method.
1279
1280 DEFINE_MODULE_* is for objects defined in an external module. 1303 DEFINE_MODULE_* is for objects defined in an external module.
1281 1304
1282 MAKE_LISP_OBJECT and MAKE_MODULE_LISP_OBJECT are what underlies all of 1305 MAKE_LISP_OBJECT and MAKE_MODULE_LISP_OBJECT are what underlies all of
1283 these; they define a structure containing pointers to object methods 1306 these; they define a structure containing pointers to object methods
1284 and other info such as the size of the structure containing the object. 1307 and other info such as the size of the structure containing the object.
1292 #endif 1315 #endif
1293 1316
1294 /********* The dumpable versions *********** */ 1317 /********* The dumpable versions *********** */
1295 1318
1296 #define DEFINE_DUMPABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ 1319 #define DEFINE_DUMPABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
1297 DEFINE_DUMPABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype) 1320 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,sizeof (structtype),0,0,structtype)
1298
1299 #define DEFINE_DUMPABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1300 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizeof (structtype),0,0,structtype)
1301 1321
1302 #define DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1322 #define DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1303 DEFINE_DUMPABLE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,structtype) 1323 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,0,sizer,0,structtype)
1304
1305 #define DEFINE_DUMPABLE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizer,structtype) \
1306 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,0,sizer,0,structtype)
1307 1324
1308 #define DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ 1325 #define DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
1309 DEFINE_DUMPABLE_FROB_BLOCK_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype) 1326 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,sizeof(structtype),0,1,structtype)
1310
1311 #define DEFINE_DUMPABLE_FROB_BLOCK_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1312 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizeof(structtype),0,1,structtype)
1313 1327
1314 #define DEFINE_DUMPABLE_FROB_BLOCK_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1328 #define DEFINE_DUMPABLE_FROB_BLOCK_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1315 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,0,sizer,1,structtype) 1329 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,0,sizer,1,structtype)
1316 1330
1317 #define DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,structtype) \ 1331 #define DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,structtype) \
1318 DEFINE_DUMPABLE_GENERAL_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,0,0,0,0,0,structtype) 1332 DEFINE_DUMPABLE_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,structtype)
1319 1333
1320 #define DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,sizer,structtype) \ 1334 #define DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,sizer,structtype) \
1321 DEFINE_DUMPABLE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,0,0,0,0,0,sizer,structtype) 1335 DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,sizer,structtype)
1322 1336
1323 /********* The non-dumpable versions *********** */ 1337 /********* The non-dumpable versions *********** */
1324 1338
1325 #define DEFINE_NODUMP_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ 1339 #define DEFINE_NODUMP_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
1326 DEFINE_NODUMP_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype) 1340 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,sizeof (structtype),0,0,structtype)
1327
1328 #define DEFINE_NODUMP_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1329 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizeof (structtype),0,0,structtype)
1330 1341
1331 #define DEFINE_NODUMP_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1342 #define DEFINE_NODUMP_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1332 DEFINE_NODUMP_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,structtype) 1343 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,0,sizer,0,structtype)
1333
1334 #define DEFINE_NODUMP_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizer,structtype) \
1335 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,0,sizer,0,structtype)
1336 1344
1337 #define DEFINE_NODUMP_FROB_BLOCK_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ 1345 #define DEFINE_NODUMP_FROB_BLOCK_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
1338 DEFINE_NODUMP_FROB_BLOCK_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype) 1346 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,sizeof(structtype),0,1,structtype)
1339
1340 #define DEFINE_NODUMP_FROB_BLOCK_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1341 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizeof(structtype),0,1,structtype)
1342 1347
1343 #define DEFINE_NODUMP_FROB_BLOCK_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1348 #define DEFINE_NODUMP_FROB_BLOCK_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1344 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,0,sizer,1,structtype) 1349 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,0,sizer,1,structtype)
1345 1350
1346 #define DEFINE_NODUMP_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,structtype) \ 1351 #define DEFINE_NODUMP_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,structtype) \
1347 DEFINE_NODUMP_GENERAL_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,0,0,0,0,0,structtype) 1352 DEFINE_NODUMP_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,structtype)
1348 1353
1349 #define DEFINE_NODUMP_SIZABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,sizer,structtype) \ 1354 #define DEFINE_NODUMP_SIZABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,sizer,structtype) \
1350 DEFINE_NODUMP_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,0,0,0,0,0,sizer,structtype) 1355 DEFINE_NODUMP_SIZABLE_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,sizer,structtype)
1351 1356
1352 /********* MAKE_LISP_OBJECT, the underlying macro *********** */ 1357 /********* MAKE_LISP_OBJECT, the underlying macro *********** */
1353 1358
1354 #ifdef NEW_GC 1359 #ifdef NEW_GC
1355 #define MAKE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,size,sizer,frob_block_p,structtype) \ 1360 #define MAKE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker, \
1361 equal,hash,desc,size,sizer,frob_block_p,structtype) \
1356 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ 1362 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
1357 const struct lrecord_implementation lrecord_##c_name = \ 1363 struct lrecord_implementation lrecord_##c_name = \
1358 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ 1364 { name, dumpable, marker, printer, nuker, equal, hash, desc, \
1359 getprop, putprop, remprop, plist, disksaver, size, sizer, \ 1365 size, sizer, lrecord_type_##c_name }
1360 lrecord_type_##c_name }
1361 #else /* not NEW_GC */ 1366 #else /* not NEW_GC */
1362 #define MAKE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,size,sizer,frob_block_p,structtype) \ 1367 #define MAKE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,size,sizer,frob_block_p,structtype) \
1363 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ 1368 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
1364 const struct lrecord_implementation lrecord_##c_name = \ 1369 struct lrecord_implementation lrecord_##c_name = \
1365 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ 1370 { name, dumpable, marker, printer, nuker, equal, hash, desc, \
1366 getprop, putprop, remprop, plist, disksaver, size, sizer, \ 1371 size, sizer, lrecord_type_##c_name, frob_block_p }
1367 lrecord_type_##c_name, frob_block_p }
1368 #endif /* not NEW_GC */ 1372 #endif /* not NEW_GC */
1369 1373
1370 1374
1371 /********* The module dumpable versions *********** */ 1375 /********* The module dumpable versions *********** */
1372 1376
1373 #define DEFINE_DUMPABLE_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ 1377 #define DEFINE_DUMPABLE_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \
1374 DEFINE_DUMPABLE_MODULE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype) 1378 MAKE_MODULE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,sizeof (structtype),0,0,structtype)
1375
1376 #define DEFINE_DUMPABLE_MODULE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1377 MAKE_MODULE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizeof (structtype),0,0,structtype)
1378 1379
1379 #define DEFINE_DUMPABLE_MODULE_SIZABLE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1380 #define DEFINE_DUMPABLE_MODULE_SIZABLE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1380 DEFINE_DUMPABLE_MODULE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,structtype) 1381 MAKE_MODULE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,0,sizer,0,structtype)
1381
1382 #define DEFINE_DUMPABLE_MODULE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizer,structtype) \
1383 MAKE_MODULE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,0,sizer,0,structtype)
1384 1382
1385 /********* The module non-dumpable versions *********** */ 1383 /********* The module non-dumpable versions *********** */
1386 1384
1387 #define DEFINE_NODUMP_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ 1385 #define DEFINE_NODUMP_MODULE_LISP_OBJECT(name,c_name,dumpable,marker, \
1388 DEFINE_NODUMP_MODULE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype) 1386 printer,nuker,equal,hash,desc,structtype) \
1389 1387 MAKE_MODULE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer, \
1390 #define DEFINE_NODUMP_MODULE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \ 1388 nuker,equal,hash,desc,sizeof (structtype),0,0,structtype)
1391 MAKE_MODULE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizeof (structtype),0,0,structtype) 1389
1392 1390 #define DEFINE_NODUMP_MODULE_SIZABLE_LISP_OBJECT(name,c_name,dumpable, \
1393 #define DEFINE_NODUMP_MODULE_SIZABLE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1391 marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1394 DEFINE_NODUMP_MODULE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,structtype) 1392 MAKE_MODULE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer, \
1395 1393 nuker,equal,hash,desc,0,sizer,0,structtype)
1396 #define DEFINE_NODUMP_MODULE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizer,structtype) \
1397 MAKE_MODULE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,0,sizer,0,structtype)
1398 1394
1399 /********* MAKE_MODULE_LISP_OBJECT, the underlying macro *********** */ 1395 /********* MAKE_MODULE_LISP_OBJECT, the underlying macro *********** */
1400 1396
1401 #ifdef NEW_GC 1397 #ifdef NEW_GC
1402 #define MAKE_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,size,sizer,frob_block_p,structtype) \ 1398 #define MAKE_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer, \
1399 nuker,equal,hash,desc,size,sizer,frob_block_p,structtype) \
1403 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ 1400 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
1404 int lrecord_type_##c_name; \ 1401 int lrecord_type_##c_name; \
1405 struct lrecord_implementation lrecord_##c_name = \ 1402 struct lrecord_implementation lrecord_##c_name = \
1406 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ 1403 { name, dumpable, marker, printer, nuker, equal, hash, desc, \
1407 getprop, putprop, remprop, plist, disksaver, size, sizer, \ 1404 size, sizer, lrecord_type_last_built_in_type }
1408 lrecord_type_last_built_in_type }
1409 #else /* not NEW_GC */ 1405 #else /* not NEW_GC */
1410 #define MAKE_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,size,sizer,frob_block_p,structtype) \ 1406 #define MAKE_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer, \
1407 nuker,equal,hash,desc,size,sizer,frob_block_p,structtype) \
1411 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ 1408 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
1412 int lrecord_type_##c_name; \ 1409 int lrecord_type_##c_name; \
1413 struct lrecord_implementation lrecord_##c_name = \ 1410 struct lrecord_implementation lrecord_##c_name = \
1414 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ 1411 { name, dumpable, marker, printer, nuker, equal, hash, desc, \
1415 getprop, putprop, remprop, plist, disksaver, size, sizer, \ 1412 size, sizer, lrecord_type_last_built_in_type, frob_block_p }
1416 lrecord_type_last_built_in_type, frob_block_p }
1417 #endif /* not NEW_GC */ 1413 #endif /* not NEW_GC */
1414
1415 #ifdef MEMORY_USAGE_STATS
1416 #define INIT_MEMORY_USAGE_STATS(type) \
1417 do \
1418 { \
1419 lrecord_implementations_table[lrecord_type_##type]-> \
1420 memusage_stats_list = Qnil; \
1421 lrecord_implementations_table[lrecord_type_##type]-> \
1422 num_extra_memusage_stats = -1; \
1423 staticpro (&lrecord_implementations_table[lrecord_type_##type]-> \
1424 memusage_stats_list); \
1425 } while (0)
1426 #else
1427 #define INIT_MEMORY_USAGE_STATS(type) DO_NOTHING
1428 #endif /* (not) MEMORY_USAGE_STATS */
1429
1430 #define INIT_LISP_OBJECT_BEGINNING(type) \
1431 do \
1432 { \
1433 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \
1434 INIT_MEMORY_USAGE_STATS (type); \
1435 } while (0)
1418 1436
1419 #ifdef USE_KKCC 1437 #ifdef USE_KKCC
1420 extern MODULE_API const struct memory_description *lrecord_memory_descriptions[]; 1438 extern MODULE_API const struct memory_description *lrecord_memory_descriptions[];
1421 1439
1422 #define INIT_LISP_OBJECT(type) do { \ 1440 #define INIT_LISP_OBJECT(type) do { \
1423 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ 1441 INIT_LISP_OBJECT_BEGINNING (type); \
1424 lrecord_memory_descriptions[lrecord_type_##type] = \ 1442 lrecord_memory_descriptions[lrecord_type_##type] = \
1425 lrecord_implementations_table[lrecord_type_##type]->description; \ 1443 lrecord_implementations_table[lrecord_type_##type]->description; \
1426 } while (0) 1444 } while (0)
1427 #else /* not USE_KKCC */ 1445 #else /* not USE_KKCC */
1428 extern MODULE_API Lisp_Object (*lrecord_markers[]) (Lisp_Object); 1446 extern MODULE_API Lisp_Object (*lrecord_markers[]) (Lisp_Object);
1429 1447
1430 #define INIT_LISP_OBJECT(type) do { \ 1448 #define INIT_LISP_OBJECT(type) do { \
1431 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ 1449 INIT_LISP_OBJECT_BEGINNING (type); \
1432 lrecord_markers[lrecord_type_##type] = \ 1450 lrecord_markers[lrecord_type_##type] = \
1433 lrecord_implementations_table[lrecord_type_##type]->marker; \ 1451 lrecord_implementations_table[lrecord_type_##type]->marker; \
1434 } while (0) 1452 } while (0)
1435 #endif /* not USE_KKCC */ 1453 #endif /* not USE_KKCC */
1436 1454
1437 #define INIT_MODULE_LISP_OBJECT(type) do { \ 1455 #define INIT_MODULE_LISP_OBJECT(type) do { \
1438 lrecord_type_##type = lrecord_type_count++; \ 1456 lrecord_type_##type = lrecord_type_count++; \
1439 lrecord_##type.lrecord_type_index = lrecord_type_##type; \ 1457 lrecord_##type.lrecord_type_index = lrecord_type_##type; \
1440 INIT_LISP_OBJECT(type); \ 1458 INIT_LISP_OBJECT (type); \
1441 } while (0) 1459 } while (0)
1442 1460
1443 #ifdef HAVE_SHLIB 1461 #ifdef HAVE_SHLIB
1444 /* Allow undefining types in order to support module unloading. */ 1462 /* Allow undefining types in order to support module unloading. */
1445 1463
1446 #ifdef USE_KKCC 1464 #ifdef USE_KKCC
1447 #define UNDEF_LISP_OBJECT(type) do { \ 1465 #define UNDEF_LISP_OBJECT(type) do { \
1448 lrecord_implementations_table[lrecord_type_##type] = NULL; \ 1466 lrecord_implementations_table[lrecord_type_##type] = NULL; \
1449 lrecord_memory_descriptions[lrecord_type_##type] = NULL; \ 1467 lrecord_memory_descriptions[lrecord_type_##type] = NULL; \
1450 } while (0) 1468 } while (0)
1451 #else /* not USE_KKCC */ 1469 #else /* not USE_KKCC */
1452 #define UNDEF_LISP_OBJECT(type) do { \ 1470 #define UNDEF_LISP_OBJECT(type) do { \
1453 lrecord_implementations_table[lrecord_type_##type] = NULL; \ 1471 lrecord_implementations_table[lrecord_type_##type] = NULL; \
1454 lrecord_markers[lrecord_type_##type] = NULL; \ 1472 lrecord_markers[lrecord_type_##type] = NULL; \
1455 } while (0) 1473 } while (0)
1456 #endif /* not USE_KKCC */ 1474 #endif /* not USE_KKCC */
1457 1475
1458 #define UNDEF_MODULE_LISP_OBJECT(type) do { \ 1476 #define UNDEF_MODULE_LISP_OBJECT(type) do { \
1459 if (lrecord_##type.lrecord_type_index == lrecord_type_count - 1) { \ 1477 if (lrecord_##type.lrecord_type_index == lrecord_type_count - 1) { \
1460 /* This is the most recently defined type. Clean up nicely. */ \ 1478 /* This is the most recently defined type. Clean up nicely. */ \
1461 lrecord_type_##type = lrecord_type_count--; \ 1479 lrecord_type_##type = lrecord_type_count--; \
1462 } /* Else we can't help leaving a hole with this implementation. */ \ 1480 } /* Else we can't help leaving a hole with this implementation. */ \
1463 UNDEF_LISP_OBJECT(type); \ 1481 UNDEF_LISP_OBJECT(type); \
1464 } while (0) 1482 } while (0)
1465 1483
1466 #endif /* HAVE_SHLIB */ 1484 #endif /* HAVE_SHLIB */
1485
1486 /*************** Macros for declaring that a Lisp object has a
1487 particular method, or for calling such a method. ********/
1488
1489 /* Declare that object-type TYPE has method M; used in
1490 initialization routines */
1491 #define OBJECT_HAS_METHOD(type, m) \
1492 (lrecord_##type.m = type##_##m)
1493 /* Same but the method name come before the type */
1494 #define OBJECT_HAS_PREMETHOD(type, m) \
1495 (lrecord_##type.m = m##_##type)
1496 /* Same but the name of the method is explicitly given */
1497 #define OBJECT_HAS_NAMED_METHOD(type, m, func) \
1498 (lrecord_##type.m = (func))
1499 /* Object type has a property with the given value. */
1500 #define OBJECT_HAS_PROPERTY(type, prop, val) \
1501 (lrecord_##type.prop = (val))
1502
1503 /* Does the given object method exist? */
1504 #define HAS_OBJECT_METH_P(obj, m) \
1505 (!!(XRECORD_LHEADER_IMPLEMENTATION (obj)->m))
1506 /* Call an object method. */
1507 #define OBJECT_METH(obj, m, args) \
1508 ((XRECORD_LHEADER_IMPLEMENTATION (obj)->m) args)
1509
1510 /* Call an object method, if it exists. */
1511 #define MAYBE_OBJECT_METH(obj, m, args) \
1512 do \
1513 { \
1514 const struct lrecord_implementation *_mom_imp = \
1515 XRECORD_LHEADER_IMPLEMENTATION (obj); \
1516 if (_mom_imp->m) \
1517 ((_mom_imp->m) args); \
1518 } while (0)
1519
1520 /* Call an object method, if it exists, or return GIVEN. NOTE:
1521 Multiply-evaluates OBJ. */
1522 #define OBJECT_METH_OR_GIVEN(obj, m, args, given) \
1523 (HAS_OBJECT_METH_P (obj, m) ? OBJECT_METH (obj, m, args) : (given))
1524
1525 #define OBJECT_PROPERTY(obj, prop) (XRECORD_LHEADER_IMPLEMENTATION (obj)->prop)
1526
1527 /************** Other stuff **************/
1467 1528
1468 #define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record) 1529 #define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record)
1469 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a)) 1530 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a))
1470 1531
1471 #define RECORD_TYPEP(x, ty) \ 1532 #define RECORD_TYPEP(x, ty) \
1673 */ 1734 */
1674 1735
1675 1736
1676 #ifdef ERROR_CHECK_TYPES 1737 #ifdef ERROR_CHECK_TYPES
1677 1738
1678 # define DECLARE_LISP_OBJECT(c_name, structtype) \ 1739 # define DECLARE_LISP_OBJECT(c_name, structtype) \
1679 extern const struct lrecord_implementation lrecord_##c_name; \ 1740 extern struct lrecord_implementation lrecord_##c_name; \
1680 DECLARE_INLINE_HEADER ( \ 1741 DECLARE_INLINE_HEADER ( \
1681 structtype * \ 1742 structtype * \
1682 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1743 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1683 ) \ 1744 ) \
1684 { \ 1745 { \
1685 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1746 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1686 return (structtype *) XPNTR (obj); \ 1747 return (structtype *) XPNTR (obj); \
1687 } \ 1748 } \
1688 extern Lisp_Object Q##c_name##p 1749 extern Lisp_Object Q##c_name##p
1689 1750
1690 # define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \ 1751 # define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \
1691 extern MODULE_API const struct lrecord_implementation lrecord_##c_name; \ 1752 extern MODULE_API struct lrecord_implementation lrecord_##c_name; \
1692 DECLARE_INLINE_HEADER ( \ 1753 DECLARE_INLINE_HEADER ( \
1693 structtype * \ 1754 structtype * \
1694 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1755 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1695 ) \ 1756 ) \
1696 { \ 1757 { \
1697 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1758 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1698 return (structtype *) XPNTR (obj); \ 1759 return (structtype *) XPNTR (obj); \
1699 } \ 1760 } \
1700 extern MODULE_API Lisp_Object Q##c_name##p 1761 extern MODULE_API Lisp_Object Q##c_name##p
1701 1762
1702 # define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \ 1763 # define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \
1703 extern int lrecord_type_##c_name; \ 1764 extern int lrecord_type_##c_name; \
1704 extern struct lrecord_implementation lrecord_##c_name; \ 1765 extern struct lrecord_implementation lrecord_##c_name; \
1705 DECLARE_INLINE_HEADER ( \ 1766 DECLARE_INLINE_HEADER ( \
1706 structtype * \ 1767 structtype * \
1707 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1768 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1708 ) \ 1769 ) \
1709 { \ 1770 { \
1710 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1771 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1711 return (structtype *) XPNTR (obj); \ 1772 return (structtype *) XPNTR (obj); \
1712 } \ 1773 } \
1713 extern Lisp_Object Q##c_name##p 1774 extern Lisp_Object Q##c_name##p
1714 1775
1715 # define XRECORD(x, c_name, structtype) \ 1776 # define XRECORD(x, c_name, structtype) \
1716 error_check_##c_name (x, __FILE__, __LINE__) 1777 error_check_##c_name (x, __FILE__, __LINE__)
1717 1778
1732 1793
1733 #else /* not ERROR_CHECK_TYPES */ 1794 #else /* not ERROR_CHECK_TYPES */
1734 1795
1735 # define DECLARE_LISP_OBJECT(c_name, structtype) \ 1796 # define DECLARE_LISP_OBJECT(c_name, structtype) \
1736 extern Lisp_Object Q##c_name##p; \ 1797 extern Lisp_Object Q##c_name##p; \
1737 extern const struct lrecord_implementation lrecord_##c_name 1798 extern struct lrecord_implementation lrecord_##c_name
1738 # define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \ 1799 # define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \
1739 extern MODULE_API Lisp_Object Q##c_name##p; \ 1800 extern MODULE_API Lisp_Object Q##c_name##p; \
1740 extern MODULE_API const struct lrecord_implementation lrecord_##c_name 1801 extern MODULE_API struct lrecord_implementation lrecord_##c_name
1741 # define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \ 1802 # define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \
1742 extern Lisp_Object Q##c_name##p; \ 1803 extern Lisp_Object Q##c_name##p; \
1743 extern int lrecord_type_##c_name; \ 1804 extern int lrecord_type_##c_name; \
1744 extern struct lrecord_implementation lrecord_##c_name 1805 extern struct lrecord_implementation lrecord_##c_name
1745 # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x)) 1806 # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x))
1946 ) 2007 )
1947 { 2008 {
1948 return detagged_lisp_object_size (XRECORD_LHEADER (o)); 2009 return detagged_lisp_object_size (XRECORD_LHEADER (o));
1949 } 2010 }
1950 2011
1951 struct overhead_stats; 2012 struct usage_stats;
1952 2013
1953 MODULE_API void copy_lisp_object (Lisp_Object dst, Lisp_Object src); 2014 MODULE_API void copy_lisp_object (Lisp_Object dst, Lisp_Object src);
1954 MODULE_API void zero_sized_lisp_object (Lisp_Object obj, Bytecount size); 2015 MODULE_API void zero_sized_lisp_object (Lisp_Object obj, Bytecount size);
1955 MODULE_API void zero_nonsized_lisp_object (Lisp_Object obj); 2016 MODULE_API void zero_nonsized_lisp_object (Lisp_Object obj);
1956 #ifdef MEMORY_USAGE_STATS 2017 #ifdef MEMORY_USAGE_STATS
1957 Bytecount lisp_object_storage_size (Lisp_Object obj, 2018 Bytecount lisp_object_storage_size (Lisp_Object obj,
1958 struct overhead_stats *ovstats); 2019 struct usage_stats *ustats);
1959 #endif /* MEMORY_USAGE_STATS */ 2020 #endif /* MEMORY_USAGE_STATS */
1960 void free_normal_lisp_object (Lisp_Object obj); 2021 void free_normal_lisp_object (Lisp_Object obj);
1961 2022
1962 2023
1963 /************************************************************************/ 2024 /************************************************************************/