Mercurial > hg > xemacs-beta
comparison src/lrecord.h @ 4930:9f04877ce07e
fix up comments about finalizers and NEWGC internal objects
-------------------- ChangeLog entries follow: --------------------
src/ChangeLog addition:
2010-01-20 Ben Wing <ben@xemacs.org>
* lrecord.h:
* lrecord.h (enum lrecord_type):
* lrecord.h (struct lrecord_implementation):
Clean up description of finalizer methods. Clean up and expand
the long comment at the top of lrecord.h. Add a section about why
New-GC requires a bunch of new internal objects to be created (not
completely understood).
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 20 Jan 2010 04:20:49 -0600 |
parents | 91b3d00e717f |
children | 94bba904528c |
comparison
equal
deleted
inserted
replaced
4929:b5ad8cf9f6e4 | 4930:9f04877ce07e |
---|---|
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 Ben Wing. | 3 Copyright (C) 1996, 2001, 2002, 2004, 2005, 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 #ifdef NEW_GC | 29 /* The "lrecord" type of Lisp object is used for all object types other |
30 /* The "lrecord" type of Lisp object is used for all object types | 30 than a few simple ones (like char and int). This allows many types to be |
31 other than a few simple ones (like char and int). This allows many | 31 implemented but only a few bits required in a Lisp object for type |
32 types to be implemented but only a few bits required in a Lisp | 32 information. (The tradeoff is that each object has its type marked in |
33 object for type information. (The tradeoff is that each object has | 33 it, thereby increasing its size.) All lrecords begin with a `struct |
34 its type marked in it, thereby increasing its size.) All lrecords | 34 lrecord_header', which identifies the lisp object type, by providing an |
35 begin with a `struct lrecord_header', which identifies the lisp | 35 index into a table of `struct lrecord_implementation', which describes |
36 object type, by providing an index into a table of `struct | 36 the behavior of the lisp object. It also contains some other data bits. |
37 lrecord_implementation', which describes the behavior of the lisp | 37 |
38 object. It also contains some other data bits. | 38 #ifndef NEW_GC |
39 | 39 Lrecords are of two types: straight lrecords, and lcrecords. |
40 Creating a new lrecord type is fairly easy; just follow the | 40 Straight lrecords are used for those types of objects that have |
41 their own allocation routines (typically allocated out of 2K chunks | |
42 of memory called `frob blocks'). These objects have a `struct | |
43 lrecord_header' at the top, containing only the bits needed to find | |
44 the lrecord_implementation for the object. There are special | |
45 routines in alloc.c to create an object of each such type. | |
46 | |
47 Lcrecords are used for less common sorts of objects that don't do | |
48 their own allocation. Each such object is malloc()ed individually, | |
49 and the objects are chained together through a `next' pointer. | |
50 Lcrecords have a `struct old_lcrecord_header' at the top, which | |
51 contains a `struct lrecord_header' and a `next' pointer, and are | |
52 allocated using old_alloc_lcrecord_type() or its variants. | |
53 #endif | |
54 | |
55 Creating a new Lisp object type is fairly easy; just follow the | |
41 lead of some existing type (e.g. hash tables). Note that you | 56 lead of some existing type (e.g. hash tables). Note that you |
42 do not need to supply all the methods (see below); reasonable | 57 do not need to supply all the methods (see below); reasonable |
43 defaults are provided for many of them. Alternatively, if you're | 58 defaults are provided for many of them. Alternatively, if you're |
44 just looking for a way of encapsulating data (which possibly | 59 just looking for a way of encapsulating data (which possibly |
45 could contain Lisp_Objects in it), you may well be able to use | 60 could contain Lisp_Objects in it), you may well be able to use |
46 the opaque type. | 61 the opaque type. |
47 */ | 62 */ |
48 #else /* not NEW_GC */ | 63 |
49 /* The "lrecord" type of Lisp object is used for all object types | 64 #ifdef NEW_GC |
50 other than a few simple ones. This allows many types to be | 65 /* |
51 implemented but only a few bits required in a Lisp object for type | 66 There are some limitations under New-GC that lead to the creation of a |
52 information. (The tradeoff is that each object has its type marked | 67 large number of new internal object types. I'm not completely sure what |
53 in it, thereby increasing its size.) All lrecords begin with a | 68 all of them are, but they are at least partially related to limitations |
54 `struct lrecord_header', which identifies the lisp object type, by | 69 on finalizers. Something else must be going on as well, because |
55 providing an index into a table of `struct lrecord_implementation', | 70 non-dumpable, non-finalizable objects like devices and frames also have |
56 which describes the behavior of the lisp object. It also contains | 71 their window-system-specific substructures converted into Lisp objects. |
57 some other data bits. | 72 It must have something to do with the fact that these substructures |
58 | 73 contain pointers to Lisp objects, but it's not completely clear why -- |
59 Lrecords are of two types: straight lrecords, and lcrecords. | 74 object descriptions exist to indicate the size of these structures and |
60 Straight lrecords are used for those types of objects that have | 75 the Lisp object pointers within them. |
61 their own allocation routines (typically allocated out of 2K chunks | 76 |
62 of memory called `frob blocks'). These objects have a `struct | 77 At least one definite issue is that under New-GC dumpable objects cannot |
63 lrecord_header' at the top, containing only the bits needed to find | 78 contain any finalizers (see pdump_register_object()). This means that any |
64 the lrecord_implementation for the object. There are special | 79 substructures in dumpable objects that are allocated separately and |
65 routines in alloc.c to create an object of each such type. | 80 normally freed in a finalizer need instead to be made into actual Lisp |
66 | 81 objects. If those structures are Dynarrs, they need to be made into |
67 Lcrecords are used for less common sorts of objects that don't do | 82 Dynarr Lisp objects (e.g. face-cachel-dynarr or glyph-cachel-dynarr), |
68 their own allocation. Each such object is malloc()ed individually, | 83 which are created using Dynarr_lisp_new() or Dynarr_new_new2(). |
69 and the objects are chained together through a `next' pointer. | 84 Furthermore, the objects contained in the Dynarr also need to be Lisp |
70 Lcrecords have a `struct old_lcrecord_header' at the top, which | 85 objects (e.g. face-cachel or glyph-cachel). |
71 contains a `struct lrecord_header' and a `next' pointer, and are | 86 |
72 allocated using old_alloc_lcrecord_type() or its variants. | 87 --ben |
73 | 88 */ |
74 Creating a new lcrecord type is fairly easy; just follow the | 89 |
75 lead of some existing type (e.g. hash tables). Note that you | 90 #endif |
76 do not need to supply all the methods (see below); reasonable | 91 |
77 defaults are provided for many of them. Alternatively, if you're | 92 |
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 | |
80 the opaque type. --ben | |
81 */ | |
82 #endif /* not NEW_GC */ | |
83 | 93 |
84 #ifdef NEW_GC | 94 #ifdef NEW_GC |
85 #define ALLOC_LCRECORD_TYPE alloc_lrecord_type | 95 #define ALLOC_LCRECORD_TYPE alloc_lrecord_type |
86 #define COPY_SIZED_LCRECORD copy_sized_lrecord | 96 #define COPY_SIZED_LCRECORD copy_sized_lrecord |
87 #define COPY_LCRECORD copy_lrecord | 97 #define COPY_LCRECORD copy_lrecord |
303 #ifndef NEW_GC | 313 #ifndef NEW_GC |
304 lrecord_type_free, /* only used for "free" lrecords */ | 314 lrecord_type_free, /* only used for "free" lrecords */ |
305 lrecord_type_undefined, /* only used for debugging */ | 315 lrecord_type_undefined, /* only used for debugging */ |
306 #endif /* not NEW_GC */ | 316 #endif /* not NEW_GC */ |
307 #ifdef NEW_GC | 317 #ifdef NEW_GC |
318 /* See comment up top explaining why these extra object types must exist. */ | |
308 lrecord_type_string_indirect_data, | 319 lrecord_type_string_indirect_data, |
309 lrecord_type_string_direct_data, | 320 lrecord_type_string_direct_data, |
310 lrecord_type_hash_table_entry, | 321 lrecord_type_hash_table_entry, |
311 lrecord_type_syntax_cache, | 322 lrecord_type_syntax_cache, |
312 lrecord_type_buffer_text, | 323 lrecord_type_buffer_text, |
368 /* `printer' converts the object to a printed representation. | 379 /* `printer' converts the object to a printed representation. |
369 This can be NULL; in this case default_object_printer() will be | 380 This can be NULL; in this case default_object_printer() will be |
370 used instead. */ | 381 used instead. */ |
371 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag); | 382 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag); |
372 | 383 |
373 /* `finalizer' is called at GC time when the object is about to | 384 /* `finalizer' is called at GC time when the object is about to be freed, |
374 be freed, and at dump time (FOR_DISKSAVE will be non-zero in this | 385 and at dump time (FOR_DISKSAVE will be non-zero in this case). It |
375 case). It should perform any necessary cleanup (e.g. freeing | 386 should perform any necessary cleanup (e.g. freeing malloc()ed memory |
376 malloc()ed memory). This can be NULL, meaning no special | 387 or releasing objects created in external libraries, such as |
377 finalization is necessary. | 388 window-system windows or file handles). This can be NULL, meaning no |
378 | 389 special finalization is necessary. |
379 WARNING: remember that `finalizer' is called at dump time even | 390 |
380 though the object is not being freed. */ | 391 WARNING: remember that `finalizer' is called at dump time even though |
392 the object is not being freed -- check the FOR_DISKSAVE argument. */ | |
381 void (*finalizer) (void *header, int for_disksave); | 393 void (*finalizer) (void *header, int for_disksave); |
382 | 394 |
383 /* This can be NULL, meaning compare objects with EQ(). */ | 395 /* This can be NULL, meaning compare objects with EQ(). */ |
384 int (*equal) (Lisp_Object obj1, Lisp_Object obj2, int depth); | 396 int (*equal) (Lisp_Object obj1, Lisp_Object obj2, int depth); |
385 | 397 |