comparison src/lrecord.h @ 5133:444a448b2f53

Merge branch ben-lisp-object into default branch
author Ben Wing <ben@xemacs.org>
date Sun, 07 Mar 2010 06:47:37 -0600
parents 7be849cb8828
children f965e31a35f0
comparison
equal deleted inserted replaced
5113:b2dcf6a6d8ab 5133:444a448b2f53
1 /* The "lrecord" structure (header of a compound lisp object). 1 /* The "lrecord" structure (header of a compound lisp object).
2 Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. 2 Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
3 Copyright (C) 1996, 2001, 2002, 2004, 2005, 2010 Ben Wing. 3 Copyright (C) 1996, 2001, 2002, 2004, 2005, 2009, 2010 Ben Wing.
4 4
5 This file is part of XEmacs. 5 This file is part of XEmacs.
6 6
7 XEmacs is free software; you can redistribute it and/or modify it 7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
24 /* This file has been Mule-ized, Ben Wing, 10-13-04. */ 24 /* This file has been Mule-ized, Ben Wing, 10-13-04. */
25 25
26 #ifndef INCLUDED_lrecord_h_ 26 #ifndef INCLUDED_lrecord_h_
27 #define INCLUDED_lrecord_h_ 27 #define INCLUDED_lrecord_h_
28 28
29 /* The "lrecord" type of Lisp object is used for all object types other 29 /* All objects other than char and int are implemented as structures and
30 than a few simple ones (like char and int). This allows many types to be 30 passed by reference. Such objects are called "record objects" ("record"
31 implemented but only a few bits required in a Lisp object for type 31 is another term for "structure"). The "wrapped" value of such an object
32 information. (The tradeoff is that each object has its type marked in 32 (i.e. when stored in a variable of type Lisp_Object) is simply the raw
33 it, thereby increasing its size.) All lrecords begin with a `struct 33 pointer coerced to an integral type the same size as the pointer
34 lrecord_header', which identifies the lisp object type, by providing an 34 (usually `long').
35 index into a table of `struct lrecord_implementation', which describes 35
36 the behavior of the lisp object. It also contains some other data bits. 36 Under old-GC (i.e. when NEW_GC is not defined), there are two kinds of
37 37 record objects: normal objects (those allocated on their own with
38 #ifndef NEW_GC 38 xmalloc()) and frob-block objects (those allocated as pieces of large,
39 Lrecords are of two types: straight lrecords, and lcrecords. 39 usually 2K, chunks of memory known as "frob blocks"). Under NEW_GC,
40 Straight lrecords are used for those types of objects that have 40 there is only one type of record object. Stuff below that applies to
41 their own allocation routines (typically allocated out of 2K chunks 41 frob-block objects is assumed to apply to the same type of object as
42 of memory called `frob blocks'). These objects have a `struct 42 normal objects under NEW_GC.
43 lrecord_header' at the top, containing only the bits needed to find 43
44 the lrecord_implementation for the object. There are special 44 Record objects have a header at the beginning of their structure, which
45 routines in alloc.c to create an object of each such type. 45 is used internally to identify the type of the object (so that an
46 46 object's type can be recovered from its pointer); in addition, it holds
47 Lcrecords are used for less common sorts of objects that don't do 47 a few flags and a "UID", which for most objects is shown when it is
48 their own allocation. Each such object is malloc()ed individually, 48 printed, and is primarily useful for debugging purposes. The header of
49 and the objects are chained together through a `next' pointer. 49 a normal object is declared as NORMAL_LISP_OBJECT_HEADER and that of a
50 Lcrecords have a `struct old_lcrecord_header' at the top, which 50 frob-block object FROB_BLOCK_LISP_OBJECT_HEADER.
51 contains a `struct lrecord_header' and a `next' pointer, and are 51
52 allocated using old_alloc_lcrecord_type() or its variants. 52 FROB_BLOCK_LISP_OBJECT_HEADER boils down to a `struct lrecord_header'.
53 #endif 53 This is a 32-bit value made up of bit fields, where 8 bits are used to
54 54 hold the type, 2 or 3 bits are used for flags associated with the
55 Creating a new Lisp object type is fairly easy; just follow the 55 garbage collector, and the remaining 21 or 22 bits hold the UID.
56 lead of some existing type (e.g. hash tables). Note that you 56
57 do not need to supply all the methods (see below); reasonable 57 Under NEW_GC, NORMAL_LISP_OBJECT_HEADER also resolves to `struct
58 defaults are provided for many of them. Alternatively, if you're 58 lrecord_header'. Under old-GC, however, NORMAL_LISP_OBJECT_HEADER
59 just looking for a way of encapsulating data (which possibly 59 resolves to a `struct old_lcrecord_header' (note the `c'), which is a
60 could contain Lisp_Objects in it), you may well be able to use 60 larger structure -- on 32-bit machines it occupies 3 machine words
61 the opaque type. 61 instead of 1. Such an object is known internally as an "lcrecord". The
62 first word of `struct old_lcrecord_header' is an embedded `struct
63 lrecord_header' with the same information as for frob-block objects;
64 that way, all objects can be cast to a `struct lrecord_header' to
65 determine their type or other info. The other words consist of a
66 pointer, used to thread all lcrecords together in one big linked list,
67 and a 32-bit structure that contains another UID field (#### which
68 should be deleted, as it is redundant; it dates back to the days when
69 the lrecord_header consisted of a pointer to an object's implementation
70 structure rather than an index).
71
72 Under old-GC, normal objects (i.e. lcrecords) are allocated in
73 individual chunks using the underlying allocator (i.e. xmalloc(), which
74 is a thin wrapper around malloc()). Frob-block objects are more
75 efficient than normal objects, as they have a smaller header and don't
76 have the additional memory overhead associated with malloc() -- instead,
77 as mentioned above, they are carved out of 2K chunks of memory called
78 "frob blocks"). However, it is slightly more tricky to create such
79 objects, as they require special routines in alloc.c to create an object
80 of each such type and to sweep them during garbage collection. In
81 addition, there is currently no mechanism for handling variable-sized
82 frob-block objects (e.g. vectors), whereas variable-sized normal objects
83 are not a problem. Frob-block objects are typically used for basic
84 objects that exist in large numbers, such as `cons' or `string'.
85
86 Note that strings are an apparent exception to the statement above that
87 variable-sized objects can't be handled. Under old-GC strings work as
88 follows. A string consists of two parts -- a fixed-size "string header"
89 that is allocated as a standard frob-block object, and a "string-chars"
90 structure that is allocated out of special 8K-sized frob blocks that
91 have a dedicated garbage-collection handler that compacts the blocks
92 during the sweep stage, relocating the string-chars data (but not the
93 string headers) to eliminate gaps. Strings larger than 8K are not
94 placed in frob blocks, but instead are stored as individually malloc()ed
95 blocks of memory. Strings larger than 8K are called "big strings" and
96 those smaller than 8K are called "small strings".
97
98 Under new-GC, there is no difference between big and small strings,
99 just as there is no difference between normal and frob-block objects.
100 There is only one allocation method, which is capable of handling
101 variable-sized objects. This apparently allocates all objects in
102 frob blocks according to the size of the object.
103
104 To create a new normal Lisp object, see the toolbar-button example
105 below. To create a new frob-block Lisp object, follow the lead of
106 one of the existing frob-block objects, such as extents or events.
107 Note that you do not need to supply all the methods (see below);
108 reasonable defaults are provided for many of them. Alternatively, if
109 you're just looking for a way of encapsulating data (which possibly
110 could contain Lisp_Objects in it), you may well be able to use the
111 opaque type.
62 */ 112 */
113
114 /*
115 How to declare a Lisp object:
116
117 NORMAL_LISP_OBJECT_HEADER:
118 Header for normal objects
119
120 FROB_BLOCK_LISP_OBJECT_HEADER:
121 Header for frob-block objects
122
123 How to allocate a Lisp object:
124
125 - For normal objects of a fixed size, simply call
126 ALLOC_NORMAL_LISP_OBJECT (type), where TYPE is the name of the type
127 (e.g. toolbar_button). Such objects can be freed manually using
128 free_normal_lisp_object.
129
130 - For normal objects whose size can vary (and hence which have a
131 size_in_bytes_method rather than a static_size), call
132 ALLOC_SIZED_LISP_OBJECT (size, type), where TYPE is the
133 name of the type. NOTE: You cannot call free_normal_lisp_object() on such
134 on object! (At least when not NEW_GC)
135
136 - For frob-block objects, use
137 ALLOC_FROB_BLOCK_LISP_OBJECT (type, lisp_type, var, lrec_ptr).
138 But these objects need special handling; if you don't understand this,
139 just ignore it.
140
141 - Some lrecords, which are used totally internally, use the
142 noseeum-* functions for debugging reasons.
143
144 Other operations:
145
146 - copy_lisp_object (dst, src)
147
148 - zero_nonsized_lisp_object (obj), zero_sized_lisp_object (obj, size):
149 BUT NOTE, it is not necessary to zero out newly allocated Lisp objects.
150 This happens automatically.
151
152 - lisp_object_size (obj): Return the size of a Lisp object. NOTE: This
153 requires that the object is properly initialized.
154
155 - lisp_object_storage_size (obj, stats): Return the storage size of a
156 Lisp objcet, including malloc or frob-block overhead; also, if STATS
157 is non-NULL, accumulate info about the size and overhead into STATS.
158 */
63 159
64 #ifdef NEW_GC 160 #ifdef NEW_GC
65 /* 161 /*
66 There are some limitations under New-GC that lead to the creation of a 162 There are some limitations under New-GC that lead to the creation of a
67 large number of new internal object types. I'm not completely sure what 163 large number of new internal object types. I'm not completely sure what
72 It must have something to do with the fact that these substructures 168 It must have something to do with the fact that these substructures
73 contain pointers to Lisp objects, but it's not completely clear why -- 169 contain pointers to Lisp objects, but it's not completely clear why --
74 object descriptions exist to indicate the size of these structures and 170 object descriptions exist to indicate the size of these structures and
75 the Lisp object pointers within them. 171 the Lisp object pointers within them.
76 172
77 At least one definite issue is that under New-GC dumpable objects cannot 173 At least one definite issue is that under New-GC dumpable objects cannot
78 contain any finalizers (see pdump_register_object()). This means that any 174 contain any finalizers (see pdump_register_object()). This means that
79 substructures in dumpable objects that are allocated separately and 175 any substructures in dumpable objects that are allocated separately and
80 normally freed in a finalizer need instead to be made into actual Lisp 176 normally freed in a finalizer need instead to be made into actual Lisp
81 objects. If those structures are Dynarrs, they need to be made into 177 objects. If those structures are Dynarrs, they need to be made into
82 Dynarr Lisp objects (e.g. face-cachel-dynarr or glyph-cachel-dynarr), 178 Dynarr Lisp objects (e.g. face-cachel-dynarr or glyph-cachel-dynarr),
83 which are created using Dynarr_lisp_new() or Dynarr_new_new2(). 179 which are created using Dynarr_lisp_new() or Dynarr_new_new2().
84 Furthermore, the objects contained in the Dynarr also need to be Lisp 180 Furthermore, the objects contained in the Dynarr also need to be Lisp
85 objects (e.g. face-cachel or glyph-cachel). 181 objects (e.g. face-cachel or glyph-cachel).
86 182
87 --ben 183 --ben
88 */ 184 */
89
90 #endif 185 #endif
91 186
92
93
94 #ifdef NEW_GC 187 #ifdef NEW_GC
95 #define ALLOC_LCRECORD_TYPE alloc_lrecord_type 188 #define ALLOC_NORMAL_LISP_OBJECT(type) alloc_lrecord (&lrecord_##type)
96 #define COPY_SIZED_LCRECORD copy_sized_lrecord 189 #define ALLOC_SIZED_LISP_OBJECT(size, type) \
97 #define COPY_LCRECORD copy_lrecord 190 alloc_sized_lrecord (size, &lrecord_##type)
98 #define LISPOBJ_STORAGE_SIZE(ptr, size, stats) \ 191 #define NORMAL_LISP_OBJECT_HEADER struct lrecord_header
99 mc_alloced_storage_size (size, stats) 192 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header
100 #define ZERO_LCRECORD zero_lrecord 193 #define LISP_OBJECT_FROB_BLOCK_P(obj) 0
101 #define LCRECORD_HEADER lrecord_header
102 #define BASIC_ALLOC_LCRECORD alloc_lrecord
103 #define FREE_LCRECORD free_lrecord
104 #else /* not NEW_GC */ 194 #else /* not NEW_GC */
105 #define ALLOC_LCRECORD_TYPE old_alloc_lcrecord_type 195 #define ALLOC_NORMAL_LISP_OBJECT(type) alloc_automanaged_lcrecord (&lrecord_##type)
106 #define COPY_SIZED_LCRECORD old_copy_sized_lcrecord 196 #define ALLOC_SIZED_LISP_OBJECT(size, type) \
107 #define COPY_LCRECORD old_copy_lcrecord 197 old_alloc_sized_lcrecord (size, &lrecord_##type)
108 #define LISPOBJ_STORAGE_SIZE malloced_storage_size 198 #define NORMAL_LISP_OBJECT_HEADER struct old_lcrecord_header
109 #define ZERO_LCRECORD old_zero_lcrecord 199 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header
110 #define LCRECORD_HEADER old_lcrecord_header 200 #define LISP_OBJECT_FROB_BLOCK_P(obj) (XRECORD_LHEADER_IMPLEMENTATION(obj)->frob_block_p)
111 #define BASIC_ALLOC_LCRECORD old_basic_alloc_lcrecord
112 #define FREE_LCRECORD old_free_lcrecord
113 #endif /* not NEW_GC */ 201 #endif /* not NEW_GC */
114 202
115 BEGIN_C_DECLS 203 BEGIN_C_DECLS
116 204
117 struct lrecord_header 205 struct lrecord_header
186 { 274 {
187 struct lrecord_header lheader; 275 struct lrecord_header lheader;
188 276
189 /* The `next' field is normally used to chain all lcrecords together 277 /* The `next' field is normally used to chain all lcrecords together
190 so that the GC can find (and free) all of them. 278 so that the GC can find (and free) all of them.
191 `old_basic_alloc_lcrecord' threads lcrecords together. 279 `old_alloc_sized_lcrecord' threads lcrecords together.
192 280
193 The `next' field may be used for other purposes as long as some 281 The `next' field may be used for other purposes as long as some
194 other mechanism is provided for letting the GC do its work. 282 other mechanism is provided for letting the GC do its work.
195 283
196 For example, the event and marker object types allocate members 284 For example, the event and marker object types allocate members
374 description below instead), unless the data description is missing. 462 description below instead), unless the data description is missing.
375 Yes, this currently means there is logic duplication. Eventually the 463 Yes, this currently means there is logic duplication. Eventually the
376 mark methods will be removed. */ 464 mark methods will be removed. */
377 Lisp_Object (*marker) (Lisp_Object); 465 Lisp_Object (*marker) (Lisp_Object);
378 466
379 /* `printer' converts the object to a printed representation. 467 /* `printer' converts the object to a printed representation. `printer'
380 This can be NULL; in this case default_object_printer() will be 468 should never be NULL (if so, you will get an assertion failure when
381 used instead. */ 469 trying to print such an object). Either supply a specific printing
470 method, or use the default methods internal_object_printer() (for
471 internal objects that should not be visible at Lisp level) or
472 external_object_printer() (for objects visible at Lisp level). */
382 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag); 473 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag);
383 474
384 /* `finalizer' is called at GC time when the object is about to be freed, 475 /* `finalizer' is called at GC time when the object is about to be freed.
385 and at dump time (FOR_DISKSAVE will be non-zero in this case). It 476 It should perform any necessary cleanup, such as freeing malloc()ed
386 should perform any necessary cleanup (e.g. freeing malloc()ed memory 477 memory or releasing pointers or handles to objects created in external
387 or releasing objects created in external libraries, such as 478 libraries, such as window-system windows or file handles. This can be
388 window-system windows or file handles). This can be NULL, meaning no 479 NULL, meaning no special finalization is necessary. */
389 special finalization is necessary. 480 void (*finalizer) (Lisp_Object obj);
390
391 WARNING: remember that `finalizer' is called at dump time even though
392 the object is not being freed -- check the FOR_DISKSAVE argument. */
393 void (*finalizer) (void *header, int for_disksave);
394 481
395 /* This can be NULL, meaning compare objects with EQ(). */ 482 /* This can be NULL, meaning compare objects with EQ(). */
396 int (*equal) (Lisp_Object obj1, Lisp_Object obj2, int depth, 483 int (*equal) (Lisp_Object obj1, Lisp_Object obj2, int depth,
397 int foldcase); 484 int foldcase);
398 485
414 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); 501 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop);
415 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); 502 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val);
416 int (*remprop) (Lisp_Object obj, Lisp_Object prop); 503 int (*remprop) (Lisp_Object obj, Lisp_Object prop);
417 Lisp_Object (*plist) (Lisp_Object obj); 504 Lisp_Object (*plist) (Lisp_Object obj);
418 505
419 #ifdef NEW_GC 506 /* `disksaver' is called at dump time. It is used for objects that
420 /* Only one of `static_size' and `size_in_bytes_method' is non-0. */ 507 contain pointers or handles to objects created in external libraries,
421 #else /* not NEW_GC */ 508 such as window-system windows or file handles. Such external objects
422 /* Only one of `static_size' and `size_in_bytes_method' is non-0. 509 cannot be dumped, so it is necessary to release them at dump time and
423 If both are 0, this type is not instantiable by 510 arrange somehow or other for them to be resurrected if necessary later
424 old_basic_alloc_lcrecord(). */ 511 on.
425 #endif /* not NEW_GC */ 512
513 It seems that even non-dumpable objects may be around at dump time,
514 and a disksaver may be provided. (In fact, the only object currently
515 with a disksaver, lstream, is non-dumpable.)
516
517 Objects rarely need to provide this method; most of the time it will
518 be NULL. */
519 void (*disksaver) (Lisp_Object);
520
521 /* Only one of `static_size' and `size_in_bytes_method' is non-0. If
522 `static_size' is 0, this type is not instantiable by
523 ALLOC_NORMAL_LISP_OBJECT(). If both are 0 (this should never happen),
524 this object cannot be instantiated; you will get an abort() if you
525 try.*/
426 Bytecount static_size; 526 Bytecount static_size;
427 Bytecount (*size_in_bytes_method) (const void *header); 527 Bytecount (*size_in_bytes_method) (Lisp_Object);
428 528
429 /* The (constant) index into lrecord_implementations_table */ 529 /* The (constant) index into lrecord_implementations_table */
430 enum lrecord_type lrecord_type_index; 530 enum lrecord_type lrecord_type_index;
431 531
432 #ifndef NEW_GC 532 #ifndef NEW_GC
433 /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e. 533 /* A "frob-block" lrecord is any lrecord that's not an lcrecord, i.e.
434 one that does not have an old_lcrecord_header at the front and which 534 one that does not have an old_lcrecord_header at the front and which
435 is (usually) allocated in frob blocks. */ 535 is (usually) allocated in frob blocks. */
436 unsigned int basic_p :1; 536 unsigned int frob_block_p :1;
437 #endif /* not NEW_GC */ 537 #endif /* not NEW_GC */
438 }; 538 };
439 539
440 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. 540 /* All the built-in lisp object types are enumerated in `enum lrecord_type'.
441 Additional ones may be defined by a module (none yet). We leave some 541 Additional ones may be defined by a module (none yet). We leave some
443 #define MODULE_DEFINABLE_TYPE_COUNT 32 543 #define MODULE_DEFINABLE_TYPE_COUNT 32
444 544
445 extern MODULE_API const struct lrecord_implementation * 545 extern MODULE_API const struct lrecord_implementation *
446 lrecord_implementations_table[lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT]; 546 lrecord_implementations_table[lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT];
447 547
548 /* Given a Lisp object, return its implementation
549 (struct lrecord_implementation) */
448 #define XRECORD_LHEADER_IMPLEMENTATION(obj) \ 550 #define XRECORD_LHEADER_IMPLEMENTATION(obj) \
449 LHEADER_IMPLEMENTATION (XRECORD_LHEADER (obj)) 551 LHEADER_IMPLEMENTATION (XRECORD_LHEADER (obj))
450 #define LHEADER_IMPLEMENTATION(lh) lrecord_implementations_table[(lh)->type] 552 #define LHEADER_IMPLEMENTATION(lh) lrecord_implementations_table[(lh)->type]
451 553
452 #include "gc.h" 554 #include "gc.h"
479 const struct lrecord_implementation *MCACF_implementation \ 581 const struct lrecord_implementation *MCACF_implementation \
480 = LHEADER_IMPLEMENTATION (MCACF_lheader); \ 582 = LHEADER_IMPLEMENTATION (MCACF_lheader); \
481 if (MCACF_implementation && MCACF_implementation->finalizer) \ 583 if (MCACF_implementation && MCACF_implementation->finalizer) \
482 { \ 584 { \
483 GC_STAT_FINALIZED; \ 585 GC_STAT_FINALIZED; \
484 MCACF_implementation->finalizer (ptr, 0); \ 586 MCACF_implementation->finalizer (MCACF_obj); \
485 } \ 587 } \
486 } \ 588 } \
487 } while (0) 589 } while (0)
488 590
489 /* Tell mc-alloc how to call a finalizer for disksave. */ 591 /* Tell mc-alloc how to call a finalizer for disksave. */
494 if (XRECORD_LHEADER (MCACF_obj) && LRECORDP (MCACF_obj) \ 596 if (XRECORD_LHEADER (MCACF_obj) && LRECORDP (MCACF_obj) \
495 && !LRECORD_FREE_P (MCACF_lheader) ) \ 597 && !LRECORD_FREE_P (MCACF_lheader) ) \
496 { \ 598 { \
497 const struct lrecord_implementation *MCACF_implementation \ 599 const struct lrecord_implementation *MCACF_implementation \
498 = LHEADER_IMPLEMENTATION (MCACF_lheader); \ 600 = LHEADER_IMPLEMENTATION (MCACF_lheader); \
499 if (MCACF_implementation && MCACF_implementation->finalizer) \ 601 if (MCACF_implementation && MCACF_implementation->disksaver) \
500 MCACF_implementation->finalizer (ptr, 1); \ 602 MCACF_implementation->disksaver (MCACF_obj); \
501 } \ 603 } \
502 } while (0) 604 } while (0)
503 605
504 #define LRECORD_FREE_P(ptr) \ 606 #define LRECORD_FREE_P(ptr) \
505 (((struct lrecord_header *) ptr)->free) 607 (((struct lrecord_header *) ptr)->free)
750 Lisp_Object value; 852 Lisp_Object value;
751 } htentry; 853 } htentry;
752 854
753 struct Lisp_Hash_Table 855 struct Lisp_Hash_Table
754 { 856 {
755 struct LCRECORD_HEADER header; 857 NORMAL_LISP_OBJECT_HEADER header;
756 Elemcount size; 858 Elemcount size;
757 Elemcount count; 859 Elemcount count;
758 Elemcount rehash_count; 860 Elemcount rehash_count;
759 double rehash_size; 861 double rehash_size;
760 double rehash_threshold; 862 double rehash_threshold;
815 ... 917 ...
816 }; 918 };
817 919
818 struct Lisp_Specifier 920 struct Lisp_Specifier
819 { 921 {
820 struct LCRECORD_HEADER header; 922 NORMAL_LISP_OBJECT_HEADER header;
821 struct specifier_methods *methods; 923 struct specifier_methods *methods;
822 924
823 ... 925 ...
824 // type-specific extra data attached to a specifier 926 // type-specific extra data attached to a specifier
825 max_align_t data[1]; 927 max_align_t data[1];
1149 1251
1150 #define XD_IS_INDIRECT(code) ((code) < 0) 1252 #define XD_IS_INDIRECT(code) ((code) < 0)
1151 #define XD_INDIRECT_VAL(code) ((-1 - (code)) & 255) 1253 #define XD_INDIRECT_VAL(code) ((-1 - (code)) & 255)
1152 #define XD_INDIRECT_DELTA(code) ((-1 - (code)) >> 8) 1254 #define XD_INDIRECT_DELTA(code) ((-1 - (code)) >> 8)
1153 1255
1154 /* DEFINE_LRECORD_IMPLEMENTATION is for objects with constant size. 1256 /* DEFINE_*_LISP_OBJECT is for objects with constant size. (Either
1155 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION is for objects whose size varies. 1257 DEFINE_DUMPABLE_LISP_OBJECT for objects that can be saved in a dumped
1258 executable, or DEFINE_NODUMP_LISP_OBJECT for objects that cannot be
1259 saved -- e.g. that contain pointers to non-persistent external objects
1260 such as window-system windows.)
1261
1262 DEFINE_*_SIZABLE_LISP_OBJECT is for objects whose size varies.
1263
1264 DEFINE_*_FROB_BLOCK_LISP_OBJECT is for objects that are allocated in
1265 large blocks ("frob blocks"), which are parceled up individually. Such
1266 objects need special handling in alloc.c. This does not apply to
1267 NEW_GC, because it does this automatically.
1268
1269 DEFINE_*_INTERNAL_LISP_OBJECT is for "internal" objects that should
1270 never be visible on the Lisp level. This is a shorthand for the most
1271 common type of internal objects, which have no equal or hash method
1272 (since they generally won't appear in hash tables), no finalizer and
1273 internal_object_printer() as their print method (which prints that the
1274 object is internal and shouldn't be visible externally). For internal
1275 objects needing a finalizer, equal or hash method, or wanting to
1276 customize the print method, use the normal DEFINE_*_LISP_OBJECT
1277 mechanism for defining these objects.
1278
1279 DEFINE_*_GENERAL_LISP_OBJECT is for objects that need to provide one of
1280 the less common methods that are omitted on most objects. These methods
1281 include the methods supporting the unified property interface using
1282 `get', `put', `remprop' and `object-plist', and (for dumpable objects
1283 only) the `disksaver' method.
1284
1285 DEFINE_MODULE_* is for objects defined in an external module.
1286
1287 MAKE_LISP_OBJECT and MAKE_MODULE_LISP_OBJECT are what underlies all of
1288 these; they define a structure containing pointers to object methods
1289 and other info such as the size of the structure containing the object.
1156 */ 1290 */
1157 1291
1292 /* #### FIXME What's going on here? */
1158 #if defined (ERROR_CHECK_TYPES) 1293 #if defined (ERROR_CHECK_TYPES)
1159 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype) 1294 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype)
1160 #else 1295 #else
1161 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype) 1296 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype)
1162 #endif 1297 #endif
1163 1298
1164 1299 /********* The dumpable versions *********** */
1165 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ 1300
1166 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) 1301 #define DEFINE_DUMPABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
1167 1302 DEFINE_DUMPABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype)
1168 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ 1303
1169 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype) 1304 #define DEFINE_DUMPABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1170 1305 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizeof (structtype),0,0,structtype)
1171 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ 1306
1172 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) 1307 #define DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1173 1308 DEFINE_DUMPABLE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,structtype)
1174 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ 1309
1175 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype) 1310 #define DEFINE_DUMPABLE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizer,structtype) \
1176 1311 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,0,sizer,0,structtype)
1177 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1312
1178 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) 1313 #define DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
1179 1314 DEFINE_DUMPABLE_FROB_BLOCK_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype)
1180 #define DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1315
1181 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype) 1316 #define DEFINE_DUMPABLE_FROB_BLOCK_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1182 1317 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizeof(structtype),0,1,structtype)
1183 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ 1318
1184 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) 1319 #define DEFINE_DUMPABLE_FROB_BLOCK_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1320 MAKE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,0,sizer,1,structtype)
1321
1322 #define DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,structtype) \
1323 DEFINE_DUMPABLE_GENERAL_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,0,0,0,0,0,structtype)
1324
1325 #define DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,sizer,structtype) \
1326 DEFINE_DUMPABLE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,0,0,0,0,0,sizer,structtype)
1327
1328 /********* The non-dumpable versions *********** */
1329
1330 #define DEFINE_NODUMP_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
1331 DEFINE_NODUMP_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype)
1332
1333 #define DEFINE_NODUMP_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1334 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)
1335
1336 #define DEFINE_NODUMP_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1337 DEFINE_NODUMP_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,structtype)
1338
1339 #define DEFINE_NODUMP_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,sizer,structtype) \
1340 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,0,sizer,0,structtype)
1341
1342 #define DEFINE_NODUMP_FROB_BLOCK_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
1343 DEFINE_NODUMP_FROB_BLOCK_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype)
1344
1345 #define DEFINE_NODUMP_FROB_BLOCK_GENERAL_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1346 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)
1347
1348 #define DEFINE_NODUMP_FROB_BLOCK_SIZABLE_LISP_OBJECT(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1349 MAKE_LISP_OBJECT(name,c_name,0 /*non-dumpable*/,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,0,sizer,1,structtype)
1350
1351 #define DEFINE_NODUMP_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,structtype) \
1352 DEFINE_NODUMP_GENERAL_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,0,0,0,0,0,structtype)
1353
1354 #define DEFINE_NODUMP_SIZABLE_INTERNAL_LISP_OBJECT(name,c_name,marker,desc,sizer,structtype) \
1355 DEFINE_NODUMP_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,marker,internal_object_printer,0,0,0,desc,0,0,0,0,0,sizer,structtype)
1356
1357 /********* MAKE_LISP_OBJECT, the underlying macro *********** */
1185 1358
1186 #ifdef NEW_GC 1359 #ifdef NEW_GC
1187 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ 1360 #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) \
1188 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ 1361 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
1189 const struct lrecord_implementation lrecord_##c_name = \ 1362 const struct lrecord_implementation lrecord_##c_name = \
1190 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ 1363 { name, dumpable, marker, printer, nuker, equal, hash, desc, \
1191 getprop, putprop, remprop, plist, size, sizer, \ 1364 getprop, putprop, remprop, plist, disksaver, size, sizer, \
1192 lrecord_type_##c_name } 1365 lrecord_type_##c_name }
1193 #else /* not NEW_GC */ 1366 #else /* not NEW_GC */
1194 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ 1367 #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) \
1195 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ 1368 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
1196 const struct lrecord_implementation lrecord_##c_name = \ 1369 const struct lrecord_implementation lrecord_##c_name = \
1197 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ 1370 { name, dumpable, marker, printer, nuker, equal, hash, desc, \
1198 getprop, putprop, remprop, plist, size, sizer, \ 1371 getprop, putprop, remprop, plist, disksaver, size, sizer, \
1199 lrecord_type_##c_name, basic_p } 1372 lrecord_type_##c_name, frob_block_p }
1200 #endif /* not NEW_GC */ 1373 #endif /* not NEW_GC */
1201 1374
1202 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ 1375
1203 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) 1376 /********* The module dumpable versions *********** */
1204 1377
1205 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ 1378 #define DEFINE_DUMPABLE_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \
1206 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype) 1379 DEFINE_DUMPABLE_MODULE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype)
1207 1380
1208 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ 1381 #define DEFINE_DUMPABLE_MODULE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1209 DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) 1382 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)
1210 1383
1211 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ 1384 #define DEFINE_DUMPABLE_MODULE_SIZABLE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1212 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) 1385 DEFINE_DUMPABLE_MODULE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,structtype)
1386
1387 #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) \
1388 MAKE_MODULE_LISP_OBJECT(name,c_name,1 /*dumpable*/,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,0,sizer,0,structtype)
1389
1390 /********* The module non-dumpable versions *********** */
1391
1392 #define DEFINE_NODUMP_MODULE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \
1393 DEFINE_NODUMP_MODULE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,structtype)
1394
1395 #define DEFINE_NODUMP_MODULE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,disksaver,structtype) \
1396 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)
1397
1398 #define DEFINE_NODUMP_MODULE_SIZABLE_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
1399 DEFINE_NODUMP_MODULE_SIZABLE_GENERAL_LISP_OBJECT(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,structtype)
1400
1401 #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) \
1402 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)
1403
1404 /********* MAKE_MODULE_LISP_OBJECT, the underlying macro *********** */
1213 1405
1214 #ifdef NEW_GC 1406 #ifdef NEW_GC
1215 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ 1407 #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) \
1216 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ 1408 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
1217 int lrecord_type_##c_name; \ 1409 int lrecord_type_##c_name; \
1218 struct lrecord_implementation lrecord_##c_name = \ 1410 struct lrecord_implementation lrecord_##c_name = \
1219 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ 1411 { name, dumpable, marker, printer, nuker, equal, hash, desc, \
1220 getprop, putprop, remprop, plist, size, sizer, \ 1412 getprop, putprop, remprop, plist, disksaver, size, sizer, \
1221 lrecord_type_last_built_in_type } 1413 lrecord_type_last_built_in_type }
1222 #else /* not NEW_GC */ 1414 #else /* not NEW_GC */
1223 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ 1415 #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) \
1224 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ 1416 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
1225 int lrecord_type_##c_name; \ 1417 int lrecord_type_##c_name; \
1226 struct lrecord_implementation lrecord_##c_name = \ 1418 struct lrecord_implementation lrecord_##c_name = \
1227 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ 1419 { name, dumpable, marker, printer, nuker, equal, hash, desc, \
1228 getprop, putprop, remprop, plist, size, sizer, \ 1420 getprop, putprop, remprop, plist, disksaver, size, sizer, \
1229 lrecord_type_last_built_in_type, basic_p } 1421 lrecord_type_last_built_in_type, frob_block_p }
1230 #endif /* not NEW_GC */ 1422 #endif /* not NEW_GC */
1231 1423
1232 #ifdef USE_KKCC 1424 #ifdef USE_KKCC
1233 extern MODULE_API const struct memory_description *lrecord_memory_descriptions[]; 1425 extern MODULE_API const struct memory_description *lrecord_memory_descriptions[];
1234 1426
1235 #define INIT_LRECORD_IMPLEMENTATION(type) do { \ 1427 #define INIT_LISP_OBJECT(type) do { \
1236 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ 1428 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \
1237 lrecord_memory_descriptions[lrecord_type_##type] = \ 1429 lrecord_memory_descriptions[lrecord_type_##type] = \
1238 lrecord_implementations_table[lrecord_type_##type]->description; \ 1430 lrecord_implementations_table[lrecord_type_##type]->description; \
1239 } while (0) 1431 } while (0)
1240 #else /* not USE_KKCC */ 1432 #else /* not USE_KKCC */
1241 extern MODULE_API Lisp_Object (*lrecord_markers[]) (Lisp_Object); 1433 extern MODULE_API Lisp_Object (*lrecord_markers[]) (Lisp_Object);
1242 1434
1243 #define INIT_LRECORD_IMPLEMENTATION(type) do { \ 1435 #define INIT_LISP_OBJECT(type) do { \
1244 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ 1436 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \
1245 lrecord_markers[lrecord_type_##type] = \ 1437 lrecord_markers[lrecord_type_##type] = \
1246 lrecord_implementations_table[lrecord_type_##type]->marker; \ 1438 lrecord_implementations_table[lrecord_type_##type]->marker; \
1247 } while (0) 1439 } while (0)
1248 #endif /* not USE_KKCC */ 1440 #endif /* not USE_KKCC */
1249 1441
1250 #define INIT_EXTERNAL_LRECORD_IMPLEMENTATION(type) do { \ 1442 #define INIT_MODULE_LISP_OBJECT(type) do { \
1251 lrecord_type_##type = lrecord_type_count++; \ 1443 lrecord_type_##type = lrecord_type_count++; \
1252 lrecord_##type.lrecord_type_index = lrecord_type_##type; \ 1444 lrecord_##type.lrecord_type_index = lrecord_type_##type; \
1253 INIT_LRECORD_IMPLEMENTATION(type); \ 1445 INIT_LISP_OBJECT(type); \
1254 } while (0) 1446 } while (0)
1255 1447
1256 #ifdef HAVE_SHLIB 1448 #ifdef HAVE_SHLIB
1257 /* Allow undefining types in order to support module unloading. */ 1449 /* Allow undefining types in order to support module unloading. */
1258 1450
1259 #ifdef USE_KKCC 1451 #ifdef USE_KKCC
1260 #define UNDEF_LRECORD_IMPLEMENTATION(type) do { \ 1452 #define UNDEF_LISP_OBJECT(type) do { \
1261 lrecord_implementations_table[lrecord_type_##type] = NULL; \ 1453 lrecord_implementations_table[lrecord_type_##type] = NULL; \
1262 lrecord_memory_descriptions[lrecord_type_##type] = NULL; \ 1454 lrecord_memory_descriptions[lrecord_type_##type] = NULL; \
1263 } while (0) 1455 } while (0)
1264 #else /* not USE_KKCC */ 1456 #else /* not USE_KKCC */
1265 #define UNDEF_LRECORD_IMPLEMENTATION(type) do { \ 1457 #define UNDEF_LISP_OBJECT(type) do { \
1266 lrecord_implementations_table[lrecord_type_##type] = NULL; \ 1458 lrecord_implementations_table[lrecord_type_##type] = NULL; \
1267 lrecord_markers[lrecord_type_##type] = NULL; \ 1459 lrecord_markers[lrecord_type_##type] = NULL; \
1268 } while (0) 1460 } while (0)
1269 #endif /* not USE_KKCC */ 1461 #endif /* not USE_KKCC */
1270 1462
1271 #define UNDEF_EXTERNAL_LRECORD_IMPLEMENTATION(type) do { \ 1463 #define UNDEF_MODULE_LISP_OBJECT(type) do { \
1272 if (lrecord_##type.lrecord_type_index == lrecord_type_count - 1) { \ 1464 if (lrecord_##type.lrecord_type_index == lrecord_type_count - 1) { \
1273 /* This is the most recently defined type. Clean up nicely. */ \ 1465 /* This is the most recently defined type. Clean up nicely. */ \
1274 lrecord_type_##type = lrecord_type_count--; \ 1466 lrecord_type_##type = lrecord_type_count--; \
1275 } /* Else we can't help leaving a hole with this implementation. */ \ 1467 } /* Else we can't help leaving a hole with this implementation. */ \
1276 UNDEF_LRECORD_IMPLEMENTATION(type); \ 1468 UNDEF_LISP_OBJECT(type); \
1277 } while (0) 1469 } while (0)
1278 1470
1279 #endif /* HAVE_SHLIB */ 1471 #endif /* HAVE_SHLIB */
1280 1472
1281 #define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record) 1473 #define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record)
1287 /* Steps to create a new object: 1479 /* Steps to create a new object:
1288 1480
1289 1. Declare the struct for your object in a header file somewhere. 1481 1. Declare the struct for your object in a header file somewhere.
1290 Remember that it must begin with 1482 Remember that it must begin with
1291 1483
1292 struct LCRECORD_HEADER header; 1484 NORMAL_LISP_OBJECT_HEADER header;
1293 1485
1294 2. Put the "standard junk" (DECLARE_RECORD()/XFOO/etc.) below the 1486 2. Put the "standard junk" (DECLARE_LISP_OBJECT()/XFOO/etc.) below the
1295 struct definition -- see below. 1487 struct definition -- see below.
1296 1488
1297 3. Add this header file to inline.c. 1489 3. Add this header file to inline.c.
1298 1490
1299 4. Create the methods for your object. Note that technically you don't 1491 4. Create the methods for your object. Note that technically you don't
1302 4. Create the data layout description for your object. See 1494 4. Create the data layout description for your object. See
1303 toolbar_button_description below; the comment above in `struct lrecord', 1495 toolbar_button_description below; the comment above in `struct lrecord',
1304 describing the purpose of the descriptions; and comments elsewhere in 1496 describing the purpose of the descriptions; and comments elsewhere in
1305 this file describing the exact syntax of the description structures. 1497 this file describing the exact syntax of the description structures.
1306 1498
1307 6. Define your object with DEFINE_LRECORD_IMPLEMENTATION() or some 1499 6. Define your object with DEFINE_*_LISP_OBJECT() or some
1308 variant. 1500 variant. At the minimum, you need to decide whether your object can
1501 be dumped. Objects that are created as part of the loadup process and
1502 need to be persistent across dumping should be created dumpable.
1503 Nondumpable objects are generally those associated with display,
1504 particularly those containing a pointer to an external library object
1505 (e.g. a window-system window).
1309 1506
1310 7. Include the header file in the .c file where you defined the object. 1507 7. Include the header file in the .c file where you defined the object.
1311 1508
1312 8. Put a call to INIT_LRECORD_IMPLEMENTATION() for the object in the 1509 8. Put a call to INIT_LISP_OBJECT() for the object in the
1313 .c file's syms_of_foo() function. 1510 .c file's syms_of_foo() function.
1314 1511
1315 9. Add a type enum for the object to enum lrecord_type, earlier in this 1512 9. Add a type enum for the object to enum lrecord_type, earlier in this
1316 file. 1513 file.
1317 1514
1318 --ben 1515 --ben
1319 1516
1320 An example: 1517 An example:
1321 1518
1322 ------------------------------ in toolbar.h ----------------------------- 1519 ------------------------------ in toolbar.h -----------------------------
1323 1520
1324 struct toolbar_button 1521 struct toolbar_button
1325 { 1522 {
1326 struct LCRECORD_HEADER header; 1523 NORMAL_LISP_OBJECT_HEADER header;
1327 1524
1328 Lisp_Object next; 1525 Lisp_Object next;
1329 Lisp_Object frame; 1526 Lisp_Object frame;
1330 1527
1331 Lisp_Object up_glyph; 1528 Lisp_Object up_glyph;
1332 Lisp_Object down_glyph; 1529 Lisp_Object down_glyph;
1333 Lisp_Object disabled_glyph; 1530 Lisp_Object disabled_glyph;
1334 1531
1335 Lisp_Object cap_up_glyph; 1532 Lisp_Object cap_up_glyph;
1336 Lisp_Object cap_down_glyph; 1533 Lisp_Object cap_down_glyph;
1337 Lisp_Object cap_disabled_glyph; 1534 Lisp_Object cap_disabled_glyph;
1338 1535
1339 Lisp_Object callback; 1536 Lisp_Object callback;
1340 Lisp_Object enabled_p; 1537 Lisp_Object enabled_p;
1341 Lisp_Object help_string; 1538 Lisp_Object help_string;
1342 1539
1343 char enabled; 1540 char enabled;
1344 char down; 1541 char down;
1345 char pushright; 1542 char pushright;
1346 char blank; 1543 char blank;
1347 1544
1348 int x, y; 1545 int x, y;
1349 int width, height; 1546 int width, height;
1350 int dirty; 1547 int dirty;
1351 int vertical; 1548 int vertical;
1352 int border_width; 1549 int border_width;
1353 }; 1550 };
1354 1551
1355 [[ the standard junk: ]] 1552 [[ the standard junk: ]]
1356 1553
1357 DECLARE_LRECORD (toolbar_button, struct toolbar_button); 1554 DECLARE_LISP_OBJECT (toolbar_button, struct toolbar_button);
1358 #define XTOOLBAR_BUTTON(x) XRECORD (x, toolbar_button, struct toolbar_button) 1555 #define XTOOLBAR_BUTTON(x) XRECORD (x, toolbar_button, struct toolbar_button)
1359 #define wrap_toolbar_button(p) wrap_record (p, toolbar_button) 1556 #define wrap_toolbar_button(p) wrap_record (p, toolbar_button)
1360 #define TOOLBAR_BUTTONP(x) RECORDP (x, toolbar_button) 1557 #define TOOLBAR_BUTTONP(x) RECORDP (x, toolbar_button)
1361 #define CHECK_TOOLBAR_BUTTON(x) CHECK_RECORD (x, toolbar_button) 1558 #define CHECK_TOOLBAR_BUTTON(x) CHECK_RECORD (x, toolbar_button)
1362 #define CONCHECK_TOOLBAR_BUTTON(x) CONCHECK_RECORD (x, toolbar_button) 1559 #define CONCHECK_TOOLBAR_BUTTON(x) CONCHECK_RECORD (x, toolbar_button)
1363 1560
1364 ------------------------------ in toolbar.c ----------------------------- 1561 ------------------------------ in toolbar.c -----------------------------
1365 1562
1366 #include "toolbar.h" 1563 #include "toolbar.h"
1367 1564
1368 ... 1565 ...
1369 1566
1370 static const struct memory_description toolbar_button_description [] = { 1567 static const struct memory_description toolbar_button_description [] = {
1371 { XD_LISP_OBJECT, offsetof (struct toolbar_button, next) }, 1568 { XD_LISP_OBJECT, offsetof (struct toolbar_button, next) },
1372 { XD_LISP_OBJECT, offsetof (struct toolbar_button, frame) }, 1569 { XD_LISP_OBJECT, offsetof (struct toolbar_button, frame) },
1373 { XD_LISP_OBJECT, offsetof (struct toolbar_button, up_glyph) }, 1570 { XD_LISP_OBJECT, offsetof (struct toolbar_button, up_glyph) },
1374 { XD_LISP_OBJECT, offsetof (struct toolbar_button, down_glyph) }, 1571 { XD_LISP_OBJECT, offsetof (struct toolbar_button, down_glyph) },
1375 { XD_LISP_OBJECT, offsetof (struct toolbar_button, disabled_glyph) }, 1572 { XD_LISP_OBJECT, offsetof (struct toolbar_button, disabled_glyph) },
1376 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_up_glyph) }, 1573 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_up_glyph) },
1377 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_down_glyph) }, 1574 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_down_glyph) },
1378 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_disabled_glyph) }, 1575 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_disabled_glyph) },
1379 { XD_LISP_OBJECT, offsetof (struct toolbar_button, callback) }, 1576 { XD_LISP_OBJECT, offsetof (struct toolbar_button, callback) },
1380 { XD_LISP_OBJECT, offsetof (struct toolbar_button, enabled_p) }, 1577 { XD_LISP_OBJECT, offsetof (struct toolbar_button, enabled_p) },
1381 { XD_LISP_OBJECT, offsetof (struct toolbar_button, help_string) }, 1578 { XD_LISP_OBJECT, offsetof (struct toolbar_button, help_string) },
1382 { XD_END } 1579 { XD_END }
1383 }; 1580 };
1384 1581
1385 static Lisp_Object 1582 static Lisp_Object
1386 mark_toolbar_button (Lisp_Object obj) 1583 allocate_toolbar_button (struct frame *f, int pushright)
1387 \{ 1584 {
1388 struct toolbar_button *data = XTOOLBAR_BUTTON (obj); 1585 struct toolbar_button *tb;
1389 mark_object (data->next); 1586
1390 mark_object (data->frame); 1587 tb = XTOOLBAR_BUTTON (ALLOC_NORMAL_LISP_OBJECT (toolbar_button));
1391 mark_object (data->up_glyph); 1588 tb->next = Qnil;
1392 mark_object (data->down_glyph); 1589 tb->frame = wrap_frame (f);
1393 mark_object (data->disabled_glyph); 1590 tb->up_glyph = Qnil;
1394 mark_object (data->cap_up_glyph); 1591 tb->down_glyph = Qnil;
1395 mark_object (data->cap_down_glyph); 1592 tb->disabled_glyph = Qnil;
1396 mark_object (data->cap_disabled_glyph); 1593 tb->cap_up_glyph = Qnil;
1397 mark_object (data->callback); 1594 tb->cap_down_glyph = Qnil;
1398 mark_object (data->enabled_p); 1595 tb->cap_disabled_glyph = Qnil;
1399 return data->help_string; 1596 tb->callback = Qnil;
1400 } 1597 tb->enabled_p = Qnil;
1401 1598 tb->help_string = Qnil;
1402 [[ If your object should never escape to Lisp, declare its print method 1599
1403 as internal_object_printer instead of 0. ]] 1600 tb->pushright = pushright;
1404 1601 tb->x = tb->y = tb->width = tb->height = -1;
1405 DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button, 1602 tb->dirty = 1;
1406 0, mark_toolbar_button, 0, 0, 0, 0, 1603
1407 toolbar_button_description, 1604 return wrap_toolbar_button (tb);
1408 struct toolbar_button); 1605 }
1409 1606
1410 ... 1607 static Lisp_Object
1411 1608 mark_toolbar_button (Lisp_Object obj)
1412 void 1609 {
1413 syms_of_toolbar (void) 1610 struct toolbar_button *data = XTOOLBAR_BUTTON (obj);
1414 { 1611 mark_object (data->next);
1415 INIT_LRECORD_IMPLEMENTATION (toolbar_button); 1612 mark_object (data->frame);
1416 1613 mark_object (data->up_glyph);
1417 ...; 1614 mark_object (data->down_glyph);
1418 } 1615 mark_object (data->disabled_glyph);
1419 1616 mark_object (data->cap_up_glyph);
1617 mark_object (data->cap_down_glyph);
1618 mark_object (data->cap_disabled_glyph);
1619 mark_object (data->callback);
1620 mark_object (data->enabled_p);
1621 return data->help_string;
1622 }
1623
1624 DEFINE_NODUMP_LISP_OBJECT ("toolbar-button", toolbar_button,
1625 mark_toolbar_button,
1626 external_object_printer, 0, 0, 0,
1627 toolbar_button_description,
1628 struct toolbar_button);
1629
1630 ...
1631
1632 void
1633 syms_of_toolbar (void)
1634 {
1635 INIT_LISP_OBJECT (toolbar_button);
1636
1637 ...;
1638 }
1639
1420 ------------------------------ in inline.c ----------------------------- 1640 ------------------------------ in inline.c -----------------------------
1421 1641
1422 #ifdef HAVE_TOOLBARS 1642 #ifdef HAVE_TOOLBARS
1423 #include "toolbar.h" 1643 #include "toolbar.h"
1424 #endif 1644 #endif
1425 1645
1426 ------------------------------ in lrecord.h ----------------------------- 1646 ------------------------------ in lrecord.h -----------------------------
1427 1647
1428 enum lrecord_type 1648 enum lrecord_type
1429 { 1649 {
1650 ...
1651 lrecord_type_toolbar_button,
1652 ...
1653 };
1654
1655 ------------------------------ in .gdbinit.in.in -----------------------------
1656
1430 ... 1657 ...
1431 lrecord_type_toolbar_button, 1658 else
1659 if $lrecord_type == lrecord_type_toolbar_button
1660 pstructtype toolbar_button
1432 ... 1661 ...
1433 }; 1662 ...
1434 1663 ...
1435 1664 end
1436 --ben 1665
1666 --ben
1437 1667
1438 */ 1668 */
1439 1669
1440 /* 1670 /*
1441 1671
1442 Note: Object types defined in external dynamically-loaded modules (not 1672 Note: Object types defined in external dynamically-loaded modules (not
1443 part of the XEmacs main source code) should use DECLARE_EXTERNAL_LRECORD 1673 part of the XEmacs main source code) should use DECLARE_*_MODULE_LISP_OBJECT
1444 and DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION rather than DECLARE_LRECORD 1674 and DEFINE_*_MODULE_LISP_OBJECT rather than DECLARE_*_LISP_OBJECT
1445 and DEFINE_LRECORD_IMPLEMENTATION. The EXTERNAL versions declare and 1675 and DEFINE_*_LISP_OBJECT. The MODULE versions declare and
1446 allocate an enumerator for the type being defined. 1676 allocate an enumerator for the type being defined.
1447 1677
1448 */ 1678 */
1449 1679
1450 1680
1451 #ifdef ERROR_CHECK_TYPES 1681 #ifdef ERROR_CHECK_TYPES
1452 1682
1453 # define DECLARE_LRECORD(c_name, structtype) \ 1683 # define DECLARE_LISP_OBJECT(c_name, structtype) \
1454 extern const struct lrecord_implementation lrecord_##c_name; \ 1684 extern const struct lrecord_implementation lrecord_##c_name; \
1455 DECLARE_INLINE_HEADER ( \ 1685 DECLARE_INLINE_HEADER ( \
1456 structtype * \ 1686 structtype * \
1457 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1687 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1458 ) \ 1688 ) \
1460 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1690 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1461 return (structtype *) XPNTR (obj); \ 1691 return (structtype *) XPNTR (obj); \
1462 } \ 1692 } \
1463 extern Lisp_Object Q##c_name##p 1693 extern Lisp_Object Q##c_name##p
1464 1694
1465 # define DECLARE_MODULE_API_LRECORD(c_name, structtype) \ 1695 # define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \
1466 extern MODULE_API const struct lrecord_implementation lrecord_##c_name; \ 1696 extern MODULE_API const struct lrecord_implementation lrecord_##c_name; \
1467 DECLARE_INLINE_HEADER ( \ 1697 DECLARE_INLINE_HEADER ( \
1468 structtype * \ 1698 structtype * \
1469 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1699 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1470 ) \ 1700 ) \
1472 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1702 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1473 return (structtype *) XPNTR (obj); \ 1703 return (structtype *) XPNTR (obj); \
1474 } \ 1704 } \
1475 extern MODULE_API Lisp_Object Q##c_name##p 1705 extern MODULE_API Lisp_Object Q##c_name##p
1476 1706
1477 # define DECLARE_EXTERNAL_LRECORD(c_name, structtype) \ 1707 # define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \
1478 extern int lrecord_type_##c_name; \ 1708 extern int lrecord_type_##c_name; \
1479 extern struct lrecord_implementation lrecord_##c_name; \ 1709 extern struct lrecord_implementation lrecord_##c_name; \
1480 DECLARE_INLINE_HEADER ( \ 1710 DECLARE_INLINE_HEADER ( \
1481 structtype * \ 1711 structtype * \
1482 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ 1712 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1485 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \ 1715 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
1486 return (structtype *) XPNTR (obj); \ 1716 return (structtype *) XPNTR (obj); \
1487 } \ 1717 } \
1488 extern Lisp_Object Q##c_name##p 1718 extern Lisp_Object Q##c_name##p
1489 1719
1490 # define DECLARE_NONRECORD(c_name, type_enum, structtype) \
1491 DECLARE_INLINE_HEADER ( \
1492 structtype * \
1493 error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \
1494 ) \
1495 { \
1496 assert_at_line (XTYPE (obj) == type_enum, file, line); \
1497 return (structtype *) XPNTR (obj); \
1498 } \
1499 extern Lisp_Object Q##c_name##p
1500
1501 # define XRECORD(x, c_name, structtype) \ 1720 # define XRECORD(x, c_name, structtype) \
1502 error_check_##c_name (x, __FILE__, __LINE__)
1503 # define XNONRECORD(x, c_name, type_enum, structtype) \
1504 error_check_##c_name (x, __FILE__, __LINE__) 1721 error_check_##c_name (x, __FILE__, __LINE__)
1505 1722
1506 DECLARE_INLINE_HEADER ( 1723 DECLARE_INLINE_HEADER (
1507 Lisp_Object 1724 Lisp_Object
1508 wrap_record_1 (const void *ptr, enum lrecord_type ty, const Ascbyte *file, 1725 wrap_record_1 (const void *ptr, enum lrecord_type ty, const Ascbyte *file,
1518 #define wrap_record(ptr, ty) \ 1735 #define wrap_record(ptr, ty) \
1519 wrap_record_1 (ptr, lrecord_type_##ty, __FILE__, __LINE__) 1736 wrap_record_1 (ptr, lrecord_type_##ty, __FILE__, __LINE__)
1520 1737
1521 #else /* not ERROR_CHECK_TYPES */ 1738 #else /* not ERROR_CHECK_TYPES */
1522 1739
1523 # define DECLARE_LRECORD(c_name, structtype) \ 1740 # define DECLARE_LISP_OBJECT(c_name, structtype) \
1524 extern Lisp_Object Q##c_name##p; \ 1741 extern Lisp_Object Q##c_name##p; \
1525 extern const struct lrecord_implementation lrecord_##c_name 1742 extern const struct lrecord_implementation lrecord_##c_name
1526 # define DECLARE_MODULE_API_LRECORD(c_name, structtype) \ 1743 # define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \
1527 extern MODULE_API Lisp_Object Q##c_name##p; \ 1744 extern MODULE_API Lisp_Object Q##c_name##p; \
1528 extern MODULE_API const struct lrecord_implementation lrecord_##c_name 1745 extern MODULE_API const struct lrecord_implementation lrecord_##c_name
1529 # define DECLARE_EXTERNAL_LRECORD(c_name, structtype) \ 1746 # define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \
1530 extern Lisp_Object Q##c_name##p; \ 1747 extern Lisp_Object Q##c_name##p; \
1531 extern int lrecord_type_##c_name; \ 1748 extern int lrecord_type_##c_name; \
1532 extern struct lrecord_implementation lrecord_##c_name 1749 extern struct lrecord_implementation lrecord_##c_name
1533 # define DECLARE_NONRECORD(c_name, type_enum, structtype) \
1534 extern Lisp_Object Q##c_name##p
1535 # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x)) 1750 # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x))
1536 # define XNONRECORD(x, c_name, type_enum, structtype) \
1537 ((structtype *) XPNTR (x))
1538 /* wrap_pointer_1 is so named as a suggestion not to use it unless you 1751 /* wrap_pointer_1 is so named as a suggestion not to use it unless you
1539 know what you're doing. */ 1752 know what you're doing. */
1540 #define wrap_record(ptr, ty) wrap_pointer_1 (ptr) 1753 #define wrap_record(ptr, ty) wrap_pointer_1 (ptr)
1541 1754
1542 #endif /* not ERROR_CHECK_TYPES */ 1755 #endif /* not ERROR_CHECK_TYPES */
1586 #ifndef NEW_GC 1799 #ifndef NEW_GC
1587 /*-------------------------- lcrecord-list -----------------------------*/ 1800 /*-------------------------- lcrecord-list -----------------------------*/
1588 1801
1589 struct lcrecord_list 1802 struct lcrecord_list
1590 { 1803 {
1591 struct LCRECORD_HEADER header; 1804 NORMAL_LISP_OBJECT_HEADER header;
1592 Lisp_Object free; 1805 Lisp_Object free;
1593 Elemcount size; 1806 Elemcount size;
1594 const struct lrecord_implementation *implementation; 1807 const struct lrecord_implementation *implementation;
1595 }; 1808 };
1596 1809
1597 DECLARE_LRECORD (lcrecord_list, struct lcrecord_list); 1810 DECLARE_LISP_OBJECT (lcrecord_list, struct lcrecord_list);
1598 #define XLCRECORD_LIST(x) XRECORD (x, lcrecord_list, struct lcrecord_list) 1811 #define XLCRECORD_LIST(x) XRECORD (x, lcrecord_list, struct lcrecord_list)
1599 #define wrap_lcrecord_list(p) wrap_record (p, lcrecord_list) 1812 #define wrap_lcrecord_list(p) wrap_record (p, lcrecord_list)
1600 #define LCRECORD_LISTP(x) RECORDP (x, lcrecord_list) 1813 #define LCRECORD_LISTP(x) RECORDP (x, lcrecord_list)
1601 /* #define CHECK_LCRECORD_LIST(x) CHECK_RECORD (x, lcrecord_list) 1814 /* #define CHECK_LCRECORD_LIST(x) CHECK_RECORD (x, lcrecord_list)
1602 Lcrecord lists should never escape to the Lisp level, so 1815 Lcrecord lists should never escape to the Lisp level, so
1607 1820
1608 See above for a discussion of the difference between plain lrecords and 1821 See above for a discussion of the difference between plain lrecords and
1609 lrecords. lcrecords themselves are divided into three types: (1) 1822 lrecords. lcrecords themselves are divided into three types: (1)
1610 auto-managed, (2) hand-managed, and (3) unmanaged. "Managed" refers to 1823 auto-managed, (2) hand-managed, and (3) unmanaged. "Managed" refers to
1611 using a special object called an lcrecord-list to keep track of freed 1824 using a special object called an lcrecord-list to keep track of freed
1612 lcrecords, which can freed with FREE_LCRECORD() or the like and later be 1825 lcrecords, which can freed with free_normal_lisp_object() or the like
1613 recycled when a new lcrecord is required, rather than requiring new 1826 and later be recycled when a new lcrecord is required, rather than
1614 malloc(). Thus, allocation of lcrecords can be very 1827 requiring new malloc(). Thus, allocation of lcrecords can be very
1615 cheap. (Technically, the lcrecord-list manager could divide up large 1828 cheap. (Technically, the lcrecord-list manager could divide up large
1616 chunks of memory and allocate out of that, mimicking what happens with 1829 chunks of memory and allocate out of that, mimicking what happens with
1617 lrecords. At that point, however, we'd want to rethink the whole 1830 lrecords. At that point, however, we'd want to rethink the whole
1618 division between lrecords and lcrecords.) 1831 division between lrecords and lcrecords.)
1619 1832
1620 NOTE: There is a fundamental limitation of lcrecord-lists, which is that 1833 NOTE: There is a fundamental limitation of lcrecord-lists, which is that
1621 they only handle blocks of a particular, fixed size. Thus, objects that 1834 they only handle blocks of a particular, fixed size. Thus, objects that
1622 can be of varying sizes need to do various tricks. These considerations 1835 can be of varying sizes need to do various tricks. These considerations
1623 in particular dictate the various types of management: 1836 in particular dictate the various types of management:
1624 1837
1625 -- "Auto-managed" means that you just go ahead and allocate the lcrecord 1838 -- "Auto-managed" means that you just go ahead and allocate the lcrecord
1626 whenever you want, using old_alloc_lcrecord_type(), and the appropriate 1839 whenever you want, using ALLOC_NORMAL_LISP_OBJECT(), and the appropriate
1627 lcrecord-list manager is automatically created. To free, you just call 1840 lcrecord-list manager is automatically created. To free, you just call
1628 "FREE_LCRECORD()" and the appropriate lcrecord-list manager is 1841 "free_normal_lisp_object()" and the appropriate lcrecord-list manager is
1629 automatically located and called. The limitation here of course is that 1842 automatically located and called. The limitation here of course is that
1630 all your objects are of the same size. (#### Eventually we should have a 1843 all your objects are of the same size. (#### Eventually we should have a
1631 more sophisticated system that tracks the sizes seen and creates one 1844 more sophisticated system that tracks the sizes seen and creates one
1632 lcrecord list per size, indexed in a hash table. Usually there are only 1845 lcrecord list per size, indexed in a hash table. Usually there are only
1633 a limited number of sizes, so this works well.) 1846 a limited number of sizes, so this works well.)
1644 lcrecord-lists, no way to free them. This may be suitable when the 1857 lcrecord-lists, no way to free them. This may be suitable when the
1645 lcrecords are variable-sized and (a) you're too lazy to write the code 1858 lcrecords are variable-sized and (a) you're too lazy to write the code
1646 to hand-manage them, or (b) the objects you create are always or almost 1859 to hand-manage them, or (b) the objects you create are always or almost
1647 always Lisp-visible, and thus there's no point in freeing them (and it 1860 always Lisp-visible, and thus there's no point in freeing them (and it
1648 wouldn't be safe to do so). You just create them with 1861 wouldn't be safe to do so). You just create them with
1649 BASIC_ALLOC_LCRECORD(), and that's it. 1862 ALLOC_SIZED_LISP_OBJECT(), and that's it.
1650 1863
1651 --ben 1864 --ben
1652 1865
1653 Here is an in-depth look at the steps required to create a allocate an 1866 Here is an in-depth look at the steps required to create a allocate an
1654 lcrecord using the hand-managed style. Since this is the most 1867 lcrecord using the hand-managed style. Since this is the most
1657 lcrecord really entails, and what are the precautions: 1870 lcrecord really entails, and what are the precautions:
1658 1871
1659 1) Create an lcrecord-list object using make_lcrecord_list(). This is 1872 1) Create an lcrecord-list object using make_lcrecord_list(). This is
1660 often done at initialization. Remember to staticpro_nodump() this 1873 often done at initialization. Remember to staticpro_nodump() this
1661 object! The arguments to make_lcrecord_list() are the same as would be 1874 object! The arguments to make_lcrecord_list() are the same as would be
1662 passed to BASIC_ALLOC_LCRECORD(). 1875 passed to ALLOC_SIZED_LISP_OBJECT().
1663 1876
1664 2) Instead of calling BASIC_ALLOC_LCRECORD(), call alloc_managed_lcrecord() 1877 2) Instead of calling ALLOC_SIZED_LISP_OBJECT(), call
1665 and pass the lcrecord-list earlier created. 1878 alloc_managed_lcrecord() and pass the lcrecord-list earlier created.
1666 1879
1667 3) When done with the lcrecord, call free_managed_lcrecord(). The 1880 3) When done with the lcrecord, call free_managed_lcrecord(). The
1668 standard freeing caveats apply: ** make sure there are no pointers to 1881 standard freeing caveats apply: ** make sure there are no pointers to
1669 the object anywhere! ** 1882 the object anywhere! **
1670 1883
1671 4) Calling free_managed_lcrecord() is just like kissing the 1884 4) Calling free_managed_lcrecord() is just like kissing the
1672 lcrecord goodbye as if it were garbage-collected. This means: 1885 lcrecord goodbye as if it were garbage-collected. This means:
1673 -- the contents of the freed lcrecord are undefined, and the 1886 -- the contents of the freed lcrecord are undefined, and the
1674 contents of something produced by alloc_managed_lcrecord() 1887 contents of something produced by alloc_managed_lcrecord()
1675 are undefined, just like for BASIC_ALLOC_LCRECORD(). 1888 are undefined, just like for ALLOC_SIZED_LISP_OBJECT().
1676 -- the mark method for the lcrecord's type will *NEVER* be called 1889 -- the mark method for the lcrecord's type will *NEVER* be called
1677 on freed lcrecords. 1890 on freed lcrecords.
1678 -- the finalize method for the lcrecord's type will be called 1891 -- the finalize method for the lcrecord's type will be called
1679 at the time that free_managed_lcrecord() is called. 1892 at the time that free_managed_lcrecord() is called.
1680 */ 1893 */
1681 1894
1682 /* UNMANAGED MODEL: */ 1895 /* UNMANAGED MODEL: */
1683 void *old_basic_alloc_lcrecord (Bytecount size, 1896 Lisp_Object old_alloc_lcrecord (const struct lrecord_implementation *);
1684 const struct lrecord_implementation *); 1897 Lisp_Object old_alloc_sized_lcrecord (Bytecount size,
1898 const struct lrecord_implementation *);
1685 1899
1686 /* HAND-MANAGED MODEL: */ 1900 /* HAND-MANAGED MODEL: */
1687 Lisp_Object make_lcrecord_list (Elemcount size, 1901 Lisp_Object make_lcrecord_list (Elemcount size,
1688 const struct lrecord_implementation 1902 const struct lrecord_implementation
1689 *implementation); 1903 *implementation);
1690 Lisp_Object alloc_managed_lcrecord (Lisp_Object lcrecord_list); 1904 Lisp_Object alloc_managed_lcrecord (Lisp_Object lcrecord_list);
1691 void free_managed_lcrecord (Lisp_Object lcrecord_list, Lisp_Object lcrecord); 1905 void free_managed_lcrecord (Lisp_Object lcrecord_list, Lisp_Object lcrecord);
1692 1906
1693 /* AUTO-MANAGED MODEL: */ 1907 /* AUTO-MANAGED MODEL: */
1694 MODULE_API void * 1908 MODULE_API Lisp_Object
1695 alloc_automanaged_lcrecord (Bytecount size, 1909 alloc_automanaged_sized_lcrecord (Bytecount size,
1696 const struct lrecord_implementation *); 1910 const struct lrecord_implementation *imp);
1697 1911 MODULE_API Lisp_Object
1698 #define old_alloc_lcrecord_type(type, lrecord_implementation) \ 1912 alloc_automanaged_lcrecord (const struct lrecord_implementation *imp);
1699 ((type *) alloc_automanaged_lcrecord (sizeof (type), lrecord_implementation)) 1913
1914 #define old_alloc_lcrecord_type(type, imp) \
1915 ((type *) XPNTR (alloc_automanaged_lcrecord (sizeof (type), imp)))
1700 1916
1701 void old_free_lcrecord (Lisp_Object rec); 1917 void old_free_lcrecord (Lisp_Object rec);
1702 1918
1703
1704 /* Copy the data from one lcrecord structure into another, but don't
1705 overwrite the header information. */
1706
1707 #define old_copy_sized_lcrecord(dst, src, size) \
1708 memcpy ((Rawbyte *) (dst) + sizeof (struct old_lcrecord_header), \
1709 (Rawbyte *) (src) + sizeof (struct old_lcrecord_header), \
1710 (size) - sizeof (struct old_lcrecord_header))
1711
1712 #define old_copy_lcrecord(dst, src) \
1713 old_copy_sized_lcrecord (dst, src, sizeof (*(dst)))
1714
1715 #define old_zero_sized_lcrecord(lcr, size) \
1716 memset ((Rawbyte *) (lcr) + sizeof (struct old_lcrecord_header), 0, \
1717 (size) - sizeof (struct old_lcrecord_header))
1718
1719 #define old_zero_lcrecord(lcr) old_zero_sized_lcrecord (lcr, sizeof (*(lcr)))
1720
1721 #else /* NEW_GC */ 1919 #else /* NEW_GC */
1722 1920
1723 /* How to allocate a lrecord: 1921 MODULE_API Lisp_Object alloc_sized_lrecord (Bytecount size,
1724 1922 const struct lrecord_implementation *imp);
1725 - If the size of the lrecord is fix, say it equals its size of its 1923 Lisp_Object noseeum_alloc_sized_lrecord (Bytecount size,
1726 struct, then use alloc_lrecord_type. 1924 const struct lrecord_implementation *imp);
1727 1925 MODULE_API Lisp_Object alloc_lrecord (const struct lrecord_implementation *imp);
1728 - If the size varies, i.e. it is not equal to the size of its 1926 Lisp_Object noseeum_alloc_lrecord (const struct lrecord_implementation *imp);
1729 struct, use alloc_lrecord and specify the amount of storage you 1927
1730 need for the object. 1928 MODULE_API Lisp_Object alloc_lrecord_array (int elemcount,
1731 1929 const struct lrecord_implementation *imp);
1732 - Some lrecords, which are used totally internally, use the 1930 MODULE_API Lisp_Object alloc_sized_lrecord_array (Bytecount size,
1733 noseeum-* functions for the reason of debugging. 1931 int elemcount,
1734 1932 const struct lrecord_implementation *imp);
1735 - To free a Lisp_Object manually, use free_lrecord. */
1736
1737 void *alloc_lrecord (Bytecount size,
1738 const struct lrecord_implementation *);
1739
1740 void *alloc_lrecord_array (Bytecount size, int elemcount,
1741 const struct lrecord_implementation *);
1742
1743 #define alloc_lrecord_type(type, lrecord_implementation) \
1744 ((type *) alloc_lrecord (sizeof (type), lrecord_implementation))
1745
1746 void *noseeum_alloc_lrecord (Bytecount size,
1747 const struct lrecord_implementation *);
1748
1749 #define noseeum_alloc_lrecord_type(type, lrecord_implementation) \
1750 ((type *) noseeum_alloc_lrecord (sizeof (type), lrecord_implementation))
1751
1752 void free_lrecord (Lisp_Object rec);
1753
1754
1755 /* Copy the data from one lrecord structure into another, but don't
1756 overwrite the header information. */
1757
1758 #define copy_sized_lrecord(dst, src, size) \
1759 memcpy ((char *) (dst) + sizeof (struct lrecord_header), \
1760 (char *) (src) + sizeof (struct lrecord_header), \
1761 (size) - sizeof (struct lrecord_header))
1762
1763 #define copy_lrecord(dst, src) copy_sized_lrecord (dst, src, sizeof (*(dst)))
1764 1933
1765 #endif /* NEW_GC */ 1934 #endif /* NEW_GC */
1766
1767 #define zero_sized_lrecord(lcr, size) \
1768 memset ((char *) (lcr) + sizeof (struct lrecord_header), 0, \
1769 (size) - sizeof (struct lrecord_header))
1770
1771 #define zero_lrecord(lcr) zero_sized_lrecord (lcr, sizeof (*(lcr)))
1772 1935
1773 DECLARE_INLINE_HEADER ( 1936 DECLARE_INLINE_HEADER (
1774 Bytecount 1937 Bytecount
1775 detagged_lisp_object_size (const struct lrecord_header *h) 1938 detagged_lisp_object_size (const struct lrecord_header *h)
1776 ) 1939 )
1777 { 1940 {
1778 const struct lrecord_implementation *imp = LHEADER_IMPLEMENTATION (h); 1941 const struct lrecord_implementation *imp = LHEADER_IMPLEMENTATION (h);
1779 1942
1780 return (imp->size_in_bytes_method ? 1943 return (imp->size_in_bytes_method ?
1781 imp->size_in_bytes_method (h) : 1944 imp->size_in_bytes_method (wrap_pointer_1 (h)) :
1782 imp->static_size); 1945 imp->static_size);
1783 } 1946 }
1784 1947
1785 DECLARE_INLINE_HEADER ( 1948 DECLARE_INLINE_HEADER (
1786 Bytecount 1949 Bytecount
1787 lisp_object_size (Lisp_Object o) 1950 lisp_object_size (Lisp_Object o)
1788 ) 1951 )
1789 { 1952 {
1790 return detagged_lisp_object_size (XRECORD_LHEADER (o)); 1953 return detagged_lisp_object_size (XRECORD_LHEADER (o));
1791 } 1954 }
1955
1956 struct overhead_stats;
1957
1958 MODULE_API void copy_lisp_object (Lisp_Object dst, Lisp_Object src);
1959 MODULE_API void zero_sized_lisp_object (Lisp_Object obj, Bytecount size);
1960 MODULE_API void zero_nonsized_lisp_object (Lisp_Object obj);
1961 #ifdef MEMORY_USAGE_STATS
1962 Bytecount lisp_object_storage_size (Lisp_Object obj,
1963 struct overhead_stats *ovstats);
1964 #endif /* MEMORY_USAGE_STATS */
1965 void free_normal_lisp_object (Lisp_Object obj);
1792 1966
1793 1967
1794 /************************************************************************/ 1968 /************************************************************************/
1795 /* Dumping */ 1969 /* Dumping */
1796 /************************************************************************/ 1970 /************************************************************************/