Mercurial > hg > xemacs-beta
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 /************************************************************************/ |