comparison src/lrecord.h @ 5127:a9c41067dd88 ben-lisp-object

more cleanups, terminology clarification, lots of doc work -------------------- ChangeLog entries follow: -------------------- man/ChangeLog addition: 2010-03-05 Ben Wing <ben@xemacs.org> * internals/internals.texi (Introduction to Allocation): * internals/internals.texi (Integers and Characters): * internals/internals.texi (Allocation from Frob Blocks): * internals/internals.texi (lrecords): * internals/internals.texi (Low-level allocation): Rewrite section on allocation of Lisp objects to reflect the new reality. Remove references to nonexistent XSETINT and XSETCHAR. modules/ChangeLog addition: 2010-03-05 Ben Wing <ben@xemacs.org> * postgresql/postgresql.c (allocate_pgconn): * postgresql/postgresql.c (allocate_pgresult): * postgresql/postgresql.h (struct Lisp_PGconn): * postgresql/postgresql.h (struct Lisp_PGresult): * ldap/eldap.c (allocate_ldap): * ldap/eldap.h (struct Lisp_LDAP): Same changes as in src/ dir. See large log there in ChangeLog, but basically: ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER ../hlo/src/ChangeLog addition: 2010-03-05 Ben Wing <ben@xemacs.org> * alloc.c: * alloc.c (old_alloc_sized_lcrecord): * alloc.c (very_old_free_lcrecord): * alloc.c (copy_lisp_object): * alloc.c (zero_sized_lisp_object): * alloc.c (zero_nonsized_lisp_object): * alloc.c (lisp_object_storage_size): * alloc.c (free_normal_lisp_object): * alloc.c (FREE_FIXED_TYPE_WHEN_NOT_IN_GC): * alloc.c (ALLOC_FROB_BLOCK_LISP_OBJECT): * alloc.c (Fcons): * alloc.c (noseeum_cons): * alloc.c (make_float): * alloc.c (make_bignum): * alloc.c (make_bignum_bg): * alloc.c (make_ratio): * alloc.c (make_ratio_bg): * alloc.c (make_ratio_rt): * alloc.c (make_bigfloat): * alloc.c (make_bigfloat_bf): * alloc.c (size_vector): * alloc.c (make_compiled_function): * alloc.c (Fmake_symbol): * alloc.c (allocate_extent): * alloc.c (allocate_event): * alloc.c (make_key_data): * alloc.c (make_button_data): * alloc.c (make_motion_data): * alloc.c (make_process_data): * alloc.c (make_timeout_data): * alloc.c (make_magic_data): * alloc.c (make_magic_eval_data): * alloc.c (make_eval_data): * alloc.c (make_misc_user_data): * alloc.c (Fmake_marker): * alloc.c (noseeum_make_marker): * alloc.c (size_string_direct_data): * alloc.c (make_uninit_string): * alloc.c (make_string_nocopy): * alloc.c (mark_lcrecord_list): * alloc.c (alloc_managed_lcrecord): * alloc.c (free_managed_lcrecord): * alloc.c (sweep_lcrecords_1): * alloc.c (malloced_storage_size): * buffer.c (allocate_buffer): * buffer.c (compute_buffer_usage): * buffer.c (DEFVAR_BUFFER_LOCAL_1): * buffer.c (nuke_all_buffer_slots): * buffer.c (common_init_complex_vars_of_buffer): * buffer.h (struct buffer_text): * buffer.h (struct buffer): * bytecode.c: * bytecode.c (make_compiled_function_args): * bytecode.c (size_compiled_function_args): * bytecode.h (struct compiled_function_args): * casetab.c (allocate_case_table): * casetab.h (struct Lisp_Case_Table): * charset.h (struct Lisp_Charset): * chartab.c (fill_char_table): * chartab.c (Fmake_char_table): * chartab.c (make_char_table_entry): * chartab.c (copy_char_table_entry): * chartab.c (Fcopy_char_table): * chartab.c (put_char_table): * chartab.h (struct Lisp_Char_Table_Entry): * chartab.h (struct Lisp_Char_Table): * console-gtk-impl.h (struct gtk_device): * console-gtk-impl.h (struct gtk_frame): * console-impl.h (struct console): * console-msw-impl.h (struct Lisp_Devmode): * console-msw-impl.h (struct mswindows_device): * console-msw-impl.h (struct msprinter_device): * console-msw-impl.h (struct mswindows_frame): * console-msw-impl.h (struct mswindows_dialog_id): * console-stream-impl.h (struct stream_console): * console-stream.c (stream_init_console): * console-tty-impl.h (struct tty_console): * console-tty-impl.h (struct tty_device): * console-tty.c (allocate_tty_console_struct): * console-x-impl.h (struct x_device): * console-x-impl.h (struct x_frame): * console.c (allocate_console): * console.c (nuke_all_console_slots): * console.c (DEFVAR_CONSOLE_LOCAL_1): * console.c (common_init_complex_vars_of_console): * data.c (make_weak_list): * data.c (make_weak_box): * data.c (make_ephemeron): * database.c: * database.c (struct Lisp_Database): * database.c (allocate_database): * database.c (finalize_database): * device-gtk.c (allocate_gtk_device_struct): * device-impl.h (struct device): * device-msw.c: * device-msw.c (mswindows_init_device): * device-msw.c (msprinter_init_device): * device-msw.c (finalize_devmode): * device-msw.c (allocate_devmode): * device-tty.c (allocate_tty_device_struct): * device-x.c (allocate_x_device_struct): * device.c: * device.c (nuke_all_device_slots): * device.c (allocate_device): * dialog-msw.c (handle_question_dialog_box): * elhash.c: * elhash.c (struct Lisp_Hash_Table): * elhash.c (finalize_hash_table): * elhash.c (make_general_lisp_hash_table): * elhash.c (Fcopy_hash_table): * elhash.h (htentry): * emacs.c (main_1): * eval.c: * eval.c (size_multiple_value): * event-stream.c (finalize_command_builder): * event-stream.c (allocate_command_builder): * event-stream.c (free_command_builder): * event-stream.c (event_stream_generate_wakeup): * event-stream.c (event_stream_resignal_wakeup): * event-stream.c (event_stream_disable_wakeup): * event-stream.c (event_stream_wakeup_pending_p): * events.h (struct Lisp_Timeout): * events.h (struct command_builder): * extents-impl.h: * extents-impl.h (struct extent_auxiliary): * extents-impl.h (struct extent_info): * extents-impl.h (set_extent_no_chase_aux_field): * extents-impl.h (set_extent_no_chase_normal_field): * extents.c: * extents.c (gap_array_marker): * extents.c (gap_array): * extents.c (extent_list_marker): * extents.c (extent_list): * extents.c (stack_of_extents): * extents.c (gap_array_make_marker): * extents.c (extent_list_make_marker): * extents.c (allocate_extent_list): * extents.c (SLOT): * extents.c (mark_extent_auxiliary): * extents.c (allocate_extent_auxiliary): * extents.c (attach_extent_auxiliary): * extents.c (size_gap_array): * extents.c (finalize_extent_info): * extents.c (allocate_extent_info): * extents.c (uninit_buffer_extents): * extents.c (allocate_soe): * extents.c (copy_extent): * extents.c (vars_of_extents): * extents.h: * faces.c (allocate_face): * faces.h (struct Lisp_Face): * faces.h (struct face_cachel): * file-coding.c: * file-coding.c (finalize_coding_system): * file-coding.c (sizeof_coding_system): * file-coding.c (Fcopy_coding_system): * file-coding.h (struct Lisp_Coding_System): * file-coding.h (MARKED_SLOT): * fns.c (size_bit_vector): * font-mgr.c: * font-mgr.c (finalize_fc_pattern): * font-mgr.c (print_fc_pattern): * font-mgr.c (Ffc_pattern_p): * font-mgr.c (Ffc_pattern_create): * font-mgr.c (Ffc_name_parse): * font-mgr.c (Ffc_name_unparse): * font-mgr.c (Ffc_pattern_duplicate): * font-mgr.c (Ffc_pattern_add): * font-mgr.c (Ffc_pattern_del): * font-mgr.c (Ffc_pattern_get): * font-mgr.c (fc_config_create_using): * font-mgr.c (fc_strlist_to_lisp_using): * font-mgr.c (fontset_to_list): * font-mgr.c (Ffc_config_p): * font-mgr.c (Ffc_config_up_to_date): * font-mgr.c (Ffc_config_build_fonts): * font-mgr.c (Ffc_config_get_cache): * font-mgr.c (Ffc_config_get_fonts): * font-mgr.c (Ffc_config_set_current): * font-mgr.c (Ffc_config_get_blanks): * font-mgr.c (Ffc_config_get_rescan_interval): * font-mgr.c (Ffc_config_set_rescan_interval): * font-mgr.c (Ffc_config_app_font_add_file): * font-mgr.c (Ffc_config_app_font_add_dir): * font-mgr.c (Ffc_config_app_font_clear): * font-mgr.c (size): * font-mgr.c (Ffc_config_substitute): * font-mgr.c (Ffc_font_render_prepare): * font-mgr.c (Ffc_font_match): * font-mgr.c (Ffc_font_sort): * font-mgr.c (finalize_fc_config): * font-mgr.c (print_fc_config): * font-mgr.h: * font-mgr.h (struct fc_pattern): * font-mgr.h (XFC_PATTERN): * font-mgr.h (struct fc_config): * font-mgr.h (XFC_CONFIG): * frame-gtk.c (allocate_gtk_frame_struct): * frame-impl.h (struct frame): * frame-msw.c (mswindows_init_frame_1): * frame-x.c (allocate_x_frame_struct): * frame.c (nuke_all_frame_slots): * frame.c (allocate_frame_core): * gc.c: * gc.c (GC_CHECK_NOT_FREE): * glyphs.c (finalize_image_instance): * glyphs.c (allocate_image_instance): * glyphs.c (Fcolorize_image_instance): * glyphs.c (allocate_glyph): * glyphs.c (unmap_subwindow_instance_cache_mapper): * glyphs.c (register_ignored_expose): * glyphs.h (struct Lisp_Image_Instance): * glyphs.h (struct Lisp_Glyph): * glyphs.h (struct glyph_cachel): * glyphs.h (struct expose_ignore): * gui.c (allocate_gui_item): * gui.h (struct Lisp_Gui_Item): * keymap.c (struct Lisp_Keymap): * keymap.c (make_keymap): * lisp.h: * lisp.h (struct Lisp_String_Direct_Data): * lisp.h (struct Lisp_String_Indirect_Data): * lisp.h (struct Lisp_Vector): * lisp.h (struct Lisp_Bit_Vector): * lisp.h (DECLARE_INLINE_LISP_BIT_VECTOR): * lisp.h (struct weak_box): * lisp.h (struct ephemeron): * lisp.h (struct weak_list): * lrecord.h: * lrecord.h (struct lrecord_implementation): * lrecord.h (MC_ALLOC_CALL_FINALIZER): * lrecord.h (struct lcrecord_list): * lstream.c (finalize_lstream): * lstream.c (sizeof_lstream): * lstream.c (Lstream_new): * lstream.c (Lstream_delete): * lstream.h (struct lstream): * marker.c: * marker.c (finalize_marker): * marker.c (compute_buffer_marker_usage): * mule-charset.c: * mule-charset.c (make_charset): * mule-charset.c (compute_charset_usage): * objects-impl.h (struct Lisp_Color_Instance): * objects-impl.h (struct Lisp_Font_Instance): * objects-tty-impl.h (struct tty_color_instance_data): * objects-tty-impl.h (struct tty_font_instance_data): * objects-tty.c (tty_initialize_color_instance): * objects-tty.c (tty_initialize_font_instance): * objects.c (finalize_color_instance): * objects.c (Fmake_color_instance): * objects.c (finalize_font_instance): * objects.c (Fmake_font_instance): * objects.c (reinit_vars_of_objects): * opaque.c: * opaque.c (sizeof_opaque): * opaque.c (make_opaque_ptr): * opaque.c (free_opaque_ptr): * opaque.h: * opaque.h (Lisp_Opaque): * opaque.h (Lisp_Opaque_Ptr): * print.c (printing_unreadable_lcrecord): * print.c (external_object_printer): * print.c (debug_p4): * process.c (finalize_process): * process.c (make_process_internal): * procimpl.h (struct Lisp_Process): * rangetab.c (Fmake_range_table): * rangetab.c (Fcopy_range_table): * rangetab.h (struct Lisp_Range_Table): * scrollbar.c: * scrollbar.c (create_scrollbar_instance): * scrollbar.c (compute_scrollbar_instance_usage): * scrollbar.h (struct scrollbar_instance): * specifier.c (finalize_specifier): * specifier.c (sizeof_specifier): * specifier.c (set_specifier_caching): * specifier.h (struct Lisp_Specifier): * specifier.h (struct specifier_caching): * symeval.h: * symeval.h (SYMBOL_VALUE_MAGIC_P): * symeval.h (DEFVAR_SYMVAL_FWD): * symsinit.h: * syntax.c (init_buffer_syntax_cache): * syntax.h (struct syntax_cache): * toolbar.c: * toolbar.c (allocate_toolbar_button): * toolbar.c (update_toolbar_button): * toolbar.h (struct toolbar_button): * tooltalk.c (struct Lisp_Tooltalk_Message): * tooltalk.c (make_tooltalk_message): * tooltalk.c (struct Lisp_Tooltalk_Pattern): * tooltalk.c (make_tooltalk_pattern): * ui-gtk.c: * ui-gtk.c (allocate_ffi_data): * ui-gtk.c (emacs_gtk_object_finalizer): * ui-gtk.c (allocate_emacs_gtk_object_data): * ui-gtk.c (allocate_emacs_gtk_boxed_data): * ui-gtk.h: * window-impl.h (struct window): * window-impl.h (struct window_mirror): * window.c (finalize_window): * window.c (allocate_window): * window.c (new_window_mirror): * window.c (mark_window_as_deleted): * window.c (make_dummy_parent): * window.c (compute_window_mirror_usage): * window.c (compute_window_usage): Overall point of this change and previous ones in this repository: (1) Introduce new, clearer terminology: everything other than int or char is a "record" object, which comes in two types: "normal objects" and "frob-block objects". Fix up all places that referred to frob-block objects as "simple", "basic", etc. (2) Provide an advertised interface for doing operations on Lisp objects, including creating new types, that is clean and consistent in its naming, uses the above-referenced terms and avoids referencing "lrecords", "old lcrecords", etc., which should hide under the surface. (3) Make the size_in_bytes and finalizer methods take a Lisp_Object rather than a void * for consistency with other methods. (4) Separate finalizer method into finalizer and disksaver, so that normal finalize methods don't have to worry about disksaving. Other specifics: (1) Renaming: LISP_OBJECT_HEADER -> NORMAL_LISP_OBJECT_HEADER ALLOC_LISP_OBJECT -> ALLOC_NORMAL_LISP_OBJECT implementation->basic_p -> implementation->frob_block_p ALLOCATE_FIXED_TYPE_AND_SET_IMPL -> ALLOC_FROB_BLOCK_LISP_OBJECT *FCCONFIG*, wrap_fcconfig -> *FC_CONFIG*, wrap_fc_config *FCPATTERN*, wrap_fcpattern -> *FC_PATTERN*, wrap_fc_pattern (the last two changes make the naming of these macros consistent with the naming of all other macros, since the objects are named fc-config and fc-pattern with a hyphen) (2) Lots of documentation fixes in lrecord.h. (3) Eliminate macros for copying, freeing, zeroing objects, getting their storage size. Instead, new functions: zero_sized_lisp_object() zero_nonsized_lisp_object() lisp_object_storage_size() free_normal_lisp_object() (copy_lisp_object() already exists) LISP_OBJECT_FROB_BLOCK_P() (actually a macro) Eliminated: free_lrecord() zero_lrecord() copy_lrecord() copy_sized_lrecord() old_copy_lcrecord() old_copy_sized_lcrecord() old_zero_lcrecord() old_zero_sized_lcrecord() LISP_OBJECT_STORAGE_SIZE() COPY_SIZED_LISP_OBJECT() COPY_SIZED_LCRECORD() COPY_LISP_OBJECT() ZERO_LISP_OBJECT() FREE_LISP_OBJECT() (4) Catch the remaining places where lrecord stuff was used directly and use the advertised interface, e.g. alloc_sized_lrecord() -> ALLOC_SIZED_LISP_OBJECT(). (5) Make certain statically-declared pseudo-objects (buffer_local_flags, console_local_flags) have their lheader initialized correctly, so things like copy_lisp_object() can work on them. Make extent_auxiliary_defaults a proper heap object Vextent_auxiliary_defaults, and make extent auxiliaries dumpable so that this object can be dumped. allocate_extent_auxiliary() now just creates the object, and attach_extent_auxiliary() creates an extent auxiliary and attaches to an extent, like the old allocate_extent_auxiliary(). (6) Create EXTENT_AUXILIARY_SLOTS macro, similar to the foo-slots.h files but in a macro instead of a file. The purpose is to avoid duplication when iterating over all the slots in an extent auxiliary. Use it. (7) In lstream.c, don't zero out object after allocation because allocation routines take care of this. (8) In marker.c, fix a mistake in computing marker overhead. (9) In print.c, clean up printing_unreadable_lcrecord(), external_object_printer() to avoid lots of ifdef NEW_GC's. (10) Separate toolbar-button allocation into a separate allocate_toolbar_button() function for use in the example code in lrecord.h.
author Ben Wing <ben@xemacs.org>
date Fri, 05 Mar 2010 04:08:17 -0600
parents 2a462149bd6a
children 7be849cb8828
comparison
equal deleted inserted replaced
5126:2a462149bd6a 5127:a9c41067dd88
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_LISP_OBJECT(type) alloc_lrecord (&lrecord_##type) 188 #define ALLOC_NORMAL_LISP_OBJECT(type) alloc_lrecord (&lrecord_##type)
96 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ 189 #define ALLOC_SIZED_LISP_OBJECT(size, type) \
97 alloc_sized_lrecord (size, &lrecord_##type) 190 alloc_sized_lrecord (size, &lrecord_##type)
98 #define COPY_SIZED_LISP_OBJECT copy_sized_lrecord 191 #define NORMAL_LISP_OBJECT_HEADER struct lrecord_header
99 #define COPY_LISP_OBJECT copy_lrecord
100 #define LISP_OBJECT_STORAGE_SIZE(ptr, size, stats) \
101 mc_alloced_storage_size (size, stats)
102 #define ZERO_LISP_OBJECT zero_lrecord
103 #define LISP_OBJECT_HEADER struct lrecord_header
104 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header 192 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header
105 #define FREE_LISP_OBJECT free_lrecord 193 #define LISP_OBJECT_FROB_BLOCK_P(obj) 0
106 #else /* not NEW_GC */ 194 #else /* not NEW_GC */
107 #define ALLOC_LISP_OBJECT(type) alloc_automanaged_lcrecord (&lrecord_##type) 195 #define ALLOC_NORMAL_LISP_OBJECT(type) alloc_automanaged_lcrecord (&lrecord_##type)
108 #define ALLOC_SIZED_LISP_OBJECT(size, type) \ 196 #define ALLOC_SIZED_LISP_OBJECT(size, type) \
109 old_alloc_sized_lcrecord (size, &lrecord_##type) 197 old_alloc_sized_lcrecord (size, &lrecord_##type)
110 #define COPY_SIZED_LISP_OBJECT old_copy_sized_lcrecord 198 #define NORMAL_LISP_OBJECT_HEADER struct old_lcrecord_header
111 #define COPY_LISP_OBJECT old_copy_lcrecord
112 #define LISP_OBJECT_STORAGE_SIZE malloced_storage_size
113 #define ZERO_LISP_OBJECT old_zero_lcrecord
114 #define LISP_OBJECT_HEADER struct old_lcrecord_header
115 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header 199 #define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header
116 #define FREE_LISP_OBJECT old_free_lcrecord 200 #define LISP_OBJECT_FROB_BLOCK_P(obj) (XRECORD_LHEADER_IMPLEMENTATION(obj)->frob_block_p)
117 #endif /* not NEW_GC */ 201 #endif /* not NEW_GC */
118 202
119 BEGIN_C_DECLS 203 BEGIN_C_DECLS
120 204
121 struct lrecord_header 205 struct lrecord_header
391 /* `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.
392 It should perform any necessary cleanup, such as freeing malloc()ed 476 It should perform any necessary cleanup, such as freeing malloc()ed
393 memory or releasing pointers or handles to objects created in external 477 memory or releasing pointers or handles to objects created in external
394 libraries, such as window-system windows or file handles. This can be 478 libraries, such as window-system windows or file handles. This can be
395 NULL, meaning no special finalization is necessary. */ 479 NULL, meaning no special finalization is necessary. */
396 void (*finalizer) (void *header); 480 void (*finalizer) (Lisp_Object obj);
397 481
398 /* This can be NULL, meaning compare objects with EQ(). */ 482 /* This can be NULL, meaning compare objects with EQ(). */
399 int (*equal) (Lisp_Object obj1, Lisp_Object obj2, int depth, 483 int (*equal) (Lisp_Object obj1, Lisp_Object obj2, int depth,
400 int foldcase); 484 int foldcase);
401 485
434 be NULL. */ 518 be NULL. */
435 void (*disksaver) (Lisp_Object); 519 void (*disksaver) (Lisp_Object);
436 520
437 /* Only one of `static_size' and `size_in_bytes_method' is non-0. If 521 /* Only one of `static_size' and `size_in_bytes_method' is non-0. If
438 `static_size' is 0, this type is not instantiable by 522 `static_size' is 0, this type is not instantiable by
439 ALLOC_LISP_OBJECT(). If both are 0 (this should never happen), this 523 ALLOC_NORMAL_LISP_OBJECT(). If both are 0 (this should never happen),
440 object cannot be instantiated; you will get an abort() if you try.*/ 524 this object cannot be instantiated; you will get an abort() if you
525 try.*/
441 Bytecount static_size; 526 Bytecount static_size;
442 Bytecount (*size_in_bytes_method) (const void *header); 527 Bytecount (*size_in_bytes_method) (Lisp_Object);
443 528
444 /* The (constant) index into lrecord_implementations_table */ 529 /* The (constant) index into lrecord_implementations_table */
445 enum lrecord_type lrecord_type_index; 530 enum lrecord_type lrecord_type_index;
446 531
447 #ifndef NEW_GC 532 #ifndef NEW_GC
448 /* 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.
449 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
450 is (usually) allocated in frob blocks. */ 535 is (usually) allocated in frob blocks. */
451 unsigned int basic_p :1; 536 unsigned int frob_block_p :1;
452 #endif /* not NEW_GC */ 537 #endif /* not NEW_GC */
453 }; 538 };
454 539
455 /* 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'.
456 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
458 #define MODULE_DEFINABLE_TYPE_COUNT 32 543 #define MODULE_DEFINABLE_TYPE_COUNT 32
459 544
460 extern MODULE_API const struct lrecord_implementation * 545 extern MODULE_API const struct lrecord_implementation *
461 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];
462 547
548 /* Given a Lisp object, return its implementation
549 (struct lrecord_implementation) */
463 #define XRECORD_LHEADER_IMPLEMENTATION(obj) \ 550 #define XRECORD_LHEADER_IMPLEMENTATION(obj) \
464 LHEADER_IMPLEMENTATION (XRECORD_LHEADER (obj)) 551 LHEADER_IMPLEMENTATION (XRECORD_LHEADER (obj))
465 #define LHEADER_IMPLEMENTATION(lh) lrecord_implementations_table[(lh)->type] 552 #define LHEADER_IMPLEMENTATION(lh) lrecord_implementations_table[(lh)->type]
466 553
467 #include "gc.h" 554 #include "gc.h"
494 const struct lrecord_implementation *MCACF_implementation \ 581 const struct lrecord_implementation *MCACF_implementation \
495 = LHEADER_IMPLEMENTATION (MCACF_lheader); \ 582 = LHEADER_IMPLEMENTATION (MCACF_lheader); \
496 if (MCACF_implementation && MCACF_implementation->finalizer) \ 583 if (MCACF_implementation && MCACF_implementation->finalizer) \
497 { \ 584 { \
498 GC_STAT_FINALIZED; \ 585 GC_STAT_FINALIZED; \
499 MCACF_implementation->finalizer (ptr); \ 586 MCACF_implementation->finalizer (MCACF_obj); \
500 } \ 587 } \
501 } \ 588 } \
502 } while (0) 589 } while (0)
503 590
504 /* Tell mc-alloc how to call a finalizer for disksave. */ 591 /* Tell mc-alloc how to call a finalizer for disksave. */
767 Lisp_Object value; 854 Lisp_Object value;
768 } htentry; 855 } htentry;
769 856
770 struct Lisp_Hash_Table 857 struct Lisp_Hash_Table
771 { 858 {
772 LISP_OBJECT_HEADER header; 859 NORMAL_LISP_OBJECT_HEADER header;
773 Elemcount size; 860 Elemcount size;
774 Elemcount count; 861 Elemcount count;
775 Elemcount rehash_count; 862 Elemcount rehash_count;
776 double rehash_size; 863 double rehash_size;
777 double rehash_threshold; 864 double rehash_threshold;
832 ... 919 ...
833 }; 920 };
834 921
835 struct Lisp_Specifier 922 struct Lisp_Specifier
836 { 923 {
837 LISP_OBJECT_HEADER header; 924 NORMAL_LISP_OBJECT_HEADER header;
838 struct specifier_methods *methods; 925 struct specifier_methods *methods;
839 926
840 ... 927 ...
841 // type-specific extra data attached to a specifier 928 // type-specific extra data attached to a specifier
842 max_align_t data[1]; 929 max_align_t data[1];
1394 /* Steps to create a new object: 1481 /* Steps to create a new object:
1395 1482
1396 1. Declare the struct for your object in a header file somewhere. 1483 1. Declare the struct for your object in a header file somewhere.
1397 Remember that it must begin with 1484 Remember that it must begin with
1398 1485
1399 LISP_OBJECT_HEADER header; 1486 NORMAL_LISP_OBJECT_HEADER header;
1400 1487
1401 2. Put the "standard junk" (DECLARE_LISP_OBJECT()/XFOO/etc.) below the 1488 2. Put the "standard junk" (DECLARE_LISP_OBJECT()/XFOO/etc.) below the
1402 struct definition -- see below. 1489 struct definition -- see below.
1403 1490
1404 3. Add this header file to inline.c. 1491 3. Add this header file to inline.c.
1427 9. Add a type enum for the object to enum lrecord_type, earlier in this 1514 9. Add a type enum for the object to enum lrecord_type, earlier in this
1428 file. 1515 file.
1429 1516
1430 --ben 1517 --ben
1431 1518
1432 An example: 1519 An example:
1433 1520
1434 ------------------------------ in toolbar.h ----------------------------- 1521 ------------------------------ in toolbar.h -----------------------------
1435 1522
1436 struct toolbar_button 1523 struct toolbar_button
1437 { 1524 {
1438 LISP_OBJECT_HEADER header; 1525 NORMAL_LISP_OBJECT_HEADER header;
1439 1526
1440 Lisp_Object next; 1527 Lisp_Object next;
1441 Lisp_Object frame; 1528 Lisp_Object frame;
1442 1529
1443 Lisp_Object up_glyph; 1530 Lisp_Object up_glyph;
1444 Lisp_Object down_glyph; 1531 Lisp_Object down_glyph;
1445 Lisp_Object disabled_glyph; 1532 Lisp_Object disabled_glyph;
1446 1533
1447 Lisp_Object cap_up_glyph; 1534 Lisp_Object cap_up_glyph;
1448 Lisp_Object cap_down_glyph; 1535 Lisp_Object cap_down_glyph;
1449 Lisp_Object cap_disabled_glyph; 1536 Lisp_Object cap_disabled_glyph;
1450 1537
1451 Lisp_Object callback; 1538 Lisp_Object callback;
1452 Lisp_Object enabled_p; 1539 Lisp_Object enabled_p;
1453 Lisp_Object help_string; 1540 Lisp_Object help_string;
1454 1541
1455 char enabled; 1542 char enabled;
1456 char down; 1543 char down;
1457 char pushright; 1544 char pushright;
1458 char blank; 1545 char blank;
1459 1546
1460 int x, y; 1547 int x, y;
1461 int width, height; 1548 int width, height;
1462 int dirty; 1549 int dirty;
1463 int vertical; 1550 int vertical;
1464 int border_width; 1551 int border_width;
1465 }; 1552 };
1466 1553
1467 [[ the standard junk: ]] 1554 [[ the standard junk: ]]
1468 1555
1469 DECLARE_LISP_OBJECT (toolbar_button, struct toolbar_button); 1556 DECLARE_LISP_OBJECT (toolbar_button, struct toolbar_button);
1470 #define XTOOLBAR_BUTTON(x) XRECORD (x, toolbar_button, struct toolbar_button) 1557 #define XTOOLBAR_BUTTON(x) XRECORD (x, toolbar_button, struct toolbar_button)
1471 #define wrap_toolbar_button(p) wrap_record (p, toolbar_button) 1558 #define wrap_toolbar_button(p) wrap_record (p, toolbar_button)
1472 #define TOOLBAR_BUTTONP(x) RECORDP (x, toolbar_button) 1559 #define TOOLBAR_BUTTONP(x) RECORDP (x, toolbar_button)
1473 #define CHECK_TOOLBAR_BUTTON(x) CHECK_RECORD (x, toolbar_button) 1560 #define CHECK_TOOLBAR_BUTTON(x) CHECK_RECORD (x, toolbar_button)
1474 #define CONCHECK_TOOLBAR_BUTTON(x) CONCHECK_RECORD (x, toolbar_button) 1561 #define CONCHECK_TOOLBAR_BUTTON(x) CONCHECK_RECORD (x, toolbar_button)
1475 1562
1476 ------------------------------ in toolbar.c ----------------------------- 1563 ------------------------------ in toolbar.c -----------------------------
1477 1564
1478 #include "toolbar.h" 1565 #include "toolbar.h"
1479 1566
1480 ... 1567 ...
1481 1568
1482 static const struct memory_description toolbar_button_description [] = { 1569 static const struct memory_description toolbar_button_description [] = {
1483 { XD_LISP_OBJECT, offsetof (struct toolbar_button, next) }, 1570 { XD_LISP_OBJECT, offsetof (struct toolbar_button, next) },
1484 { XD_LISP_OBJECT, offsetof (struct toolbar_button, frame) }, 1571 { XD_LISP_OBJECT, offsetof (struct toolbar_button, frame) },
1485 { XD_LISP_OBJECT, offsetof (struct toolbar_button, up_glyph) }, 1572 { XD_LISP_OBJECT, offsetof (struct toolbar_button, up_glyph) },
1486 { XD_LISP_OBJECT, offsetof (struct toolbar_button, down_glyph) }, 1573 { XD_LISP_OBJECT, offsetof (struct toolbar_button, down_glyph) },
1487 { XD_LISP_OBJECT, offsetof (struct toolbar_button, disabled_glyph) }, 1574 { XD_LISP_OBJECT, offsetof (struct toolbar_button, disabled_glyph) },
1488 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_up_glyph) }, 1575 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_up_glyph) },
1489 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_down_glyph) }, 1576 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_down_glyph) },
1490 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_disabled_glyph) }, 1577 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_disabled_glyph) },
1491 { XD_LISP_OBJECT, offsetof (struct toolbar_button, callback) }, 1578 { XD_LISP_OBJECT, offsetof (struct toolbar_button, callback) },
1492 { XD_LISP_OBJECT, offsetof (struct toolbar_button, enabled_p) }, 1579 { XD_LISP_OBJECT, offsetof (struct toolbar_button, enabled_p) },
1493 { XD_LISP_OBJECT, offsetof (struct toolbar_button, help_string) }, 1580 { XD_LISP_OBJECT, offsetof (struct toolbar_button, help_string) },
1494 { XD_END } 1581 { XD_END }
1495 }; 1582 };
1496 1583
1497 static Lisp_Object 1584 static Lisp_Object
1498 mark_toolbar_button (Lisp_Object obj) 1585 allocate_toolbar_button (struct frame *f, int pushright)
1499 \{ 1586 {
1500 struct toolbar_button *data = XTOOLBAR_BUTTON (obj); 1587 struct toolbar_button *tb;
1501 mark_object (data->next); 1588
1502 mark_object (data->frame); 1589 tb = XTOOLBAR_BUTTON (ALLOC_NORMAL_LISP_OBJECT (toolbar_button));
1503 mark_object (data->up_glyph); 1590 tb->next = Qnil;
1504 mark_object (data->down_glyph); 1591 tb->frame = wrap_frame (f);
1505 mark_object (data->disabled_glyph); 1592 tb->up_glyph = Qnil;
1506 mark_object (data->cap_up_glyph); 1593 tb->down_glyph = Qnil;
1507 mark_object (data->cap_down_glyph); 1594 tb->disabled_glyph = Qnil;
1508 mark_object (data->cap_disabled_glyph); 1595 tb->cap_up_glyph = Qnil;
1509 mark_object (data->callback); 1596 tb->cap_down_glyph = Qnil;
1510 mark_object (data->enabled_p); 1597 tb->cap_disabled_glyph = Qnil;
1511 return data->help_string; 1598 tb->callback = Qnil;
1512 } 1599 tb->enabled_p = Qnil;
1513 1600 tb->help_string = Qnil;
1514 DEFINE_NODUMP_LISP_OBJECT ("toolbar-button", toolbar_button, 1601
1515 mark_toolbar_button, 1602 tb->pushright = pushright;
1516 external_object_printer, 0, 0, 0, 1603 tb->x = tb->y = tb->width = tb->height = -1;
1517 toolbar_button_description, 1604 tb->dirty = 1;
1518 struct toolbar_button); 1605
1519 1606 return wrap_toolbar_button (tb);
1520 ... 1607 }
1521 1608
1522 void 1609 static Lisp_Object
1523 syms_of_toolbar (void) 1610 mark_toolbar_button (Lisp_Object obj)
1524 { 1611 {
1525 INIT_LISP_OBJECT (toolbar_button); 1612 struct toolbar_button *data = XTOOLBAR_BUTTON (obj);
1526 1613 mark_object (data->next);
1527 ...; 1614 mark_object (data->frame);
1528 } 1615 mark_object (data->up_glyph);
1529 1616 mark_object (data->down_glyph);
1617 mark_object (data->disabled_glyph);
1618 mark_object (data->cap_up_glyph);
1619 mark_object (data->cap_down_glyph);
1620 mark_object (data->cap_disabled_glyph);
1621 mark_object (data->callback);
1622 mark_object (data->enabled_p);
1623 return data->help_string;
1624 }
1625
1626 DEFINE_NODUMP_LISP_OBJECT ("toolbar-button", toolbar_button,
1627 mark_toolbar_button,
1628 external_object_printer, 0, 0, 0,
1629 toolbar_button_description,
1630 struct toolbar_button);
1631
1632 ...
1633
1634 void
1635 syms_of_toolbar (void)
1636 {
1637 INIT_LISP_OBJECT (toolbar_button);
1638
1639 ...;
1640 }
1641
1530 ------------------------------ in inline.c ----------------------------- 1642 ------------------------------ in inline.c -----------------------------
1531 1643
1532 #ifdef HAVE_TOOLBARS 1644 #ifdef HAVE_TOOLBARS
1533 #include "toolbar.h" 1645 #include "toolbar.h"
1534 #endif 1646 #endif
1535 1647
1536 ------------------------------ in lrecord.h ----------------------------- 1648 ------------------------------ in lrecord.h -----------------------------
1537 1649
1538 enum lrecord_type 1650 enum lrecord_type
1539 { 1651 {
1652 ...
1653 lrecord_type_toolbar_button,
1654 ...
1655 };
1656
1657 ------------------------------ in .gdbinit.in.in -----------------------------
1658
1540 ... 1659 ...
1541 lrecord_type_toolbar_button, 1660 else
1661 if $lrecord_type == lrecord_type_toolbar_button
1662 pstructtype toolbar_button
1542 ... 1663 ...
1543 }; 1664 ...
1544 1665 ...
1545 1666 end
1546 --ben 1667
1668 --ben
1547 1669
1548 */ 1670 */
1549 1671
1550 /* 1672 /*
1551 1673
1674 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \ 1796 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \
1675 if (XTYPE (x) != lisp_enum) \ 1797 if (XTYPE (x) != lisp_enum) \
1676 dead_wrong_type_argument (predicate, x); \ 1798 dead_wrong_type_argument (predicate, x); \
1677 } while (0) 1799 } while (0)
1678 1800
1679 /* How to allocate a Lisp object:
1680
1681 - For most objects, simply call ALLOC_LISP_OBJECT (type), where TYPE is
1682 the name of the type (e.g. toolbar_button). Such objects can be freed
1683 manually using FREE_LISP_OBJECT.
1684
1685 - For objects whose size can vary (and hence which have a
1686 size_in_bytes_method rather than a static_size), call
1687 ALLOC_SIZED_LISP_OBJECT (size, type), where TYPE is the
1688 name of the type. NOTE: You cannot call FREE_LISP_OBJECT() on such
1689 on object! (At least when not NEW_GC)
1690
1691 - Basic lrecords (of which there are a limited number, which exist only
1692 when not NEW_GC, and which have special handling in alloc.c) need
1693 special handling; if you don't understand this, just ignore it.
1694
1695 - Some lrecords, which are used totally internally, use the
1696 noseeum-* functions for the reason of debugging.
1697 */
1698
1699 #ifndef NEW_GC 1801 #ifndef NEW_GC
1700 /*-------------------------- lcrecord-list -----------------------------*/ 1802 /*-------------------------- lcrecord-list -----------------------------*/
1701 1803
1702 struct lcrecord_list 1804 struct lcrecord_list
1703 { 1805 {
1704 LISP_OBJECT_HEADER header; 1806 NORMAL_LISP_OBJECT_HEADER header;
1705 Lisp_Object free; 1807 Lisp_Object free;
1706 Elemcount size; 1808 Elemcount size;
1707 const struct lrecord_implementation *implementation; 1809 const struct lrecord_implementation *implementation;
1708 }; 1810 };
1709 1811
1720 1822
1721 See above for a discussion of the difference between plain lrecords and 1823 See above for a discussion of the difference between plain lrecords and
1722 lrecords. lcrecords themselves are divided into three types: (1) 1824 lrecords. lcrecords themselves are divided into three types: (1)
1723 auto-managed, (2) hand-managed, and (3) unmanaged. "Managed" refers to 1825 auto-managed, (2) hand-managed, and (3) unmanaged. "Managed" refers to
1724 using a special object called an lcrecord-list to keep track of freed 1826 using a special object called an lcrecord-list to keep track of freed
1725 lcrecords, which can freed with FREE_LISP_OBJECT() or the like and later be 1827 lcrecords, which can freed with free_normal_lisp_object() or the like
1726 recycled when a new lcrecord is required, rather than requiring new 1828 and later be recycled when a new lcrecord is required, rather than
1727 malloc(). Thus, allocation of lcrecords can be very 1829 requiring new malloc(). Thus, allocation of lcrecords can be very
1728 cheap. (Technically, the lcrecord-list manager could divide up large 1830 cheap. (Technically, the lcrecord-list manager could divide up large
1729 chunks of memory and allocate out of that, mimicking what happens with 1831 chunks of memory and allocate out of that, mimicking what happens with
1730 lrecords. At that point, however, we'd want to rethink the whole 1832 lrecords. At that point, however, we'd want to rethink the whole
1731 division between lrecords and lcrecords.) 1833 division between lrecords and lcrecords.)
1732 1834
1733 NOTE: There is a fundamental limitation of lcrecord-lists, which is that 1835 NOTE: There is a fundamental limitation of lcrecord-lists, which is that
1734 they only handle blocks of a particular, fixed size. Thus, objects that 1836 they only handle blocks of a particular, fixed size. Thus, objects that
1735 can be of varying sizes need to do various tricks. These considerations 1837 can be of varying sizes need to do various tricks. These considerations
1736 in particular dictate the various types of management: 1838 in particular dictate the various types of management:
1737 1839
1738 -- "Auto-managed" means that you just go ahead and allocate the lcrecord 1840 -- "Auto-managed" means that you just go ahead and allocate the lcrecord
1739 whenever you want, using ALLOC_LISP_OBJECT(), and the appropriate 1841 whenever you want, using ALLOC_NORMAL_LISP_OBJECT(), and the appropriate
1740 lcrecord-list manager is automatically created. To free, you just call 1842 lcrecord-list manager is automatically created. To free, you just call
1741 "FREE_LISP_OBJECT()" and the appropriate lcrecord-list manager is 1843 "free_normal_lisp_object()" and the appropriate lcrecord-list manager is
1742 automatically located and called. The limitation here of course is that 1844 automatically located and called. The limitation here of course is that
1743 all your objects are of the same size. (#### Eventually we should have a 1845 all your objects are of the same size. (#### Eventually we should have a
1744 more sophisticated system that tracks the sizes seen and creates one 1846 more sophisticated system that tracks the sizes seen and creates one
1745 lcrecord list per size, indexed in a hash table. Usually there are only 1847 lcrecord list per size, indexed in a hash table. Usually there are only
1746 a limited number of sizes, so this works well.) 1848 a limited number of sizes, so this works well.)
1814 #define old_alloc_lcrecord_type(type, imp) \ 1916 #define old_alloc_lcrecord_type(type, imp) \
1815 ((type *) XPNTR (alloc_automanaged_lcrecord (sizeof (type), imp))) 1917 ((type *) XPNTR (alloc_automanaged_lcrecord (sizeof (type), imp)))
1816 1918
1817 void old_free_lcrecord (Lisp_Object rec); 1919 void old_free_lcrecord (Lisp_Object rec);
1818 1920
1819
1820 /* Copy the data from one lcrecord structure into another, but don't
1821 overwrite the header information. */
1822
1823 #define old_copy_sized_lcrecord(dst, src, size) \
1824 memcpy ((Rawbyte *) (dst) + sizeof (struct old_lcrecord_header), \
1825 (Rawbyte *) (src) + sizeof (struct old_lcrecord_header), \
1826 (size) - sizeof (struct old_lcrecord_header))
1827
1828 #define old_copy_lcrecord(dst, src) \
1829 old_copy_sized_lcrecord (dst, src, sizeof (*(dst)))
1830
1831 #define old_zero_sized_lcrecord(lcr, size) \
1832 memset ((Rawbyte *) (lcr) + sizeof (struct old_lcrecord_header), 0, \
1833 (size) - sizeof (struct old_lcrecord_header))
1834
1835 #define old_zero_lcrecord(lcr) old_zero_sized_lcrecord (lcr, sizeof (*(lcr)))
1836
1837 #else /* NEW_GC */ 1921 #else /* NEW_GC */
1838 1922
1839 MODULE_API Lisp_Object alloc_sized_lrecord (Bytecount size, 1923 MODULE_API Lisp_Object alloc_sized_lrecord (Bytecount size,
1840 const struct lrecord_implementation *imp); 1924 const struct lrecord_implementation *imp);
1841 Lisp_Object noseeum_alloc_sized_lrecord (Bytecount size, 1925 Lisp_Object noseeum_alloc_sized_lrecord (Bytecount size,
1847 const struct lrecord_implementation *imp); 1931 const struct lrecord_implementation *imp);
1848 MODULE_API Lisp_Object alloc_sized_lrecord_array (Bytecount size, 1932 MODULE_API Lisp_Object alloc_sized_lrecord_array (Bytecount size,
1849 int elemcount, 1933 int elemcount,
1850 const struct lrecord_implementation *imp); 1934 const struct lrecord_implementation *imp);
1851 1935
1852 void free_lrecord (Lisp_Object rec);
1853
1854
1855 /* Copy the data from one lrecord structure into another, but don't
1856 overwrite the header information. */
1857
1858 #define copy_sized_lrecord(dst, src, size) \
1859 memcpy ((char *) (dst) + sizeof (struct lrecord_header), \
1860 (char *) (src) + sizeof (struct lrecord_header), \
1861 (size) - sizeof (struct lrecord_header))
1862
1863 #define copy_lrecord(dst, src) copy_sized_lrecord (dst, src, sizeof (*(dst)))
1864
1865 #endif /* NEW_GC */ 1936 #endif /* NEW_GC */
1866
1867 #define zero_sized_lrecord(lcr, size) \
1868 memset ((char *) (lcr) + sizeof (struct lrecord_header), 0, \
1869 (size) - sizeof (struct lrecord_header))
1870
1871 #define zero_lrecord(lcr) zero_sized_lrecord (lcr, sizeof (*(lcr)))
1872 1937
1873 DECLARE_INLINE_HEADER ( 1938 DECLARE_INLINE_HEADER (
1874 Bytecount 1939 Bytecount
1875 detagged_lisp_object_size (const struct lrecord_header *h) 1940 detagged_lisp_object_size (const struct lrecord_header *h)
1876 ) 1941 )
1877 { 1942 {
1878 const struct lrecord_implementation *imp = LHEADER_IMPLEMENTATION (h); 1943 const struct lrecord_implementation *imp = LHEADER_IMPLEMENTATION (h);
1879 1944
1880 return (imp->size_in_bytes_method ? 1945 return (imp->size_in_bytes_method ?
1881 imp->size_in_bytes_method (h) : 1946 imp->size_in_bytes_method (wrap_pointer_1 (h)) :
1882 imp->static_size); 1947 imp->static_size);
1883 } 1948 }
1884 1949
1885 DECLARE_INLINE_HEADER ( 1950 DECLARE_INLINE_HEADER (
1886 Bytecount 1951 Bytecount
1887 lisp_object_size (Lisp_Object o) 1952 lisp_object_size (Lisp_Object o)
1888 ) 1953 )
1889 { 1954 {
1890 return detagged_lisp_object_size (XRECORD_LHEADER (o)); 1955 return detagged_lisp_object_size (XRECORD_LHEADER (o));
1891 } 1956 }
1957
1958 struct overhead_stats;
1959
1960 MODULE_API void copy_lisp_object (Lisp_Object dst, Lisp_Object src);
1961 MODULE_API void zero_sized_lisp_object (Lisp_Object obj, Bytecount size);
1962 MODULE_API void zero_nonsized_lisp_object (Lisp_Object obj);
1963 #ifdef MEMORY_USAGE_STATS
1964 Bytecount lisp_object_storage_size (Lisp_Object obj,
1965 struct overhead_stats *ovstats);
1966 #endif /* MEMORY_USAGE_STATS */
1967 void free_normal_lisp_object (Lisp_Object obj);
1892 1968
1893 1969
1894 /************************************************************************/ 1970 /************************************************************************/
1895 /* Dumping */ 1971 /* Dumping */
1896 /************************************************************************/ 1972 /************************************************************************/