Mercurial > hg > xemacs-beta
comparison src/lrecord.h @ 3263:d674024a8674
[xemacs-hg @ 2006-02-27 16:29:00 by crestani]
- Introduce a fancy asynchronous finalization strategy on C level.
- Merge the code conditioned on MC_ALLOC into the code conditioned on
NEW_GC.
- Remove the possibility to free objects manually outside garbage
collections when the new collector is enabled.
author | crestani |
---|---|
date | Mon, 27 Feb 2006 16:29:29 +0000 |
parents | 902a82391129 |
children | fd1f0c73d4df |
comparison
equal
deleted
inserted
replaced
3262:79d41cfd8e6b | 3263:d674024a8674 |
---|---|
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 #ifdef MC_ALLOC | 29 #ifdef NEW_GC |
30 /* The "lrecord" type of Lisp object is used for all object types | 30 /* The "lrecord" type of Lisp object is used for all object types |
31 other than a few simple ones (like char and int). This allows many | 31 other than a few simple ones (like char and int). This allows many |
32 types to be implemented but only a few bits required in a Lisp | 32 types to be implemented but only a few bits required in a Lisp |
33 object for type information. (The tradeoff is that each object has | 33 object for type information. (The tradeoff is that each object has |
34 its type marked in it, thereby increasing its size.) All lrecords | 34 its type marked in it, thereby increasing its size.) All lrecords |
43 defaults are provided for many of them. Alternatively, if you're | 43 defaults are provided for many of them. Alternatively, if you're |
44 just looking for a way of encapsulating data (which possibly | 44 just looking for a way of encapsulating data (which possibly |
45 could contain Lisp_Objects in it), you may well be able to use | 45 could contain Lisp_Objects in it), you may well be able to use |
46 the opaque type. | 46 the opaque type. |
47 */ | 47 */ |
48 #else /* not MC_ALLOC */ | 48 #else /* not NEW_GC */ |
49 /* The "lrecord" type of Lisp object is used for all object types | 49 /* The "lrecord" type of Lisp object is used for all object types |
50 other than a few simple ones. This allows many types to be | 50 other than a few simple ones. This allows many types to be |
51 implemented but only a few bits required in a Lisp object for type | 51 implemented but only a few bits required in a Lisp object for type |
52 information. (The tradeoff is that each object has its type marked | 52 information. (The tradeoff is that each object has its type marked |
53 in it, thereby increasing its size.) All lrecords begin with a | 53 in it, thereby increasing its size.) All lrecords begin with a |
77 defaults are provided for many of them. Alternatively, if you're | 77 defaults are provided for many of them. Alternatively, if you're |
78 just looking for a way of encapsulating data (which possibly | 78 just looking for a way of encapsulating data (which possibly |
79 could contain Lisp_Objects in it), you may well be able to use | 79 could contain Lisp_Objects in it), you may well be able to use |
80 the opaque type. --ben | 80 the opaque type. --ben |
81 */ | 81 */ |
82 #endif /* not MC_ALLOC */ | 82 #endif /* not NEW_GC */ |
83 | 83 |
84 #ifdef MC_ALLOC | 84 #ifdef NEW_GC |
85 #define ALLOC_LCRECORD_TYPE alloc_lrecord_type | 85 #define ALLOC_LCRECORD_TYPE alloc_lrecord_type |
86 #define COPY_SIZED_LCRECORD copy_sized_lrecord | 86 #define COPY_SIZED_LCRECORD copy_sized_lrecord |
87 #define COPY_LCRECORD copy_lrecord | 87 #define COPY_LCRECORD copy_lrecord |
88 #define LISPOBJ_STORAGE_SIZE(ptr, size, stats) \ | 88 #define LISPOBJ_STORAGE_SIZE(ptr, size, stats) \ |
89 mc_alloced_storage_size (size, stats) | 89 mc_alloced_storage_size (size, stats) |
90 #define ZERO_LCRECORD zero_lrecord | 90 #define ZERO_LCRECORD zero_lrecord |
91 #define LCRECORD_HEADER lrecord_header | 91 #define LCRECORD_HEADER lrecord_header |
92 #define BASIC_ALLOC_LCRECORD alloc_lrecord | 92 #define BASIC_ALLOC_LCRECORD alloc_lrecord |
93 #define FREE_LCRECORD free_lrecord | 93 #define FREE_LCRECORD free_lrecord |
94 #else | 94 #else /* not NEW_GC */ |
95 #define ALLOC_LCRECORD_TYPE old_alloc_lcrecord_type | 95 #define ALLOC_LCRECORD_TYPE old_alloc_lcrecord_type |
96 #define COPY_SIZED_LCRECORD old_copy_sized_lcrecord | 96 #define COPY_SIZED_LCRECORD old_copy_sized_lcrecord |
97 #define COPY_LCRECORD old_copy_lcrecord | 97 #define COPY_LCRECORD old_copy_lcrecord |
98 #define LISPOBJ_STORAGE_SIZE malloced_storage_size | 98 #define LISPOBJ_STORAGE_SIZE malloced_storage_size |
99 #define ZERO_LCRECORD old_zero_lcrecord | 99 #define ZERO_LCRECORD old_zero_lcrecord |
100 #define LCRECORD_HEADER old_lcrecord_header | 100 #define LCRECORD_HEADER old_lcrecord_header |
101 #define BASIC_ALLOC_LCRECORD old_basic_alloc_lcrecord | 101 #define BASIC_ALLOC_LCRECORD old_basic_alloc_lcrecord |
102 #define FREE_LCRECORD old_free_lcrecord | 102 #define FREE_LCRECORD old_free_lcrecord |
103 #endif | 103 #endif /* not NEW_GC */ |
104 | 104 |
105 BEGIN_C_DECLS | 105 BEGIN_C_DECLS |
106 | 106 |
107 struct lrecord_header | 107 struct lrecord_header |
108 { | 108 { |
109 /* Index into lrecord_implementations_table[]. Objects that have been | 109 /* Index into lrecord_implementations_table[]. Objects that have been |
110 explicitly freed using e.g. free_cons() have lrecord_type_free in this | 110 explicitly freed using e.g. free_cons() have lrecord_type_free in this |
111 field. */ | 111 field. */ |
112 unsigned int type :8; | 112 unsigned int type :8; |
113 | 113 |
114 #ifdef MC_ALLOC | 114 #ifdef NEW_GC |
115 /* 1 if the object is readonly from lisp */ | 115 /* 1 if the object is readonly from lisp */ |
116 unsigned int lisp_readonly :1; | 116 unsigned int lisp_readonly :1; |
117 | 117 |
118 /* The `free' field is a flag that indicates whether this lrecord | 118 /* The `free' field is a flag that indicates whether this lrecord |
119 is currently free or not. This is used for error checking and | 119 is currently free or not. This is used for error checking and |
123 /* The `uid' field is just for debugging/printing convenience. Having | 123 /* The `uid' field is just for debugging/printing convenience. Having |
124 this slot doesn't hurt us spacewise, since the bits are unused | 124 this slot doesn't hurt us spacewise, since the bits are unused |
125 anyway. (The bits are used for strings, though.) */ | 125 anyway. (The bits are used for strings, though.) */ |
126 unsigned int uid :22; | 126 unsigned int uid :22; |
127 | 127 |
128 #else /* not MC_ALLOC */ | 128 #else /* not NEW_GC */ |
129 /* If `mark' is 0 after the GC mark phase, the object will be freed | 129 /* If `mark' is 0 after the GC mark phase, the object will be freed |
130 during the GC sweep phase. There are 2 ways that `mark' can be 1: | 130 during the GC sweep phase. There are 2 ways that `mark' can be 1: |
131 - by being referenced from other objects during the GC mark phase | 131 - by being referenced from other objects during the GC mark phase |
132 - because it is permanently on, for c_readonly objects */ | 132 - because it is permanently on, for c_readonly objects */ |
133 unsigned int mark :1; | 133 unsigned int mark :1; |
143 /* The `uid' field is just for debugging/printing convenience. Having | 143 /* The `uid' field is just for debugging/printing convenience. Having |
144 this slot doesn't hurt us spacewise, since the bits are unused | 144 this slot doesn't hurt us spacewise, since the bits are unused |
145 anyway. (The bits are used for strings, though.) */ | 145 anyway. (The bits are used for strings, though.) */ |
146 unsigned int uid :21; | 146 unsigned int uid :21; |
147 | 147 |
148 #endif /* not MC_ALLOC */ | 148 #endif /* not NEW_GC */ |
149 }; | 149 }; |
150 | 150 |
151 struct lrecord_implementation; | 151 struct lrecord_implementation; |
152 int lrecord_type_index (const struct lrecord_implementation *implementation); | 152 int lrecord_type_index (const struct lrecord_implementation *implementation); |
153 extern int lrecord_uid_counter; | 153 extern int lrecord_uid_counter; |
154 | 154 |
155 #ifdef MC_ALLOC | 155 #ifdef NEW_GC |
156 #define set_lheader_implementation(header,imp) do { \ | 156 #define set_lheader_implementation(header,imp) do { \ |
157 struct lrecord_header* SLI_header = (header); \ | 157 struct lrecord_header* SLI_header = (header); \ |
158 SLI_header->type = (imp)->lrecord_type_index; \ | 158 SLI_header->type = (imp)->lrecord_type_index; \ |
159 SLI_header->lisp_readonly = 0; \ | 159 SLI_header->lisp_readonly = 0; \ |
160 SLI_header->free = 0; \ | 160 SLI_header->free = 0; \ |
161 SLI_header->uid = lrecord_uid_counter++; \ | 161 SLI_header->uid = lrecord_uid_counter++; \ |
162 } while (0) | 162 } while (0) |
163 #else /* not MC_ALLOC */ | 163 #else /* not NEW_GC */ |
164 #define set_lheader_implementation(header,imp) do { \ | 164 #define set_lheader_implementation(header,imp) do { \ |
165 struct lrecord_header* SLI_header = (header); \ | 165 struct lrecord_header* SLI_header = (header); \ |
166 SLI_header->type = (imp)->lrecord_type_index; \ | 166 SLI_header->type = (imp)->lrecord_type_index; \ |
167 SLI_header->mark = 0; \ | 167 SLI_header->mark = 0; \ |
168 SLI_header->c_readonly = 0; \ | 168 SLI_header->c_readonly = 0; \ |
169 SLI_header->lisp_readonly = 0; \ | 169 SLI_header->lisp_readonly = 0; \ |
170 SLI_header->uid = lrecord_uid_counter++; \ | 170 SLI_header->uid = lrecord_uid_counter++; \ |
171 } while (0) | 171 } while (0) |
172 #endif /* not MC_ALLOC */ | 172 #endif /* not NEW_GC */ |
173 | 173 |
174 #ifndef MC_ALLOC | 174 #ifndef NEW_GC |
175 struct old_lcrecord_header | 175 struct old_lcrecord_header |
176 { | 176 { |
177 struct lrecord_header lheader; | 177 struct lrecord_header lheader; |
178 | 178 |
179 /* The `next' field is normally used to chain all lcrecords together | 179 /* The `next' field is normally used to chain all lcrecords together |
207 struct free_lcrecord_header | 207 struct free_lcrecord_header |
208 { | 208 { |
209 struct old_lcrecord_header lcheader; | 209 struct old_lcrecord_header lcheader; |
210 Lisp_Object chain; | 210 Lisp_Object chain; |
211 }; | 211 }; |
212 #endif /* not MC_ALLOC */ | 212 #endif /* not NEW_GC */ |
213 | 213 |
214 enum lrecord_type | 214 enum lrecord_type |
215 { | 215 { |
216 /* Symbol value magic types come first to make SYMBOL_VALUE_MAGIC_P fast. | 216 /* Symbol value magic types come first to make SYMBOL_VALUE_MAGIC_P fast. |
217 #### This should be replaced by a symbol_value_magic_p flag | 217 #### This should be replaced by a symbol_value_magic_p flag |
224 lrecord_type_symbol, | 224 lrecord_type_symbol, |
225 lrecord_type_subr, | 225 lrecord_type_subr, |
226 lrecord_type_cons, | 226 lrecord_type_cons, |
227 lrecord_type_vector, | 227 lrecord_type_vector, |
228 lrecord_type_string, | 228 lrecord_type_string, |
229 #ifndef MC_ALLOC | 229 #ifndef NEW_GC |
230 lrecord_type_lcrecord_list, | 230 lrecord_type_lcrecord_list, |
231 #endif /* not MC_ALLOC */ | 231 #endif /* not NEW_GC */ |
232 lrecord_type_compiled_function, | 232 lrecord_type_compiled_function, |
233 lrecord_type_weak_list, | 233 lrecord_type_weak_list, |
234 lrecord_type_bit_vector, | 234 lrecord_type_bit_vector, |
235 lrecord_type_float, | 235 lrecord_type_float, |
236 lrecord_type_hash_table, | 236 lrecord_type_hash_table, |
295 lrecord_type_weak_box, | 295 lrecord_type_weak_box, |
296 lrecord_type_ephemeron, | 296 lrecord_type_ephemeron, |
297 lrecord_type_bignum, | 297 lrecord_type_bignum, |
298 lrecord_type_ratio, | 298 lrecord_type_ratio, |
299 lrecord_type_bigfloat, | 299 lrecord_type_bigfloat, |
300 #ifndef MC_ALLOC | 300 #ifndef NEW_GC |
301 lrecord_type_free, /* only used for "free" lrecords */ | 301 lrecord_type_free, /* only used for "free" lrecords */ |
302 lrecord_type_undefined, /* only used for debugging */ | 302 lrecord_type_undefined, /* only used for debugging */ |
303 #endif /* not MC_ALLOC */ | 303 #endif /* not NEW_GC */ |
304 #ifdef NEW_GC | 304 #ifdef NEW_GC |
305 lrecord_type_string_indirect_data, | 305 lrecord_type_string_indirect_data, |
306 lrecord_type_string_direct_data, | 306 lrecord_type_string_direct_data, |
307 lrecord_type_hash_table_entry, | 307 lrecord_type_hash_table_entry, |
308 lrecord_type_syntax_cache, | 308 lrecord_type_syntax_cache, |
398 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); | 398 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); |
399 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); | 399 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); |
400 int (*remprop) (Lisp_Object obj, Lisp_Object prop); | 400 int (*remprop) (Lisp_Object obj, Lisp_Object prop); |
401 Lisp_Object (*plist) (Lisp_Object obj); | 401 Lisp_Object (*plist) (Lisp_Object obj); |
402 | 402 |
403 #ifdef MC_ALLOC | 403 #ifdef NEW_GC |
404 /* Only one of `static_size' and `size_in_bytes_method' is non-0. */ | 404 /* Only one of `static_size' and `size_in_bytes_method' is non-0. */ |
405 #else /* not MC_ALLOC */ | 405 #else /* not NEW_GC */ |
406 /* Only one of `static_size' and `size_in_bytes_method' is non-0. | 406 /* Only one of `static_size' and `size_in_bytes_method' is non-0. |
407 If both are 0, this type is not instantiable by | 407 If both are 0, this type is not instantiable by |
408 old_basic_alloc_lcrecord(). */ | 408 old_basic_alloc_lcrecord(). */ |
409 #endif /* not MC_ALLOC */ | 409 #endif /* not NEW_GC */ |
410 Bytecount static_size; | 410 Bytecount static_size; |
411 Bytecount (*size_in_bytes_method) (const void *header); | 411 Bytecount (*size_in_bytes_method) (const void *header); |
412 | 412 |
413 /* The (constant) index into lrecord_implementations_table */ | 413 /* The (constant) index into lrecord_implementations_table */ |
414 enum lrecord_type lrecord_type_index; | 414 enum lrecord_type lrecord_type_index; |
415 | 415 |
416 #ifndef MC_ALLOC | 416 #ifndef NEW_GC |
417 /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e. | 417 /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e. |
418 one that does not have an old_lcrecord_header at the front and which | 418 one that does not have an old_lcrecord_header at the front and which |
419 is (usually) allocated in frob blocks. */ | 419 is (usually) allocated in frob blocks. */ |
420 unsigned int basic_p :1; | 420 unsigned int basic_p :1; |
421 #endif /* not MC_ALLOC */ | 421 #endif /* not NEW_GC */ |
422 }; | 422 }; |
423 | 423 |
424 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. | 424 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. |
425 Additional ones may be defined by a module (none yet). We leave some | 425 Additional ones may be defined by a module (none yet). We leave some |
426 room in `lrecord_implementations_table' for such new lisp object types. */ | 426 room in `lrecord_implementations_table' for such new lisp object types. */ |
439 #include "vdb.h" | 439 #include "vdb.h" |
440 #endif /* NEW_GC */ | 440 #endif /* NEW_GC */ |
441 | 441 |
442 extern int gc_in_progress; | 442 extern int gc_in_progress; |
443 | 443 |
444 #ifdef MC_ALLOC | 444 #ifdef NEW_GC |
445 #include "mc-alloc.h" | 445 #include "mc-alloc.h" |
446 | 446 |
447 #ifdef ALLOC_TYPE_STATS | 447 #ifdef ALLOC_TYPE_STATS |
448 void init_lrecord_stats (void); | 448 void init_lrecord_stats (void); |
449 void inc_lrecord_stats (Bytecount size, const struct lrecord_header *h); | 449 void inc_lrecord_stats (Bytecount size, const struct lrecord_header *h); |
451 const struct lrecord_header *h); | 451 const struct lrecord_header *h); |
452 int lrecord_stats_heap_size (void); | 452 int lrecord_stats_heap_size (void); |
453 #endif /* ALLOC_TYPE_STATS */ | 453 #endif /* ALLOC_TYPE_STATS */ |
454 | 454 |
455 /* Tell mc-alloc how to call a finalizer. */ | 455 /* Tell mc-alloc how to call a finalizer. */ |
456 #ifdef NEW_GC | |
457 #define MC_ALLOC_CALL_FINALIZER(ptr) \ | 456 #define MC_ALLOC_CALL_FINALIZER(ptr) \ |
458 { \ | 457 { \ |
459 Lisp_Object MCACF_obj = wrap_pointer_1 (ptr); \ | 458 Lisp_Object MCACF_obj = wrap_pointer_1 (ptr); \ |
460 struct lrecord_header *MCACF_lheader = XRECORD_LHEADER (MCACF_obj); \ | 459 struct lrecord_header *MCACF_lheader = XRECORD_LHEADER (MCACF_obj); \ |
461 if (XRECORD_LHEADER (MCACF_obj) && LRECORDP (MCACF_obj) \ | 460 if (XRECORD_LHEADER (MCACF_obj) && LRECORDP (MCACF_obj) \ |
468 GC_STAT_FINALIZED; \ | 467 GC_STAT_FINALIZED; \ |
469 MCACF_implementation->finalizer (ptr, 0); \ | 468 MCACF_implementation->finalizer (ptr, 0); \ |
470 } \ | 469 } \ |
471 } \ | 470 } \ |
472 } while (0) | 471 } while (0) |
473 #else /* not NEW_GC */ | |
474 #define MC_ALLOC_CALL_FINALIZER(ptr) \ | |
475 { \ | |
476 Lisp_Object MCACF_obj = wrap_pointer_1 (ptr); \ | |
477 struct lrecord_header *MCACF_lheader = XRECORD_LHEADER (MCACF_obj); \ | |
478 if (XRECORD_LHEADER (MCACF_obj) && LRECORDP (MCACF_obj) \ | |
479 && !LRECORD_FREE_P (MCACF_lheader) ) \ | |
480 { \ | |
481 const struct lrecord_implementation *MCACF_implementation \ | |
482 = LHEADER_IMPLEMENTATION (MCACF_lheader); \ | |
483 if (MCACF_implementation && MCACF_implementation->finalizer) \ | |
484 MCACF_implementation->finalizer (ptr, 0); \ | |
485 } \ | |
486 } while (0) | |
487 #endif /* not NEW_GC */ | |
488 | 472 |
489 /* Tell mc-alloc how to call a finalizer for disksave. */ | 473 /* Tell mc-alloc how to call a finalizer for disksave. */ |
490 #define MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE(ptr) \ | 474 #define MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE(ptr) \ |
491 { \ | 475 { \ |
492 Lisp_Object MCACF_obj = wrap_pointer_1 (ptr); \ | 476 Lisp_Object MCACF_obj = wrap_pointer_1 (ptr); \ |
519 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \ | 503 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \ |
520 ((void) ((lheader)->lisp_readonly = 1)) | 504 ((void) ((lheader)->lisp_readonly = 1)) |
521 #define MARK_LRECORD_AS_LISP_READONLY(ptr) \ | 505 #define MARK_LRECORD_AS_LISP_READONLY(ptr) \ |
522 ((void) (((struct lrecord_header *) ptr)->lisp_readonly = 1)) | 506 ((void) (((struct lrecord_header *) ptr)->lisp_readonly = 1)) |
523 | 507 |
524 #else /* not MC_ALLOC */ | 508 #else /* not NEW_GC */ |
525 | 509 |
526 #define LRECORD_FREE_P(ptr) \ | 510 #define LRECORD_FREE_P(ptr) \ |
527 (((struct lrecord_header *) ptr)->type == lrecord_type_free) | 511 (((struct lrecord_header *) ptr)->type == lrecord_type_free) |
528 | 512 |
529 #define MARK_LRECORD_AS_FREE(ptr) \ | 513 #define MARK_LRECORD_AS_FREE(ptr) \ |
542 SCRRH_lheader->lisp_readonly = 1; \ | 526 SCRRH_lheader->lisp_readonly = 1; \ |
543 SCRRH_lheader->mark = 1; \ | 527 SCRRH_lheader->mark = 1; \ |
544 } while (0) | 528 } while (0) |
545 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \ | 529 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \ |
546 ((void) ((lheader)->lisp_readonly = 1)) | 530 ((void) ((lheader)->lisp_readonly = 1)) |
547 #endif /* not MC_ALLOC */ | 531 #endif /* not NEW_GC */ |
548 | 532 |
549 #ifdef USE_KKCC | 533 #ifdef USE_KKCC |
550 #define RECORD_DESCRIPTION(lheader) lrecord_memory_descriptions[(lheader)->type] | 534 #define RECORD_DESCRIPTION(lheader) lrecord_memory_descriptions[(lheader)->type] |
551 #else /* not USE_KKCC */ | 535 #else /* not USE_KKCC */ |
552 #define RECORD_MARKER(lheader) lrecord_markers[(lheader)->type] | 536 #define RECORD_MARKER(lheader) lrecord_markers[(lheader)->type] |
1052 XD_FLAG_NO_KKCC = 1, | 1036 XD_FLAG_NO_KKCC = 1, |
1053 /* If set, pdump does not process this entry. */ | 1037 /* If set, pdump does not process this entry. */ |
1054 XD_FLAG_NO_PDUMP = 2, | 1038 XD_FLAG_NO_PDUMP = 2, |
1055 /* Indicates that this is a "default" entry in a union map. */ | 1039 /* Indicates that this is a "default" entry in a union map. */ |
1056 XD_FLAG_UNION_DEFAULT_ENTRY = 4, | 1040 XD_FLAG_UNION_DEFAULT_ENTRY = 4, |
1057 #ifndef MC_ALLOC | 1041 #ifndef NEW_GC |
1058 /* Indicates that this is a free Lisp object we're marking. | 1042 /* Indicates that this is a free Lisp object we're marking. |
1059 Only relevant for ERROR_CHECK_GC. This occurs when we're marking | 1043 Only relevant for ERROR_CHECK_GC. This occurs when we're marking |
1060 lcrecord-lists, where the objects have had their type changed to | 1044 lcrecord-lists, where the objects have had their type changed to |
1061 lrecord_type_free and also have had their free bit set, but we mark | 1045 lrecord_type_free and also have had their free bit set, but we mark |
1062 them as normal. */ | 1046 them as normal. */ |
1063 XD_FLAG_FREE_LISP_OBJECT = 8 | 1047 XD_FLAG_FREE_LISP_OBJECT = 8 |
1064 #endif /* not MC_ALLOC */ | 1048 #endif /* not NEW_GC */ |
1065 #if 0 | 1049 #if 0 |
1066 , | 1050 , |
1067 /* Suggestions for other possible flags: */ | 1051 /* Suggestions for other possible flags: */ |
1068 | 1052 |
1069 /* Eliminate XD_UNION_DYNAMIC_SIZE and replace it with a flag, like this. */ | 1053 /* Eliminate XD_UNION_DYNAMIC_SIZE and replace it with a flag, like this. */ |
1186 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype) | 1170 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype) |
1187 | 1171 |
1188 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | 1172 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ |
1189 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | 1173 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) |
1190 | 1174 |
1191 #ifdef MC_ALLOC | 1175 #ifdef NEW_GC |
1192 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 1176 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
1193 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 1177 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
1194 const struct lrecord_implementation lrecord_##c_name = \ | 1178 const struct lrecord_implementation lrecord_##c_name = \ |
1195 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 1179 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
1196 getprop, putprop, remprop, plist, size, sizer, \ | 1180 getprop, putprop, remprop, plist, size, sizer, \ |
1197 lrecord_type_##c_name } | 1181 lrecord_type_##c_name } |
1198 #else /* not MC_ALLOC */ | 1182 #else /* not NEW_GC */ |
1199 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 1183 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
1200 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 1184 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
1201 const struct lrecord_implementation lrecord_##c_name = \ | 1185 const struct lrecord_implementation lrecord_##c_name = \ |
1202 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 1186 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
1203 getprop, putprop, remprop, plist, size, sizer, \ | 1187 getprop, putprop, remprop, plist, size, sizer, \ |
1204 lrecord_type_##c_name, basic_p } | 1188 lrecord_type_##c_name, basic_p } |
1205 #endif /* not MC_ALLOC */ | 1189 #endif /* not NEW_GC */ |
1206 | 1190 |
1207 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ | 1191 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ |
1208 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) | 1192 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) |
1209 | 1193 |
1210 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ | 1194 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ |
1214 DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) | 1198 DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) |
1215 | 1199 |
1216 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | 1200 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ |
1217 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | 1201 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) |
1218 | 1202 |
1219 #ifdef MC_ALLOC | 1203 #ifdef NEW_GC |
1220 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 1204 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
1221 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 1205 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
1222 int lrecord_type_##c_name; \ | 1206 int lrecord_type_##c_name; \ |
1223 struct lrecord_implementation lrecord_##c_name = \ | 1207 struct lrecord_implementation lrecord_##c_name = \ |
1224 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 1208 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
1225 getprop, putprop, remprop, plist, size, sizer, \ | 1209 getprop, putprop, remprop, plist, size, sizer, \ |
1226 lrecord_type_last_built_in_type } | 1210 lrecord_type_last_built_in_type } |
1227 #else /* not MC_ALLOC */ | 1211 #else /* not NEW_GC */ |
1228 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 1212 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
1229 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 1213 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
1230 int lrecord_type_##c_name; \ | 1214 int lrecord_type_##c_name; \ |
1231 struct lrecord_implementation lrecord_##c_name = \ | 1215 struct lrecord_implementation lrecord_##c_name = \ |
1232 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 1216 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
1233 getprop, putprop, remprop, plist, size, sizer, \ | 1217 getprop, putprop, remprop, plist, size, sizer, \ |
1234 lrecord_type_last_built_in_type, basic_p } | 1218 lrecord_type_last_built_in_type, basic_p } |
1235 #endif /* not MC_ALLOC */ | 1219 #endif /* not NEW_GC */ |
1236 | 1220 |
1237 #ifdef USE_KKCC | 1221 #ifdef USE_KKCC |
1238 extern MODULE_API const struct memory_description *lrecord_memory_descriptions[]; | 1222 extern MODULE_API const struct memory_description *lrecord_memory_descriptions[]; |
1239 | 1223 |
1240 #define INIT_LRECORD_IMPLEMENTATION(type) do { \ | 1224 #define INIT_LRECORD_IMPLEMENTATION(type) do { \ |
1586 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \ | 1570 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \ |
1587 if (XTYPE (x) != lisp_enum) \ | 1571 if (XTYPE (x) != lisp_enum) \ |
1588 dead_wrong_type_argument (predicate, x); \ | 1572 dead_wrong_type_argument (predicate, x); \ |
1589 } while (0) | 1573 } while (0) |
1590 | 1574 |
1591 #ifndef MC_ALLOC | 1575 #ifndef NEW_GC |
1592 /*-------------------------- lcrecord-list -----------------------------*/ | 1576 /*-------------------------- lcrecord-list -----------------------------*/ |
1593 | 1577 |
1594 struct lcrecord_list | 1578 struct lcrecord_list |
1595 { | 1579 { |
1596 struct LCRECORD_HEADER header; | 1580 struct LCRECORD_HEADER header; |
1721 memset ((Rawbyte *) (lcr) + sizeof (struct old_lcrecord_header), 0, \ | 1705 memset ((Rawbyte *) (lcr) + sizeof (struct old_lcrecord_header), 0, \ |
1722 (size) - sizeof (struct old_lcrecord_header)) | 1706 (size) - sizeof (struct old_lcrecord_header)) |
1723 | 1707 |
1724 #define old_zero_lcrecord(lcr) old_zero_sized_lcrecord (lcr, sizeof (*(lcr))) | 1708 #define old_zero_lcrecord(lcr) old_zero_sized_lcrecord (lcr, sizeof (*(lcr))) |
1725 | 1709 |
1726 #else /* MC_ALLOC */ | 1710 #else /* NEW_GC */ |
1727 | 1711 |
1728 /* How to allocate a lrecord: | 1712 /* How to allocate a lrecord: |
1729 | 1713 |
1730 - If the size of the lrecord is fix, say it equals its size of its | 1714 - If the size of the lrecord is fix, say it equals its size of its |
1731 struct, then use alloc_lrecord_type. | 1715 struct, then use alloc_lrecord_type. |
1765 (char *) (src) + sizeof (struct lrecord_header), \ | 1749 (char *) (src) + sizeof (struct lrecord_header), \ |
1766 (size) - sizeof (struct lrecord_header)) | 1750 (size) - sizeof (struct lrecord_header)) |
1767 | 1751 |
1768 #define copy_lrecord(dst, src) copy_sized_lrecord (dst, src, sizeof (*(dst))) | 1752 #define copy_lrecord(dst, src) copy_sized_lrecord (dst, src, sizeof (*(dst))) |
1769 | 1753 |
1770 #endif /* MC_ALLOC */ | 1754 #endif /* NEW_GC */ |
1771 | 1755 |
1772 #define zero_sized_lrecord(lcr, size) \ | 1756 #define zero_sized_lrecord(lcr, size) \ |
1773 memset ((char *) (lcr) + sizeof (struct lrecord_header), 0, \ | 1757 memset ((char *) (lcr) + sizeof (struct lrecord_header), 0, \ |
1774 (size) - sizeof (struct lrecord_header)) | 1758 (size) - sizeof (struct lrecord_header)) |
1775 | 1759 |
1884 Used during startup to detect startup of dumped Emacs. */ | 1868 Used during startup to detect startup of dumped Emacs. */ |
1885 extern MODULE_API int initialized; | 1869 extern MODULE_API int initialized; |
1886 | 1870 |
1887 #ifdef PDUMP | 1871 #ifdef PDUMP |
1888 #include "dumper.h" | 1872 #include "dumper.h" |
1889 #ifdef MC_ALLOC | 1873 #ifdef NEW_GC |
1890 #define DUMPEDP(adr) 0 | 1874 #define DUMPEDP(adr) 0 |
1891 #else /* not MC_ALLOC */ | 1875 #else /* not NEW_GC */ |
1892 #define DUMPEDP(adr) ((((Rawbyte *) (adr)) < pdump_end) && \ | 1876 #define DUMPEDP(adr) ((((Rawbyte *) (adr)) < pdump_end) && \ |
1893 (((Rawbyte *) (adr)) >= pdump_start)) | 1877 (((Rawbyte *) (adr)) >= pdump_start)) |
1894 #endif /* not MC_ALLOC */ | 1878 #endif /* not NEW_GC */ |
1895 #else | 1879 #else |
1896 #define DUMPEDP(adr) 0 | 1880 #define DUMPEDP(adr) 0 |
1897 #endif | 1881 #endif |
1898 | 1882 |
1899 #define OBJECT_DUMPED_P(obj) DUMPEDP (XPNTR (obj)) | 1883 #define OBJECT_DUMPED_P(obj) DUMPEDP (XPNTR (obj)) |