Mercurial > hg > xemacs-beta
comparison src/lrecord.h @ 1204:e22b0213b713
[xemacs-hg @ 2003-01-12 11:07:58 by michaels]
modules/ChangeLog:
2002-12-16 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c:
remove ifdef USE_KKCC.
src/ChangeLog:
2003-01-08 Mike Sperber <mike@xemacs.org>
* console.h (CDFW_CONSOLE): Don't lead to a crash if we're dealing
with a dead window/frame/device/console.
2002-12-20 Mike Sperber <mike@xemacs.org>
* ui-gtk.c: Fix typo from Ben's patch: emacs_ffi_data is a
typedef, not a struct. emacs_gtk_object_data is a typedef, not a
struct.
* gtk-glue.c (gdk_event_to_emacs_event): Fix typos from Ben's
patch: le -> emacs_event + rearrange the code.
* event-gtk.c (gtk_event_to_emacs_event): Fix typos from Ben's
patch: ..._UNDERLYING_GDK_EVENT -> ..._GDK_EVENT, ev -> key_event.
* device-gtk.c: Fix typo from Ben's patch: x_keysym_map_hash_table
-> x_keysym_map_hashtable.
2002-12-19 Mike Sperber <mike@xemacs.org>
* menubar-x.c (set_frame_menubar): Initialize protect_me field of
popup_data.
2002-12-16 Ben Wing <ben@xemacs.org>
Major cleanup of KKCC, etc.
KKCC, pdump-related:
-- descriptions are written for all objects. this required some
changes in the format of some objects, e.g. extents, popup-data,
coding system, lstream, lcrecord-list.
-- KKCC now handles weakness in markers, hash tables, elsewhere
correctly (formerly, you'd eventually get a stack overflow due
to endlessly expanding markers).
-- textual changes: lrecord_description -> memory_description,
struct_description -> sized_memory_description.
-- extensive comment describing descriptions and pdump.
-- redo XD_UNION so it works inline and change its format to provide
sufficient info for pdump. implement XD_UNION in pdump. also add
XD_UNION_DYNAMIC_SIZE, which works like XD_UNION except for when
auto-computing structure sizes.
-- add support for XD_INDIRECT in description offsets (used by
extents).
-- add support for "description maps", allowing for indirect
descriptions that are retrieved from an object at run-time. this
generalizes XD_CODING_SYSTEM_END, XD_SPECIFIER_END, etc., which
have now been eliminated.
-- add a fifth field "flags" to memory_description, to support flags
that can be specified for this particular line. Currently defined
flags are XD_FLAG_NO_KKCC (KKCC should ignore this entry; useful
for the weakness above in markers, etc.), XD_FLAG_NO_PDUMP (pdump
should ignore this entry), XD_FLAG_UNION_DEFAULT_ENTRY (in
union maps, this specifies a "default" entry for all remaining
values), and XD_FLAG_FREE_LISP_OBJECT (for use with lcrecord-lists).
-- clean up the kkcc-itis in events, so that the differences
between event data as separate objects and as a union are now
minimized to a small number of places. with the new XD_UNION, we
no longer need event data as separate objects, so this code is no
longer ifdef USE_KKCC, but instead ifdef EVENT_DATA_AS_OBJECTS,
not used by default. make sure that we explicitly free the
separate event data objects when no longer in use, to maintain the
invariant the event processing causes no consing.
-- also remove other USE_KKCC ifdefs when not necessary.
-- allow for KKCC compilation under MS Windows.
-- fix README.kkcc.
-- dump_add_root_object -> dump_add_root_lisp_object.
-- implement dump_add_root_block and use this to handle
dump_add_opaque.
-- factor out some code duplicated in kkcc and pdump.
Other allocation/object-related:
-- change various *slots.h so MARKED_SLOT() call no longer
includes semicolon.
-- free_marker() takes a Lisp_Object not a direct pointer.
-- make bit vectors lcrecords, like vectors, and eliminate code
that essentially duplicated the lcrecord handling.
-- additional asserts in FREE_FIXED_TYPE, formerly duplicated in
the various callers of this.
-- all lcrecord allocation functions now zero out the returned
lcrecords. unnecessary calls to zero_lcrecord removed. add long
comment describing these functions.
-- extract out process and coding system slots, like for buffers,
frames, etc.
-- lcrecords now set the type of items sitting on the free list to
lcrecord_type_free.
-- changes to the way that gap arrays are allocated, for kkcc's
benefit -- now, one single memory block with a stretchy array on
the end, instead of a separate block holding the array.
Error-checking-related:
-- now can compile with C++ under MS Windows. clean up compile errors
discovered that way. (a few were real problems)
-- add C++ error-checking code to verify problems with mismatched
GCPRO/UNGCPRO. (there were a few in the kkcc code.) add long
comment about how to catch insufficient GCPRO (yes, it's possible
using C++).
-- add debug_p4(), a simple object printer, when debug_print()
doesn't work.
-- add dp() and db() as short synonyms of debug_print(),
debug_backtrace().
-- `print' tries EXTREMELY hard to avoid core dumping when printing
when crashing or from debug_print(), and tries as hard as it
reasonably can in other situations.
-- Correct the message output upon crashing to be more up-to-date.
Event-related:
-- document event-matches-key-specifier-p better.
-- generalize the dispatch queues formerly duplicated in the
various event implementations. add event methods to drain pending
events. generalize and clean up QUIT handling, removing
event-specific quit processing. allow arbitrary keystrokes, not
just ASCII, to be the QUIT char. among other things, this should
fix some longstanding bugs in X quit handling. long comment
describing the various event queues.
-- implement delaying of XFlush() if there are pending expose events.
SOMEONE PLEASE TRY THIS OUT.
-- Fix `xemacs -batch -l dunnet' under Cygwin. Try to fix under
MS Windows but not quite there yet.
Other:
-- class -> class_ and no more C++ games with this item.
new -> new_ in the lwlib code, so far not elsewhere.
-- use `struct htentry' not `struct hentry' in elhash.c to avoid
debugger confusion with hash.c.
-- new macros ALIST_LOOP_3, ALIST_LOOP_4.
* README.kkcc:
* alloc.c:
* alloc.c (deadbeef_memory):
* alloc.c (allocate_lisp_storage):
* alloc.c (copy_lisp_object):
* alloc.c (ALLOCATE_FIXED_TYPE_1):
* alloc.c (FREE_FIXED_TYPE):
* alloc.c (make_vector_internal):
* alloc.c (make_bit_vector_internal):
* 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 (struct string_chars_block):
* alloc.c (mark_lcrecord_list):
* alloc.c (make_lcrecord_list):
* alloc.c (alloc_managed_lcrecord):
* alloc.c (free_managed_lcrecord):
* alloc.c (alloc_automanaged_lcrecord):
* alloc.c (staticpro_1):
* alloc.c (staticpro):
* alloc.c (lispdesc_indirect_count_1):
* alloc.c (lispdesc_indirect_description_1):
* alloc.c (lispdesc_one_description_line_size):
* alloc.c (lispdesc_structure_size):
* alloc.c (mark_object_maybe_checking_free):
* alloc.c (mark_with_description):
* alloc.c (mark_struct_contents):
* alloc.c (mark_object):
* alloc.c (tick_lcrecord_stats):
* alloc.c (free_cons):
* alloc.c (free_key_data):
* alloc.c (free_button_data):
* alloc.c (free_motion_data):
* alloc.c (free_process_data):
* alloc.c (free_timeout_data):
* alloc.c (free_magic_data):
* alloc.c (free_magic_eval_data):
* alloc.c (free_eval_data):
* alloc.c (free_misc_user_data):
* alloc.c (free_marker):
* alloc.c (compact_string_chars):
* alloc.c (gc_sweep):
* alloc.c (garbage_collect_1):
* alloc.c (Fgarbage_collect):
* alloc.c (common_init_alloc_early):
* alloc.c (init_alloc_early):
* alloc.c (init_alloc_once_early):
* buffer.c:
* buffer.c (mark_buffer):
* buffer.c (MARKED_SLOT):
* buffer.c (cleanup_buffer_undo_lists):
* buffer.c (Fget_file_buffer):
* buffer.h (MARKED_SLOT):
* bufslots.h:
* bytecode.c:
* callint.c:
* casetab.c:
* chartab.c:
* chartab.c (symbol_to_char_table_type):
* cmdloop.c:
* cmdloop.c (Fcommand_loop_1):
* config.h.in (new):
* conslots.h:
* console-gtk-impl.h (struct gtk_frame):
* console-impl.h:
* console-impl.h (struct console):
* console-impl.h (MARKED_SLOT):
* console-impl.h (CONSOLE_QUIT_EVENT):
* console-msw-impl.h (XM_BUMPQUEUE):
* console-msw.c (write_string_to_mswindows_debugging_output):
* console-msw.h:
* console-stream-impl.h:
* console-stream-impl.h (struct stream_console):
* console-stream.c:
* console-stream.c (stream_init_console):
* console-stream.h:
* console-tty.c:
* console-tty.h:
* console-x.h:
* console.c:
* console.c (mark_console):
* console.c (MARKED_SLOT):
* console.c (allocate_console):
* console.c (get_console_variant):
* console.c (create_console):
* console.c (delete_console_internal):
* console.c (Fset_input_mode):
* console.c (Fcurrent_input_mode):
* console.c (common_init_complex_vars_of_console):
* console.h:
* console.h (console_variant):
* console.h (device_metrics):
* data.c:
* data.c (Faref):
* data.c (Faset):
* data.c (decode_weak_list_type):
* database.c:
* debug.c (xemacs_debug_loop):
* debug.c (FROB):
* debug.c (Fadd_debug_class_to_check):
* debug.c (Fdelete_debug_class_to_check):
* debug.c (Fset_debug_classes_to_check):
* debug.c (Fset_debug_class_types_to_check):
* debug.c (Fdebug_types_being_checked):
* debug.h (DASSERT):
* device-gtk.c:
* device-impl.h (struct device):
* device-impl.h (MARKED_SLOT):
* device-msw.c:
* device-x.c:
* device-x.c (x_init_device_class):
* device-x.c (x_comp_visual_info):
* device-x.c (x_try_best_visual_class):
* device-x.c (x_init_device):
* device-x.c (construct_name_list):
* device-x.c (x_get_resource_prefix):
* device-x.c (Fx_get_resource):
* device-x.c (Fx_display_visual_class):
* device.c:
* device.c (MARKED_SLOT):
* device.c (allocate_device):
* device.c (Fmake_device):
* device.c (delete_device_internal):
* device.c (Fset_device_class):
* device.h:
* devslots.h:
* devslots.h (MARKED_SLOT):
* dialog-msw.c:
* dired-msw.c (mswindows_ls_sort_fcn):
* dired-msw.c (mswindows_get_files):
* dired-msw.c (mswindows_format_file):
* doprnt.c (parse_doprnt_spec):
* dumper.c:
* dumper.c (struct):
* dumper.c (dump_add_root_block):
* dumper.c (dump_add_root_struct_ptr):
* dumper.c (dump_add_root_lisp_object):
* dumper.c (pdump_struct_list_elt):
* dumper.c (pdump_get_entry_list):
* dumper.c (pdump_backtrace):
* dumper.c (pdump_bump_depth):
* dumper.c (pdump_register_sub):
* dumper.c (pdump_register_object):
* dumper.c (pdump_register_struct_contents):
* dumper.c (pdump_register_struct):
* dumper.c (pdump_store_new_pointer_offsets):
* dumper.c (pdump_dump_data):
* dumper.c (pdump_reloc_one):
* dumper.c (pdump_allocate_offset):
* dumper.c (pdump_scan_by_alignment):
* dumper.c (pdump_dump_root_blocks):
* dumper.c (pdump_dump_rtables):
* dumper.c (pdump_dump_root_lisp_objects):
* dumper.c (pdump):
* dumper.c (pdump_load_finish):
* dumper.c (pdump_file_get):
* dumper.c (pdump_resource_get):
* dumper.c (pdump_load):
* editfns.c (save_excursion_restore):
* editfns.c (user_login_name):
* editfns.c (save_restriction_restore):
* elhash.c:
* elhash.c (htentry):
* elhash.c (struct Lisp_Hash_Table):
* elhash.c (HTENTRY_CLEAR_P):
* elhash.c (LINEAR_PROBING_LOOP):
* elhash.c (check_hash_table_invariants):
* elhash.c (mark_hash_table):
* elhash.c (hash_table_equal):
* elhash.c (print_hash_table_data):
* elhash.c (free_hentries):
* elhash.c (make_general_lisp_hash_table):
* elhash.c (decode_hash_table_weakness):
* elhash.c (decode_hash_table_test):
* elhash.c (Fcopy_hash_table):
* elhash.c (resize_hash_table):
* elhash.c (pdump_reorganize_hash_table):
* elhash.c (find_htentry):
* elhash.c (Fgethash):
* elhash.c (Fputhash):
* elhash.c (remhash_1):
* elhash.c (Fremhash):
* elhash.c (Fclrhash):
* elhash.c (copy_compress_hentries):
* elhash.c (elisp_maphash_unsafe):
* elhash.c (finish_marking_weak_hash_tables):
* elhash.c (prune_weak_hash_tables):
* elhash.h:
* emacs.c:
* emacs.c (main_1):
* emacs.c (main):
* emacs.c (shut_down_emacs):
* emodules.h (dump_add_root_lisp_object):
* eval.c:
* eval.c (unwind_to_catch):
* eval.c (maybe_signal_error_1):
* eval.c (maybe_signal_continuable_error_1):
* eval.c (maybe_signal_error):
* eval.c (maybe_signal_continuable_error):
* eval.c (maybe_signal_error_2):
* eval.c (maybe_signal_continuable_error_2):
* eval.c (maybe_signal_ferror):
* eval.c (maybe_signal_continuable_ferror):
* eval.c (maybe_signal_ferror_with_frob):
* eval.c (maybe_signal_continuable_ferror_with_frob):
* eval.c (maybe_syntax_error):
* eval.c (maybe_sferror):
* eval.c (maybe_invalid_argument):
* eval.c (maybe_invalid_constant):
* eval.c (maybe_invalid_operation):
* eval.c (maybe_invalid_change):
* eval.c (maybe_invalid_state):
* eval.c (Feval):
* eval.c (call_trapping_problems):
* eval.c (call_with_suspended_errors):
* eval.c (warn_when_safe_lispobj):
* eval.c (warn_when_safe):
* eval.c (vars_of_eval):
* event-Xt.c:
* event-Xt.c (maybe_define_x_key_as_self_inserting_character):
* event-Xt.c (x_to_emacs_keysym):
* event-Xt.c (x_event_to_emacs_event):
* event-Xt.c (emacs_Xt_enqueue_focus_event):
* event-Xt.c (emacs_Xt_format_magic_event):
* event-Xt.c (emacs_Xt_compare_magic_event):
* event-Xt.c (emacs_Xt_hash_magic_event):
* event-Xt.c (emacs_Xt_handle_magic_event):
* event-Xt.c (Xt_timeout_to_emacs_event):
* event-Xt.c (Xt_process_to_emacs_event):
* event-Xt.c (signal_special_Xt_user_event):
* event-Xt.c (emacs_Xt_next_event):
* event-Xt.c (emacs_Xt_event_handler):
* event-Xt.c (emacs_Xt_drain_queue):
* event-Xt.c (emacs_Xt_event_pending_p):
* event-Xt.c (check_if_pending_expose_event):
* event-Xt.c (reinit_vars_of_event_Xt):
* event-Xt.c (vars_of_event_Xt):
* event-gtk.c:
* event-gtk.c (IS_MODIFIER_KEY):
* event-gtk.c (emacs_gtk_format_magic_event):
* event-gtk.c (emacs_gtk_compare_magic_event):
* event-gtk.c (emacs_gtk_hash_magic_event):
* event-gtk.c (emacs_gtk_handle_magic_event):
* event-gtk.c (gtk_to_emacs_keysym):
* event-gtk.c (gtk_timeout_to_emacs_event):
* event-gtk.c (gtk_process_to_emacs_event):
* event-gtk.c (dragndrop_data_received):
* event-gtk.c (signal_special_gtk_user_event):
* event-gtk.c (emacs_gtk_next_event):
* event-gtk.c (gtk_event_to_emacs_event):
* event-gtk.c (generic_event_handler):
* event-gtk.c (emacs_shell_event_handler):
* event-gtk.c (emacs_gtk_drain_queue):
* event-gtk.c (emacs_gtk_event_pending_p):
* event-gtk.c (reinit_vars_of_event_gtk):
* event-gtk.c (vars_of_event_gtk):
* event-msw.c:
* event-msw.c (struct winsock_stream):
* event-msw.c (winsock_reader):
* event-msw.c (winsock_writer):
* event-msw.c (mswindows_enqueue_dispatch_event):
* event-msw.c (mswindows_enqueue_misc_user_event):
* event-msw.c (mswindows_enqueue_magic_event):
* event-msw.c (mswindows_enqueue_process_event):
* event-msw.c (mswindows_enqueue_mouse_button_event):
* event-msw.c (mswindows_enqueue_keypress_event):
* event-msw.c (mswindows_dequeue_dispatch_event):
* event-msw.c (emacs_mswindows_drain_queue):
* event-msw.c (mswindows_need_event_in_modal_loop):
* event-msw.c (mswindows_need_event):
* event-msw.c (mswindows_wm_timer_callback):
* event-msw.c (dde_eval_string):
* event-msw.c (Fdde_alloc_advise_item):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (mswindows_wnd_proc):
* event-msw.c (remove_timeout_mapper):
* event-msw.c (emacs_mswindows_remove_timeout):
* event-msw.c (emacs_mswindows_event_pending_p):
* event-msw.c (emacs_mswindows_format_magic_event):
* event-msw.c (emacs_mswindows_compare_magic_event):
* event-msw.c (emacs_mswindows_hash_magic_event):
* event-msw.c (emacs_mswindows_handle_magic_event):
* event-msw.c (emacs_mswindows_select_console):
* event-msw.c (emacs_mswindows_unselect_console):
* event-msw.c (reinit_vars_of_event_mswindows):
* event-msw.c (vars_of_event_mswindows):
* event-stream.c:
* event-stream.c (mark_command_builder):
* event-stream.c (reset_command_builder_event_chain):
* event-stream.c (allocate_command_builder):
* event-stream.c (copy_command_builder):
* event-stream.c (command_builder_append_event):
* event-stream.c (event_stream_event_pending_p):
* event-stream.c (event_stream_force_event_pending):
* event-stream.c (maybe_read_quit_event):
* event-stream.c (event_stream_drain_queue):
* event-stream.c (remove_quit_p_event):
* event-stream.c (event_stream_quit_p):
* event-stream.c (echo_key_event):
* event-stream.c (maybe_kbd_translate):
* event-stream.c (execute_help_form):
* event-stream.c (event_stream_generate_wakeup):
* event-stream.c (enqueue_dispatch_event):
* event-stream.c (enqueue_magic_eval_event):
* event-stream.c (Fenqueue_eval_event):
* event-stream.c (enqueue_misc_user_event):
* event-stream.c (enqueue_misc_user_event_pos):
* event-stream.c (next_event_internal):
* event-stream.c (Fnext_event):
* event-stream.c (Faccept_process_output):
* event-stream.c (execute_internal_event):
* event-stream.c (munge_keymap_translate):
* event-stream.c (command_builder_find_leaf_no_mule_processing):
* event-stream.c (command_builder_find_leaf):
* event-stream.c (lookup_command_event):
* event-stream.c (is_scrollbar_event):
* event-stream.c (execute_command_event):
* event-stream.c (Fdispatch_event):
* event-stream.c (Fread_key_sequence):
* event-stream.c (dribble_out_event):
* event-stream.c (vars_of_event_stream):
* event-tty.c (tty_timeout_to_emacs_event):
* event-tty.c (emacs_tty_next_event):
* event-tty.c (emacs_tty_drain_queue):
* event-tty.c (reinit_vars_of_event_tty):
* event-unixoid.c:
* event-unixoid.c (find_tty_or_stream_console_from_fd):
* event-unixoid.c (read_event_from_tty_or_stream_desc):
* event-unixoid.c (drain_tty_devices):
* event-unixoid.c (poll_fds_for_input):
* events.c:
* events.c (deinitialize_event):
* events.c (zero_event):
* events.c (mark_event):
* events.c (print_event_1):
* events.c (print_event):
* events.c (event_equal):
* events.c (event_hash):
* events.c (Fmake_event):
* events.c (Fdeallocate_event):
* events.c (Fcopy_event):
* events.c (map_event_chain_remove):
* events.c (character_to_event):
* events.c (event_to_character):
* events.c (Fevent_to_character):
* events.c (format_event_object):
* events.c (upshift_event):
* events.c (downshift_event):
* events.c (event_upshifted_p):
* events.c (Fevent_live_p):
* events.c (Fevent_type):
* events.c (Fevent_timestamp):
* events.c (CHECK_EVENT_TYPE):
* events.c (CHECK_EVENT_TYPE2):
* events.c (CHECK_EVENT_TYPE3):
* events.c (Fevent_key):
* events.c (Fevent_button):
* events.c (Fevent_modifier_bits):
* events.c (event_x_y_pixel_internal):
* events.c (event_pixel_translation):
* events.c (Fevent_process):
* events.c (Fevent_function):
* events.c (Fevent_object):
* events.c (Fevent_properties):
* events.c (syms_of_events):
* events.c (vars_of_events):
* events.h:
* events.h (struct event_stream):
* events.h (struct Lisp_Key_Data):
* events.h (KEY_DATA_KEYSYM):
* events.h (EVENT_KEY_KEYSYM):
* events.h (struct Lisp_Button_Data):
* events.h (EVENT_BUTTON_BUTTON):
* events.h (struct Lisp_Motion_Data):
* events.h (EVENT_MOTION_X):
* events.h (struct Lisp_Process_Data):
* events.h (EVENT_PROCESS_PROCESS):
* events.h (struct Lisp_Timeout_Data):
* events.h (EVENT_TIMEOUT_INTERVAL_ID):
* events.h (struct Lisp_Eval_Data):
* events.h (EVENT_EVAL_FUNCTION):
* events.h (struct Lisp_Misc_User_Data):
* events.h (EVENT_MISC_USER_FUNCTION):
* events.h (struct Lisp_Magic_Eval_Data):
* events.h (EVENT_MAGIC_EVAL_INTERNAL_FUNCTION):
* events.h (struct Lisp_Magic_Data):
* events.h (EVENT_MAGIC_UNDERLYING):
* events.h (EVENT_MAGIC_GDK_EVENT):
* events.h (struct Lisp_Event):
* events.h (XEVENT_CHANNEL):
* events.h (SET_EVENT_TIMESTAMP_ZERO):
* events.h (SET_EVENT_CHANNEL):
* events.h (SET_EVENT_NEXT):
* events.h (XSET_EVENT_TYPE):
* events.h (struct command_builder):
* extents.c:
* extents.c (gap_array_adjust_markers):
* extents.c (gap_array_recompute_derived_values):
* extents.c (gap_array_move_gap):
* extents.c (gap_array_make_gap):
* extents.c (gap_array_insert_els):
* extents.c (gap_array_delete_els):
* extents.c (gap_array_make_marker):
* extents.c (gap_array_delete_marker):
* extents.c (gap_array_move_marker):
* extents.c (make_gap_array):
* extents.c (free_gap_array):
* extents.c (extent_list_num_els):
* extents.c (extent_list_insert):
* extents.c (mark_extent_auxiliary):
* extents.c (allocate_extent_auxiliary):
* extents.c (decode_extent_at_flag):
* extents.c (verify_extent_mapper):
* extents.c (symbol_to_glyph_layout):
* extents.c (syms_of_extents):
* faces.c:
* file-coding.c:
* file-coding.c (struct_detector_category_description =):
* file-coding.c (detector_category_dynarr_description_1):
* file-coding.c (struct_detector_description =):
* file-coding.c (detector_dynarr_description_1):
* file-coding.c (MARKED_SLOT):
* file-coding.c (mark_coding_system):
* file-coding.c (coding_system_extra_description_map):
* file-coding.c (coding_system_description):
* file-coding.c (allocate_coding_system):
* file-coding.c (symbol_to_eol_type):
* file-coding.c (Fcoding_system_aliasee):
* file-coding.c (set_coding_stream_coding_system):
* file-coding.c (struct convert_eol_coding_system):
* file-coding.c (struct undecided_coding_system):
* file-coding.c (undecided_mark_coding_stream):
* file-coding.c (coding_category_symbol_to_id):
* file-coding.c (struct gzip_coding_system):
* file-coding.c (coding_system_type_create):
* file-coding.h:
* file-coding.h (struct Lisp_Coding_System):
* file-coding.h (CODING_SYSTEM_SLOT_DECLARATION):
* file-coding.h (coding_system_variant):
* file-coding.h (struct coding_system_methods):
* file-coding.h (DEFINE_CODING_SYSTEM_TYPE_WITH_DATA):
* file-coding.h (INITIALIZE_CODING_SYSTEM_TYPE_WITH_DATA):
* file-coding.h (struct coding_stream):
* fileio.c (Fsubstitute_in_file_name):
* floatfns.c:
* fns.c:
* fns.c (base64_encode_1):
* frame-gtk.c:
* frame-gtk.c (Fgtk_start_drag_internal):
* frame-impl.h (struct frame):
* frame-impl.h (MARKED_SLOT):
* frame-msw.c:
* frame-x.c:
* frame-x.c (Fcde_start_drag_internal):
* frame-x.c (Foffix_start_drag_internal):
* frame.c:
* frame.c (MARKED_SLOT):
* frame.c (allocate_frame_core):
* frame.c (delete_frame_internal):
* frame.c (Fmouse_position_as_motion_event):
* frameslots.h:
* frameslots.h (MARKED_SLOT_ARRAY):
* free-hook.c:
* glyphs-msw.c (mswindows_widget_instantiate):
* glyphs-x.c:
* glyphs-x.c (convert_EImage_to_XImage):
* glyphs.c:
* glyphs.c (process_image_string_instantiator):
* glyphs.c (mark_image_instance):
* glyphs.c (allocate_image_instance):
* glyphs.c (unmap_subwindow):
* glyphs.c (map_subwindow):
* glyphs.c (syms_of_glyphs):
* glyphs.c (specifier_type_create_image):
* glyphs.h:
* glyphs.h (struct text_image_instance):
* glyphs.h (struct Lisp_Image_Instance):
* gmalloc.c:
* gmalloc.c ("C"):
* gpmevent.c (Freceive_gpm_event):
* gpmevent.c (gpm_next_event_cb):
* gpmevent.c (vars_of_gpmevent):
* gtk-glue.c (gdk_event_to_emacs_event):
* gtk-xemacs.c (gtk_xemacs_class_init):
* gui-msw.c:
* gui-msw.c (mswindows_handle_gui_wm_command):
* gui-msw.c (mswindows_translate_menu_or_dialog_item):
* gui-x.c:
* gui-x.c (mark_popup_data):
* gui-x.c (snarf_widget_value_mapper):
* gui-x.c (gcpro_popup_callbacks):
* gui-x.c (ungcpro_popup_callbacks):
* gui-x.c (free_popup_widget_value_tree):
* gui-x.c (popup_selection_callback):
* gui-x.h:
* gui-x.h (struct popup_data):
* gui.c:
* gui.c (allocate_gui_item):
* gutter.c (decode_gutter_position):
* hash.c (NULL_ENTRY):
* indent.c (vmotion_1):
* indent.c (vmotion_pixels):
* input-method-motif.c (res):
* input-method-xlib.c (IMInstantiateCallback):
* input-method-xlib.c (XIM_init_device):
* input-method-xlib.c (res):
* intl-encap-win32.c:
* intl-encap-win32.c (qxeSHGetDataFromIDList):
* intl-win32.c:
* intl-win32.c (mswindows_multibyte_cp_type):
* intl-win32.c (struct mswindows_multibyte_coding_system):
* keymap.c:
* keymap.c (make_key_description):
* keymap.c (keymap_store):
* keymap.c (get_keyelt):
* keymap.c (keymap_lookup_1):
* keymap.c (define_key_parser):
* keymap.c (key_desc_list_to_event):
* keymap.c (event_matches_key_specifier_p):
* keymap.c (meta_prefix_char_p):
* keymap.c (ensure_meta_prefix_char_keymapp):
* keymap.c (Fdefine_key):
* keymap.c (struct raw_lookup_key_mapper_closure):
* keymap.c (raw_lookup_key):
* keymap.c (raw_lookup_key_mapper):
* keymap.c (lookup_keys):
* keymap.c (lookup_events):
* keymap.c (Flookup_key):
* keymap.c (struct map_keymap_unsorted_closure):
* keymap.c (map_keymap_unsorted_mapper):
* keymap.c (map_keymap_sorted):
* keymap.c (map_keymap_mapper):
* keymap.c (map_keymap):
* keymap.c (accessible_keymaps_mapper_1):
* keymap.c (Faccessible_keymaps):
* keymap.c (Fsingle_key_description):
* keymap.c (raw_keys_to_keys):
* keymap.c (format_raw_keys):
* keymap.c (where_is_recursive_mapper):
* keymap.c (where_is_internal):
* keymap.c (describe_map_mapper_shadow_search):
* keymap.c (keymap_lookup_inherited_mapper):
* keymap.c (describe_map_mapper):
* keymap.h (event_matches_key_specifier_p):
* lisp.h:
* lisp.h (this):
* lisp.h (RETURN_NOT_REACHED):
* lisp.h (struct Lisp_Vector):
* lisp.h (struct Lisp_Bit_Vector):
* lisp.h (UNGCPRO_1):
* lisp.h (NUNGCPRO):
* lisp.h (NNUNGCPRO):
* lisp.h (DECLARE_INLINE_HEADER):
* lrecord.h:
* lrecord.h (struct lrecord_header):
* lrecord.h (struct lcrecord_header):
* lrecord.h (lrecord_type):
* lrecord.h (struct lrecord_implementation):
* lrecord.h (RECORD_DUMPABLE):
* lrecord.h (memory_description_type):
* lrecord.h (data_description_entry_flags):
* lrecord.h (struct memory_description):
* lrecord.h (struct sized_memory_description):
* lrecord.h (XD_INDIRECT):
* lrecord.h (XD_IS_INDIRECT):
* lrecord.h (XD_DYNARR_DESC):
* lrecord.h (DEFINE_BASIC_LRECORD_IMPLEMENTATION):
* lrecord.h (MAKE_LRECORD_IMPLEMENTATION):
* lrecord.h (MAKE_EXTERNAL_LRECORD_IMPLEMENTATION):
* lrecord.h (alloc_lcrecord_type):
* lstream.c:
* lstream.c (Lstream_new):
* lstream.c (lisp_buffer_marker):
* lstream.h:
* lstream.h (lstream_implementation):
* lstream.h (DEFINE_LSTREAM_IMPLEMENTATION):
* lstream.h (DEFINE_LSTREAM_IMPLEMENTATION_WITH_DATA):
* marker.c:
* marker.c (copy_marker_1):
* mem-limits.h:
* menubar-gtk.c:
* menubar-gtk.c (gtk_popup_menu):
* menubar-msw.c:
* menubar-msw.c (mswindows_popup_menu):
* menubar-x.c (make_dummy_xbutton_event):
* menubar-x.c (command_builder_operate_menu_accelerator):
* menubar-x.c (menu_accelerator_safe_compare):
* menubar-x.c (menu_accelerator_safe_mod_compare):
* mule-charset.c:
* mule-charset.c (make_charset):
* mule-charset.c (Fcharset_property):
* mule-coding.c:
* mule-coding.c (ccs_description_1):
* mule-coding.c (ccs_description =):
* mule-coding.c (ccsd_description_1):
* mule-coding.c (ccsd_description =):
* nt.c (getpwnam):
* nt.c (init_mswindows_environment):
* nt.c (get_cached_volume_information):
* nt.c (mswindows_is_executable):
* nt.c (read_unc_volume):
* nt.c (mswindows_access):
* nt.c (mswindows_link):
* nt.c (mswindows_fstat):
* nt.c (mswindows_stat):
* nt.c (mswindows_executable_type):
* nt.c (Fmswindows_short_file_name):
* nt.c (Fmswindows_long_file_name):
* objects-impl.h (struct Lisp_Color_Instance):
* objects-impl.h (struct Lisp_Font_Instance):
* objects-tty.c:
* objects-x.c (allocate_nearest_color):
* objects.c:
* objects.c (Fmake_color_instance):
* objects.c (Fmake_font_instance):
* objects.c (font_instantiate):
* opaque.c:
* opaque.c (make_opaque):
* opaque.c (make_opaque_ptr):
* opaque.c (reinit_opaque_early):
* opaque.c (init_opaque_once_early):
* print.c:
* print.c (printing_badness):
* print.c (printing_major_badness):
* print.c (print_internal):
* print.c (debug_p4):
* print.c (dp):
* print.c (debug_backtrace):
* process-nt.c (nt_create_process):
* process-nt.c (get_internet_address):
* process-unix.c:
* process-unix.c (struct unix_process_data):
* process-unix.c (get_internet_address):
* process-unix.c (unix_alloc_process_data):
* process-unix.c (unix_create_process):
* process-unix.c (try_to_initialize_subtty):
* process-unix.c (unix_kill_child_process):
* process-unix.c (process_type_create_unix):
* process.c:
* process.c (mark_process):
* process.c (MARKED_SLOT):
* process.c (make_process_internal):
* process.c (Fprocess_tty_name):
* process.c (decode_signal):
* process.h:
* procimpl.h:
* procimpl.h (struct process_methods):
* procimpl.h (struct Lisp_Process):
* rangetab.c:
* realpath.c (readlink_and_correct_case):
* redisplay-x.c (x_window_output_end):
* redisplay-x.c (x_redraw_exposed_area):
* redisplay-x.c (x_clear_frame):
* redisplay.c:
* redisplay.h:
* redisplay.h (struct rune_dglyph):
* redisplay.h (struct rune):
* scrollbar.c:
* scrollbar.c (create_scrollbar_instance):
* specifier.c:
* specifier.c (specifier_empty_extra_description_1):
* specifier.c (make_specifier_internal):
* specifier.c (decode_locale_type):
* specifier.c (decode_how_to_add_specification):
* specifier.h:
* specifier.h (struct specifier_methods):
* specifier.h (DEFINE_SPECIFIER_TYPE_WITH_DATA):
* specifier.h (INITIALIZE_SPECIFIER_TYPE_WITH_DATA):
* symbols.c:
* symbols.c (Fsetplist):
* symbols.c (default_value):
* symbols.c (decode_magic_handler_type):
* symbols.c (handler_type_from_function_symbol):
* symbols.c (Fdefvaralias):
* symbols.c (init_symbols_once_early):
* symbols.c (reinit_symbols_early):
* symsinit.h:
* sysdep.c (sys_subshell):
* sysdep.c (tty_init_sys_modes_on_device):
* syswindows.h:
* text.c (dfc_convert_to_external_format):
* text.c (dfc_convert_to_internal_format):
* text.c (reinit_eistring_early):
* text.c (init_eistring_once_early):
* text.c (reinit_vars_of_text):
* text.h:
* text.h (INC_IBYTEPTR_FMT):
* text.h (DEC_IBYTEPTR_FMT):
* toolbar.c:
* toolbar.c (decode_toolbar_position):
* tooltalk.c:
* ui-gtk.c:
* unexnt.c:
* unexnt.c (_start):
* unexnt.c (unexec):
* unexnt.c (get_section_info):
* unicode.c:
* unicode.c (vars_of_unicode):
* window.c:
* window.c (allocate_window):
* window.c (new_window_mirror):
* window.c (update_mirror_internal):
* winslots.h:
author | michaels |
---|---|
date | Sun, 12 Jan 2003 11:08:22 +0000 |
parents | 25e260cb7994 |
children | 4542b72c005e |
comparison
equal
deleted
inserted
replaced
1203:5f2f8dcbfb3e | 1204:e22b0213b713 |
---|---|
38 Straight lrecords are used for those types of objects that have | 38 Straight lrecords are used for those types of objects that have |
39 their own allocation routines (typically allocated out of 2K chunks | 39 their own allocation routines (typically allocated out of 2K chunks |
40 of memory called `frob blocks'). These objects have a `struct | 40 of memory called `frob blocks'). These objects have a `struct |
41 lrecord_header' at the top, containing only the bits needed to find | 41 lrecord_header' at the top, containing only the bits needed to find |
42 the lrecord_implementation for the object. There are special | 42 the lrecord_implementation for the object. There are special |
43 routines in alloc.c to deal with each such object type. | 43 routines in alloc.c to create an object of each such type. |
44 | 44 |
45 Lcrecords are used for less common sorts of objects that don't do | 45 Lcrecords are used for less common sorts of objects that don't do |
46 their own allocation. Each such object is malloc()ed individually, | 46 their own allocation. Each such object is malloc()ed individually, |
47 and the objects are chained together through a `next' pointer. | 47 and the objects are chained together through a `next' pointer. |
48 Lcrecords have a `struct lcrecord_header' at the top, which | 48 Lcrecords have a `struct lcrecord_header' at the top, which |
49 contains a `struct lrecord_header' and a `next' pointer, and are | 49 contains a `struct lrecord_header' and a `next' pointer, and are |
50 allocated using alloc_lcrecord(). | 50 allocated using alloc_lcrecord_type() or its variants. |
51 | 51 |
52 Creating a new lcrecord type is fairly easy; just follow the | 52 Creating a new lcrecord type is fairly easy; just follow the |
53 lead of some existing type (e.g. hash tables). Note that you | 53 lead of some existing type (e.g. hash tables). Note that you |
54 do not need to supply all the methods (see below); reasonable | 54 do not need to supply all the methods (see below); reasonable |
55 defaults are provided for many of them. Alternatively, if you're | 55 defaults are provided for many of them. Alternatively, if you're |
56 just looking for a way of encapsulating data (which possibly | 56 just looking for a way of encapsulating data (which possibly |
57 could contain Lisp_Objects in it), you may well be able to use | 57 could contain Lisp_Objects in it), you may well be able to use |
58 the opaque type. */ | 58 the opaque type. --ben |
59 */ | |
59 | 60 |
60 struct lrecord_header | 61 struct lrecord_header |
61 { | 62 { |
62 /* index into lrecord_implementations_table[] */ | 63 /* Index into lrecord_implementations_table[]. Objects that have been |
64 explicitly freed using e.g. free_cons() have lrecord_type_free in this | |
65 field. */ | |
63 unsigned int type :8; | 66 unsigned int type :8; |
64 | 67 |
65 /* If `mark' is 0 after the GC mark phase, the object will be freed | 68 /* If `mark' is 0 after the GC mark phase, the object will be freed |
66 during the GC sweep phase. There are 2 ways that `mark' can be 1: | 69 during the GC sweep phase. There are 2 ways that `mark' can be 1: |
67 - by being referenced from other objects during the GC mark phase | 70 - by being referenced from other objects during the GC mark phase |
95 { | 98 { |
96 struct lrecord_header lheader; | 99 struct lrecord_header lheader; |
97 | 100 |
98 /* The `next' field is normally used to chain all lcrecords together | 101 /* The `next' field is normally used to chain all lcrecords together |
99 so that the GC can find (and free) all of them. | 102 so that the GC can find (and free) all of them. |
100 `alloc_lcrecord' threads lcrecords together. | 103 `basic_alloc_lcrecord' threads lcrecords together. |
101 | 104 |
102 The `next' field may be used for other purposes as long as some | 105 The `next' field may be used for other purposes as long as some |
103 other mechanism is provided for letting the GC do its work. | 106 other mechanism is provided for letting the GC do its work. |
104 | 107 |
105 For example, the event and marker object types allocate members | 108 For example, the event and marker object types allocate members |
132 enum lrecord_type | 135 enum lrecord_type |
133 { | 136 { |
134 /* Symbol value magic types come first to make SYMBOL_VALUE_MAGIC_P fast. | 137 /* Symbol value magic types come first to make SYMBOL_VALUE_MAGIC_P fast. |
135 #### This should be replaced by a symbol_value_magic_p flag | 138 #### This should be replaced by a symbol_value_magic_p flag |
136 in the Lisp_Symbol lrecord_header. */ | 139 in the Lisp_Symbol lrecord_header. */ |
137 lrecord_type_symbol_value_forward, | 140 lrecord_type_symbol_value_forward, /* 0 */ |
138 lrecord_type_symbol_value_varalias, | 141 lrecord_type_symbol_value_varalias, /* 1 */ |
139 lrecord_type_symbol_value_lisp_magic, | 142 lrecord_type_symbol_value_lisp_magic, /* 2 */ |
140 lrecord_type_symbol_value_buffer_local, | 143 lrecord_type_symbol_value_buffer_local, /* 3 */ |
141 lrecord_type_max_symbol_value_magic = lrecord_type_symbol_value_buffer_local, | 144 lrecord_type_max_symbol_value_magic = lrecord_type_symbol_value_buffer_local, |
142 | 145 |
143 lrecord_type_symbol, | 146 lrecord_type_symbol, /* 4 */ |
144 lrecord_type_subr, | 147 lrecord_type_subr, /* 5 */ |
145 lrecord_type_cons, | 148 lrecord_type_cons, /* 6 */ |
146 lrecord_type_vector, | 149 lrecord_type_vector, |
147 lrecord_type_string, | 150 lrecord_type_string, |
148 lrecord_type_lcrecord_list, | 151 lrecord_type_lcrecord_list, |
149 lrecord_type_compiled_function, | 152 lrecord_type_compiled_function, |
150 lrecord_type_weak_list, | 153 lrecord_type_weak_list, |
164 lrecord_type_extent, | 167 lrecord_type_extent, |
165 lrecord_type_extent_info, | 168 lrecord_type_extent_info, |
166 lrecord_type_extent_auxiliary, | 169 lrecord_type_extent_auxiliary, |
167 lrecord_type_marker, | 170 lrecord_type_marker, |
168 lrecord_type_event, | 171 lrecord_type_event, |
169 #ifdef USE_KKCC | 172 #ifdef EVENT_DATA_AS_OBJECTS |
170 lrecord_type_key_data, | 173 lrecord_type_key_data, |
171 lrecord_type_button_data, | 174 lrecord_type_button_data, |
172 lrecord_type_motion_data, | 175 lrecord_type_motion_data, |
173 lrecord_type_process_data, | 176 lrecord_type_process_data, |
174 lrecord_type_timeout_data, | 177 lrecord_type_timeout_data, |
175 lrecord_type_eval_data, | 178 lrecord_type_eval_data, |
176 lrecord_type_misc_user_data, | 179 lrecord_type_misc_user_data, |
177 lrecord_type_magic_eval_data, | 180 lrecord_type_magic_eval_data, |
178 lrecord_type_magic_data, | 181 lrecord_type_magic_data, |
179 #endif /* USE_KKCC */ | 182 #endif /* EVENT_DATA_AS_OBJECTS */ |
180 lrecord_type_keymap, | 183 lrecord_type_keymap, |
181 lrecord_type_command_builder, | 184 lrecord_type_command_builder, |
182 lrecord_type_timeout, | 185 lrecord_type_timeout, |
183 lrecord_type_specifier, | 186 lrecord_type_specifier, |
184 lrecord_type_console, | 187 lrecord_type_console, |
231 the return value is non-nil, it should be a Lisp_Object to be | 234 the return value is non-nil, it should be a Lisp_Object to be |
232 marked (don't call the mark_object function explicitly on it, | 235 marked (don't call the mark_object function explicitly on it, |
233 because the GC routines will do this). Doing it this way reduces | 236 because the GC routines will do this). Doing it this way reduces |
234 recursion, so the object returned should preferably be the one | 237 recursion, so the object returned should preferably be the one |
235 with the deepest level of Lisp_Object pointers. This function | 238 with the deepest level of Lisp_Object pointers. This function |
236 can be NULL, meaning no GC marking is necessary. */ | 239 can be NULL, meaning no GC marking is necessary. |
240 | |
241 NOTE NOTE NOTE: This is not used by KKCC (which uses the data | |
242 description below instead), unless the data description is missing. | |
243 Yes, this currently means there is logic duplication. Eventually the | |
244 mark methods will be removed. */ | |
237 Lisp_Object (*marker) (Lisp_Object); | 245 Lisp_Object (*marker) (Lisp_Object); |
238 | 246 |
239 /* `printer' converts the object to a printed representation. | 247 /* `printer' converts the object to a printed representation. |
240 This can be NULL; in this case default_object_printer() will be | 248 This can be NULL; in this case default_object_printer() will be |
241 used instead. */ | 249 used instead. */ |
261 hash to the same value in order for hash tables to work properly. | 269 hash to the same value in order for hash tables to work properly. |
262 This means that `hash' can be NULL only if the `equal' method is | 270 This means that `hash' can be NULL only if the `equal' method is |
263 also NULL. */ | 271 also NULL. */ |
264 unsigned long (*hash) (Lisp_Object, int); | 272 unsigned long (*hash) (Lisp_Object, int); |
265 | 273 |
266 /* External data layout description */ | 274 /* Data layout description for your object. See long comment below. */ |
267 const struct lrecord_description *description; | 275 const struct memory_description *description; |
268 | 276 |
269 /* These functions allow any object type to have builtin property | 277 /* These functions allow any object type to have builtin property |
270 lists that can be manipulated from the lisp level with | 278 lists that can be manipulated from the lisp level with |
271 `get', `put', `remprop', and `object-plist'. */ | 279 `get', `put', `remprop', and `object-plist'. */ |
272 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); | 280 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop); |
273 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); | 281 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val); |
274 int (*remprop) (Lisp_Object obj, Lisp_Object prop); | 282 int (*remprop) (Lisp_Object obj, Lisp_Object prop); |
275 Lisp_Object (*plist) (Lisp_Object obj); | 283 Lisp_Object (*plist) (Lisp_Object obj); |
276 | 284 |
277 /* Only one of `static_size' and `size_in_bytes_method' is non-0. | 285 /* Only one of `static_size' and `size_in_bytes_method' is non-0. |
278 If both are 0, this type is not instantiable by alloc_lcrecord(). */ | 286 If both are 0, this type is not instantiable by basic_alloc_lcrecord(). */ |
279 Bytecount static_size; | 287 Bytecount static_size; |
280 Bytecount (*size_in_bytes_method) (const void *header); | 288 Bytecount (*size_in_bytes_method) (const void *header); |
281 | 289 |
282 /* The (constant) index into lrecord_implementations_table */ | 290 /* The (constant) index into lrecord_implementations_table */ |
283 enum lrecord_type lrecord_type_index; | 291 enum lrecord_type lrecord_type_index; |
284 | 292 |
285 /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e. | 293 /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e. |
286 one that does not have an lcrecord_header at the front and which | 294 one that does not have an lcrecord_header at the front and which |
287 is (usually) allocated in frob blocks. We only use this flag for | 295 is (usually) allocated in frob blocks. */ |
288 some consistency checking, and that only when error-checking is | |
289 enabled. */ | |
290 unsigned int basic_p :1; | 296 unsigned int basic_p :1; |
291 }; | 297 }; |
292 | 298 |
293 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. | 299 /* All the built-in lisp object types are enumerated in `enum lrecord_type'. |
294 Additional ones may be defined by a module (none yet). We leave some | 300 Additional ones may be defined by a module (none yet). We leave some |
318 } while (0) | 324 } while (0) |
319 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \ | 325 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \ |
320 ((void) ((lheader)->lisp_readonly = 1)) | 326 ((void) ((lheader)->lisp_readonly = 1)) |
321 #define RECORD_MARKER(lheader) lrecord_markers[(lheader)->type] | 327 #define RECORD_MARKER(lheader) lrecord_markers[(lheader)->type] |
322 | 328 |
323 #ifdef USE_KKCC | |
324 #define RECORD_DUMPABLE(lheader) (lrecord_implementations_table[(lheader)->type])->dumpable | 329 #define RECORD_DUMPABLE(lheader) (lrecord_implementations_table[(lheader)->type])->dumpable |
325 #endif /* USE_KKCC */ | 330 |
326 | 331 /* Data description stuff |
327 /* External description stuff | 332 |
328 | 333 Data layout descriptions describe blocks of memory (in particular, Lisp |
329 PLEASE NOTE: Both lrecord_description and struct_description are | 334 objects and other objects on the heap, and global objects with pointers |
330 badly misnamed. In reality, an lrecord_description is nothing more | 335 to such heap objects), including their size and a list of the elements |
331 than a list of the elements in a block of memory that need | 336 that need relocating, marking or other special handling. They are |
332 relocating or other special handling, and a struct_description is | 337 currently used in two places: by pdump [the new, portable dumper] and |
333 no more than an lrecord_description plus the size of the block of | 338 KKCC [the new garbage collector]. The two subsystems use the |
334 memory. (In fact, a struct_description can now have its size given | 339 descriptions in different ways, and as a result some of the descriptions |
335 as zero, i.e. unspecified, meaning that the last element in the | 340 are appropriate only for one or the other, when it is known that only |
336 structure is noted in the list and the size of the block can | 341 that subsystem will use the description. (This is particularly the case |
337 therefore be computed from it.) The names stem from the fact | 342 with objects that can't be dumped, because pdump needs more info than |
338 lrecord_descriptions are used to describe lrecords (the size of the | 343 KKCC.) However, properly written descriptions are appropriate for both, |
339 lrecord is elsewhere in its description, attached to its methods, | 344 and you should strive to write your descriptions that way, since the |
340 so it does not need to be given here), while struct_descriptions | 345 dumpable status of an object may change and new uses for the |
341 are used to describe C structs; but both are used in various | 346 descriptions may be created. (An example that comes to mind is a |
342 additional ways. Much better terms would be memory_description and | 347 facility for determining the memory usage of XEmacs data structures -- |
343 sized_memory_description. | 348 like `buffer-memory-usage', `window-memory-usage', etc. but more |
344 | 349 general.) |
345 An lrecord_description is an array of values. (This is actually | 350 |
351 More specifically: | |
352 | |
353 Pdump (the portable dumper) needs to write out all objects in heap | |
354 space, and later on (in another invocation of XEmacs) load them back | |
355 into the heap, relocating all pointers to the heap objects in the global | |
356 data space. ("Heap" means anything malloc()ed, including all Lisp | |
357 objects, and "global data" means anything declared globally or | |
358 `static'.) Pdump, then, needs to be told about the location of all | |
359 global pointers to heap objects, all the description of all such | |
360 objects, including their size and any pointers to other heap (aka | |
361 "relocatable") objects. (Pdump assumes that the heap may occur in | |
362 different places in different invocations -- therefore, it is not enough | |
363 simply to write out the entire heap and later reload it at the same | |
364 location -- but that global data is always in the same place, and hence | |
365 pointers to it do not need to be relocated. This assumption holds true | |
366 in general for modern operating systems, but would be broken, for | |
367 example, in a system without virtual memory, or when dealing with shared | |
368 libraries. Also, unlike unexec, pdump does not usually write out or | |
369 restore objects in the global data space, and thus they need to be | |
370 initialized every time XEmacs is loaded. This is the purpose of the | |
371 reinit_*() functions throughout XEmacs. [It's possible, however, to make | |
372 pdump restore global data. This must be done, of course, for heap | |
373 pointers, but is also done for other values that are not easy to | |
374 recompute -- in particular, values established by the Lisp code loaded | |
375 at dump time.]) Note that the data type `Lisp_Object' is basically just | |
376 a relocatable pointer disguised as a long, and in general pdump treats | |
377 the Lisp_Object values and pointers to Lisp objects (e.g. Lisp_Object | |
378 vs. `struct frame *') identically. (NOTE: This equivalence depends | |
379 crucially on the current "minimal tagbits" implementation of Lisp_Object | |
380 pointers.) | |
381 | |
382 Descriptions are used by pdump in three places: (a) descriptions of Lisp | |
383 objects, referenced in the DEFINE_*LRECORD_*IMPLEMENTATION*() call; (b) | |
384 descriptions of global objects to be dumped, registered by | |
385 dump_add_root_block(); (c) descriptions of global pointers to | |
386 non-Lisp_Object heap objects, registered by dump_add_root_struct_ptr(). | |
387 The descriptions need to tell pdump which elements of your structure are | |
388 Lisp_Objects or structure pointers, plus the descriptions in turn of the | |
389 non-Lisp_Object structures pointed to. If these structures are you own | |
390 private ones, you will have to write these recursive descriptions | |
391 yourself; otherwise, you are reusing a structure already in existence | |
392 elsewhere and there is probably already a description for it. | |
393 | |
394 Pdump does not care about Lisp objects that cannot be dumped (the | |
395 dumpable flag to DEFINE_*LRECORD_*IMPLEMENTATION*() is 0). | |
396 | |
397 KKCC also uses data layout descriptions, but differently. It cares | |
398 about all objects, dumpable or not, but specifically only wants to know | |
399 about Lisp_Objects in your object and in structures pointed to. Thus, | |
400 it doesn't care about things like pointers to structures ot other blocks | |
401 of memory with no Lisp Objects in them, which pdump would care a lot | |
402 about. | |
403 | |
404 Technically, then, you could write your description differently | |
405 depending on whether your object is dumpable -- the full pdump | |
406 description if so, the abbreviated KKCC description if not. In fact, | |
407 some descriptions are written this way. This is dangerous, though, | |
408 because another use might come along for the data descriptions, that | |
409 doesn't care about the dumper flag and makes use of some of the stuff | |
410 normally omitted from the "abbreviated" description -- see above. | |
411 | |
412 A memory_description is an array of values. (This is actually | |
346 misnamed, in that it does not just describe lrecords, but any | 413 misnamed, in that it does not just describe lrecords, but any |
347 blocks of memory.) The first value of each line is a type, the | 414 blocks of memory.) The first value of each line is a type, the |
348 second the offset in the lrecord structure. The third and | 415 second the offset in the lrecord structure. The third and |
349 following elements are parameters; their presence, type and number | 416 following elements are parameters; their presence, type and number |
350 is type-dependent. | 417 is type-dependent. |
351 | 418 |
352 The description ends with a "XD_END", "XD_SPECIFIER_END" or | 419 The description ends with an "XD_END" record. |
353 "XD_CODING_SYSTEM_END" record. | |
354 | 420 |
355 The top-level description of an lrecord or lcrecord does not need | 421 The top-level description of an lrecord or lcrecord does not need |
356 to describe every element, just the ones that need to be relocated, | 422 to describe every element, just the ones that need to be relocated, |
357 since the size of the lrecord is known. (The same goes for nested | 423 since the size of the lrecord is known. (The same goes for nested |
358 structures, whenever the structure size is given, rather than being | 424 structures, whenever the structure size is given, rather than being |
359 defaulted by specifying 0 for the size.) | 425 defaulted by specifying 0 for the size.) |
360 | 426 |
361 A struct_description is used for describing nested "structures". (Again | 427 A sized_memory_description is a memory_description plus the size of the |
362 a misnomer, since it can be used for any blocks of memory, not just | 428 block of memory. The size field in a sized_memory_description can be |
363 structures.) It just contains a size for the memory block, a pointer to | 429 given as zero, i.e. unspecified, meaning that the last element in the |
364 an lrecord_description, and (for unions only) a union constant, | 430 structure is described in the description and the size of the block can |
365 described below. The size can be 0, in which case the size will be | 431 therefore be computed from it. (This is useful for stretchy arrays.) |
366 determined from the largest offset logically referenced (i.e. last | 432 |
367 offset mentioned + size of that object). This is useful for stretchy | 433 memory_descriptions are used to describe lrecords (the size of the |
368 arrays. | 434 lrecord is elsewhere in its description, attached to its methods, so it |
435 does not need to be given here) and global objects, where the size is an | |
436 argument to the call to dump_add_root_block(). | |
437 sized_memory_descriptions are used for pointers and arrays in | |
438 memory_descriptions and for calls to dump_add_root_struct_ptr(). (#### | |
439 It is not obvious why this is so in the latter case. Probably, calls to | |
440 dump_add_root_struct_ptr() should use plain memory_descriptions and have | |
441 the size be an argument to the call.) | |
442 | |
443 NOTE: Anywhere that a sized_memory_description occurs inside of a plain | |
444 memory_description, a "description map" can be substituted. Rather than | |
445 being an actual description, this describes how to find the description | |
446 by looking inside of the object being described. This is a convenient | |
447 way to describe Lisp objects with subtypes and corresponding | |
448 type-specific data. | |
369 | 449 |
370 Some example descriptions : | 450 Some example descriptions : |
371 | 451 |
372 struct Lisp_String | 452 struct Lisp_String |
373 { | 453 { |
375 Bytecount size; | 455 Bytecount size; |
376 Ibyte *data; | 456 Ibyte *data; |
377 Lisp_Object plist; | 457 Lisp_Object plist; |
378 }; | 458 }; |
379 | 459 |
380 static const struct lrecord_description cons_description[] = { | 460 static const struct memory_description cons_description[] = { |
381 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car) }, | 461 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car) }, |
382 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr) }, | 462 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr) }, |
383 { XD_END } | 463 { XD_END } |
384 }; | 464 }; |
385 | 465 |
386 Which means "two lisp objects starting at the 'car' and 'cdr' elements" | 466 Which means "two lisp objects starting at the 'car' and 'cdr' elements" |
387 | 467 |
388 static const struct lrecord_description string_description[] = { | 468 static const struct memory_description string_description[] = { |
389 { XD_BYTECOUNT, offsetof (Lisp_String, size) }, | 469 { XD_BYTECOUNT, offsetof (Lisp_String, size) }, |
390 { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT(0, 1) }, | 470 { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT (0, 1) }, |
391 { XD_LISP_OBJECT, offsetof (Lisp_String, plist) }, | 471 { XD_LISP_OBJECT, offsetof (Lisp_String, plist) }, |
392 { XD_END } | 472 { XD_END } |
393 }; | 473 }; |
394 | 474 |
395 "A pointer to string data at 'data', the size of the pointed array being | 475 "A pointer to string data at 'data', the size of the pointed array being |
406 ...; | 486 ...; |
407 } | 487 } |
408 | 488 |
409 You'd use XD_STRUCT_PTR, something like: | 489 You'd use XD_STRUCT_PTR, something like: |
410 | 490 |
411 static const struct lrecord_description lo_description_1[] = { | 491 static const struct memory_description foo_description[] = { |
492 ... | |
493 { XD_INT, offsetof (Lisp_Foo, count) }, | |
494 { XD_STRUCT_PTR, offsetof (Lisp_Foo, objects), | |
495 XD_INDIRECT (0, 0), &lisp_object_description }, | |
496 ... | |
497 }; | |
498 | |
499 lisp_object_description is declared in alloc.c, like this: | |
500 | |
501 static const struct memory_description lisp_object_description_1[] = { | |
412 { XD_LISP_OBJECT, 0 }, | 502 { XD_LISP_OBJECT, 0 }, |
413 { XD_END } | 503 { XD_END } |
414 }; | 504 }; |
415 | 505 |
416 static const struct struct_description lo_description = { | 506 const struct sized_memory_description lisp_object_description = { |
417 sizeof (Lisp_Object), | 507 sizeof (Lisp_Object), |
418 lo_description_1 | 508 lisp_object_description_1 |
419 }; | 509 }; |
420 | 510 |
421 static const struct lrecord_description foo_description[] = { | |
422 ... | |
423 { XD_INT, offsetof (Lisp_Foo, count) }, | |
424 { XD_STRUCT_PTR, offsetof (Lisp_Foo, objects), | |
425 XD_INDIRECT (0, 0), &lo_description }, | |
426 ... | |
427 }; | |
428 | |
429 | |
430 Another example of XD_STRUCT_PTR: | 511 Another example of XD_STRUCT_PTR: |
431 | 512 |
432 typedef struct hentry | 513 typedef struct htentry |
433 { | 514 { |
434 Lisp_Object key; | 515 Lisp_Object key; |
435 Lisp_Object value; | 516 Lisp_Object value; |
436 } hentry; | 517 } htentry; |
437 | 518 |
438 struct Lisp_Hash_Table | 519 struct Lisp_Hash_Table |
439 { | 520 { |
440 struct lcrecord_header header; | 521 struct lcrecord_header header; |
441 Elemcount size; | 522 Elemcount size; |
444 double rehash_size; | 525 double rehash_size; |
445 double rehash_threshold; | 526 double rehash_threshold; |
446 Elemcount golden_ratio; | 527 Elemcount golden_ratio; |
447 hash_table_hash_function_t hash_function; | 528 hash_table_hash_function_t hash_function; |
448 hash_table_test_function_t test_function; | 529 hash_table_test_function_t test_function; |
449 hentry *hentries; | 530 htentry *hentries; |
450 enum hash_table_weakness weakness; | 531 enum hash_table_weakness weakness; |
451 Lisp_Object next_weak; // Used to chain together all of the weak | 532 Lisp_Object next_weak; // Used to chain together all of the weak |
452 // hash tables. Don't mark through this. | 533 // hash tables. Don't mark through this. |
453 }; | 534 }; |
454 | 535 |
455 static const struct lrecord_description hentry_description_1[] = { | 536 static const struct memory_description htentry_description_1[] = { |
456 { XD_LISP_OBJECT, offsetof (hentry, key) }, | 537 { XD_LISP_OBJECT, offsetof (htentry, key) }, |
457 { XD_LISP_OBJECT, offsetof (hentry, value) }, | 538 { XD_LISP_OBJECT, offsetof (htentry, value) }, |
458 { XD_END } | 539 { XD_END } |
459 }; | 540 }; |
460 | 541 |
461 static const struct struct_description hentry_description = { | 542 static const struct sized_memory_description htentry_description = { |
462 sizeof (hentry), | 543 sizeof (htentry), |
463 hentry_description_1 | 544 htentry_description_1 |
464 }; | 545 }; |
465 | 546 |
466 const struct lrecord_description hash_table_description[] = { | 547 const struct memory_description hash_table_description[] = { |
467 { XD_ELEMCOUNT, offsetof (Lisp_Hash_Table, size) }, | 548 { XD_ELEMCOUNT, offsetof (Lisp_Hash_Table, size) }, |
468 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), | 549 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT (0, 1), |
469 &hentry_description }, | 550 &htentry_description }, |
470 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) }, | 551 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) }, |
471 { XD_END } | 552 { XD_END } |
472 }; | 553 }; |
473 | 554 |
474 Note that we don't need to declare all the elements in the structure, just | 555 Note that we don't need to declare all the elements in the structure, just |
475 the ones that need to be relocated (Lisp_Objects and structures) or that | 556 the ones that need to be relocated (Lisp_Objects and structures) or that |
476 need to be referenced as counts for relocated objects. | 557 need to be referenced as counts for relocated objects. |
477 | 558 |
559 A description map looks like this: | |
560 | |
561 static const struct sized_memory_description specifier_extra_description_map [] = { | |
562 { offsetof (Lisp_Specifier, methods) }, | |
563 { offsetof (struct specifier_methods, extra_description) }, | |
564 { -1 } | |
565 }; | |
566 | |
567 const struct memory_description specifier_description[] = { | |
568 ... | |
569 { XD_STRUCT_ARRAY, offset (Lisp_Specifier, data), 1, | |
570 specifier_extra_description_map }, | |
571 ... | |
572 { XD_END } | |
573 }; | |
574 | |
575 This would be appropriate for an object that looks like this: | |
576 | |
577 struct specifier_methods | |
578 { | |
579 ... | |
580 const struct sized_memory_description *extra_description; | |
581 ... | |
582 }; | |
583 | |
584 struct Lisp_Specifier | |
585 { | |
586 struct lcrecord_header header; | |
587 struct specifier_methods *methods; | |
588 | |
589 ... | |
590 // type-specific extra data attached to a specifier | |
591 max_align_t data[1]; | |
592 }; | |
593 | |
594 The description map means "retrieve a pointer into the object at offset | |
595 `offsetof (Lisp_Specifier, methods)' , then in turn retrieve a pointer | |
596 into that object at offset `offsetof (struct specifier_methods, | |
597 extra_description)', and that is the sized_memory_description to use." | |
598 There can be any number of indirections, which can be either into | |
599 straight pointers or Lisp_Objects. The way that description maps are | |
600 distinguished from normal sized_memory_descriptions is that in the | |
601 former, the memory_description pointer is NULL. | |
602 | |
603 --ben | |
604 | |
478 | 605 |
479 The existing types : | 606 The existing types : |
480 | 607 |
481 | 608 |
482 XD_LISP_OBJECT | 609 XD_LISP_OBJECT |
483 A Lisp object. This is also the type to use for pointers to other lrecords. | 610 |
611 A Lisp object. This is also the type to use for pointers to other lrecords | |
612 (e.g. struct frame *). | |
484 | 613 |
485 XD_LISP_OBJECT_ARRAY | 614 XD_LISP_OBJECT_ARRAY |
615 | |
486 An array of Lisp objects or (equivalently) pointers to lrecords. | 616 An array of Lisp objects or (equivalently) pointers to lrecords. |
487 The parameter (i.e. third element) is the count. This would be declared | 617 The parameter (i.e. third element) is the count. This would be declared |
488 as Lisp_Object foo[666]. For something declared as Lisp_Object *foo, | 618 as Lisp_Object foo[666]. For something declared as Lisp_Object *foo, |
489 use XD_STRUCT_PTR, whose description parameter is a struct_description | 619 use XD_STRUCT_PTR, whose description parameter is a sized_memory_description |
490 consisting of only XD_LISP_OBJECT and XD_END. | 620 consisting of only XD_LISP_OBJECT and XD_END. |
491 | 621 |
492 XD_LO_LINK | 622 XD_LO_LINK |
623 | |
493 Weak link in a linked list of objects of the same type. This is a | 624 Weak link in a linked list of objects of the same type. This is a |
494 link that does NOT generate a GC reference. Thus the pdumper will | 625 link that does NOT generate a GC reference. Thus the pdumper will |
495 not automatically add the referenced object to the table of all | 626 not automatically add the referenced object to the table of all |
496 objects to be dumped, and when storing and loading the dumped data | 627 objects to be dumped, and when storing and loading the dumped data |
497 will automatically prune unreferenced objects in the chain and link | 628 will automatically prune unreferenced objects in the chain and link |
499 many links away. We also need to special handling of a similar | 630 many links away. We also need to special handling of a similar |
500 nature for the root of the chain, which will be a staticpro()ed | 631 nature for the root of the chain, which will be a staticpro()ed |
501 object. | 632 object. |
502 | 633 |
503 XD_OPAQUE_PTR | 634 XD_OPAQUE_PTR |
635 | |
504 Pointer to undumpable data. Must be NULL when dumping. | 636 Pointer to undumpable data. Must be NULL when dumping. |
505 | 637 |
506 XD_STRUCT_PTR | 638 XD_STRUCT_PTR |
639 | |
507 Pointer to block of described memory. (This is misnamed: It is NOT | 640 Pointer to block of described memory. (This is misnamed: It is NOT |
508 necessarily a pointer to a struct foo.) Parameters are number of | 641 necessarily a pointer to a struct foo.) Parameters are number of |
509 contiguous blocks and struct_description. | 642 contiguous blocks and sized_memory_description. |
510 | 643 |
511 XD_STRUCT_ARRAY | 644 XD_STRUCT_ARRAY |
645 | |
512 Array of blocks of described memory. Parameters are number of | 646 Array of blocks of described memory. Parameters are number of |
513 structures and struct_description. This differs from XD_STRUCT_PTR | 647 structures and sized_memory_description. This differs from XD_STRUCT_PTR |
514 in that the parameter is declared as struct foo[666] instead of | 648 in that the parameter is declared as struct foo[666] instead of |
515 struct *foo. In other words, the block of memory holding the | 649 struct *foo. In other words, the block of memory holding the |
516 structures is within the containing structure, rather than being | 650 structures is within the containing structure, rather than being |
517 elsewhere, with a pointer in the containing structure. | 651 elsewhere, with a pointer in the containing structure. |
518 | 652 |
653 NOTE NOTE NOTE: Be sure that you understand the difference between | |
654 XD_STRUCT_PTR and XD_STRUCT_ARRAY: | |
655 - struct foo bar[666], i.e. 666 inline struct foos | |
656 --> XD_STRUCT_ARRAY, argument 666, pointing to a description of | |
657 struct foo | |
658 - struct foo *bar, i.e. pointer to a block of 666 struct foos | |
659 --> XD_STRUCT_PTR, argument 666, pointing to a description of | |
660 struct foo | |
661 - struct foo *bar[666], i.e. 666 pointers to separate blocks of struct foos | |
662 --> XD_STRUCT_ARRAY, argument 666, pointing to a description of | |
663 a single pointer to struct foo; the description is a single | |
664 XD_STRUCT_PTR, argument 1, which in turn points to a description | |
665 of struct foo. | |
666 | |
519 XD_OPAQUE_DATA_PTR | 667 XD_OPAQUE_DATA_PTR |
668 | |
520 Pointer to dumpable opaque data. Parameter is the size of the data. | 669 Pointer to dumpable opaque data. Parameter is the size of the data. |
521 Pointed data must be relocatable without changes. | 670 Pointed data must be relocatable without changes. |
522 | 671 |
523 XD_UNION | 672 XD_UNION |
524 Union of two or more different types of data. Parameters are a | 673 |
525 constant which determines which type the data is (this is usually an | 674 Union of two or more different types of data. Parameters are a constant |
526 XD_INDIRECT, referring to one of the fields in the structure), and | 675 which determines which type the data is (this is usually an XD_INDIRECT, |
527 an array of struct_descriptions, whose values are used as follows, | 676 referring to one of the fields in the structure), and a "sizing lobby" (a |
528 which is *DIFFERENT* from their usage in XD_STRUCT_PTR: the first | 677 sized_memory_description, which points to a memory_description and |
529 field is a constant, which is compared to the first parameter of the | 678 indicates its size). The size field in the sizing lobby describes the |
530 XD_UNION descriptor to determine if this description applies to the | 679 size of the union field in the object, and the memory_description in it |
531 data at the given offset, and the second is a pointer to a *SINGLE* | 680 is referred to as a "union map" and has a special interpretation: The |
532 lrecord_description structure, describing the data being pointed at | 681 offset field is replaced by a constant, which is compared to the first |
533 when the associated constant matches. You can go ahead and create | 682 parameter of the XD_UNION descriptor to determine if this description |
534 an array of lrecord_description structures and put an XD_END on it, | 683 applies to the union data, and XD_INDIRECT references refer to the |
535 but only the first one is used. If the data being pointed at is a | 684 containing object and description. Note that the description applies |
536 structure, you *MAY NOT* substitute an array of lrecord_description | 685 "inline" to the union data, like XD_STRUCT_ARRAY and not XD_STRUCT_PTR. |
537 structures describing the structure; instead, use a single | 686 If the union data is a pointer to different types of structures, each |
538 lrecord_description structure with an XD_STRUCT_PTR in it, and point | 687 element in the memory_description should be an XD_STRUCT_PTR. See |
539 it in turn to the description of the structure. See charset.h for a | 688 unicode.c, redisplay.c and objects.c for examples of XD_UNION. |
540 description of how to use XD_UNION. (In other words, if the constant | 689 |
541 matches, the lrecord_description pointed at will in essence be | 690 XD_UNION_DYNAMIC_SIZE |
542 substituted for the XD_UNION declaration.) | 691 |
692 Same as XD_UNION except that this is used for objects where the size of | |
693 the object containing the union varies depending on the particular value | |
694 of the union constant. That is, an object with plain XD_UNION typically | |
695 has the union declared as `union foo' or as `void *', where an object | |
696 with XD_UNION_DYNAMIC_SIZE typically has the union as the last element, | |
697 and declared as something like char foo[1]. With plain XD_UNION, the | |
698 object is (usually) of fixed size and always contains enough space for | |
699 the data associated with all possible union constants, and thus the union | |
700 constant can potentially change during the lifetime of the object. With | |
701 XD_UNION_DYNAMIC_SIZE, however, the union constant is fixed at the time | |
702 of creation of the object, and the size of the object is computed | |
703 dynamically at creation time based on the size of the data associated | |
704 with the union constant. Currently, the only difference between XD_UNION | |
705 and XD_UNION_DYNAMIC_SIZE is how the size of the union data is | |
706 calculated, when (a) the structure containing the union has no size | |
707 given; (b) the union occurs as the last element in the structure; and (c) | |
708 the union has no size given (in the first-level sized_memory_description | |
709 pointed to). In this circumstance, the size of XD_UNION comes from the | |
710 max size of the data associated with all possible union constants, | |
711 whereas the size of XD_UNION_DYNAMIC_SIZE comes from the size of the data | |
712 associated with the currently specified (and unchangeable) union | |
713 constant. | |
543 | 714 |
544 XD_C_STRING | 715 XD_C_STRING |
716 | |
545 Pointer to a C string. | 717 Pointer to a C string. |
546 | 718 |
547 XD_DOC_STRING | 719 XD_DOC_STRING |
720 | |
548 Pointer to a doc string (C string if positive, opaque value if negative) | 721 Pointer to a doc string (C string if positive, opaque value if negative) |
549 | 722 |
550 XD_INT_RESET | 723 XD_INT_RESET |
724 | |
551 An integer which will be reset to a given value in the dump file. | 725 An integer which will be reset to a given value in the dump file. |
552 | 726 |
553 | |
554 XD_ELEMCOUNT | 727 XD_ELEMCOUNT |
728 | |
555 Elemcount value. Used for counts. | 729 Elemcount value. Used for counts. |
556 | 730 |
557 XD_BYTECOUNT | 731 XD_BYTECOUNT |
732 | |
558 Bytecount value. Used for counts. | 733 Bytecount value. Used for counts. |
559 | 734 |
560 XD_HASHCODE | 735 XD_HASHCODE |
736 | |
561 Hashcode value. Used for the results of hashing functions. | 737 Hashcode value. Used for the results of hashing functions. |
562 | 738 |
563 XD_INT | 739 XD_INT |
740 | |
564 int value. Used for counts. | 741 int value. Used for counts. |
565 | 742 |
566 XD_LONG | 743 XD_LONG |
744 | |
567 long value. Used for counts. | 745 long value. Used for counts. |
568 | 746 |
569 XD_BYTECOUNT | 747 XD_BYTECOUNT |
748 | |
570 bytecount value. Used for counts. | 749 bytecount value. Used for counts. |
571 | 750 |
572 XD_END | 751 XD_END |
752 | |
573 Special type indicating the end of the array. | 753 Special type indicating the end of the array. |
574 | 754 |
575 XD_SPECIFIER_END | |
576 Special type indicating the end of the array for a specifier. Extra | |
577 description, describing the specifier-type-specific data at the end | |
578 of the specifier object, is going to be fetched from the specifier | |
579 methods. This should occur exactly once, in the description of the | |
580 specifier object, and the dump code knows how to special-case this | |
581 by fetching the specifier_methods pointer from the appropriate place | |
582 in the memory block (which will, of course, be a struct | |
583 Lisp_Specifier), fetching the description of the | |
584 specifier-type-specific data from this, and continuing processing | |
585 the memory block. | |
586 | |
587 XD_CODING_SYSTEM_END | |
588 Special type indicating the end of the array for a coding system. | |
589 Extra description is going to be fetched from the coding system | |
590 methods. Works just like XD_SPECIFIER_END. | |
591 | |
592 | 755 |
593 Special macros: | 756 Special macros: |
594 XD_INDIRECT(line, delta) | 757 |
595 Usable where a "count" or "size" is requested. Gives the value of | 758 XD_INDIRECT (line, delta) |
596 the element which is at line number 'line' in the description (count | 759 Usable where a count, size, offset or union constant is requested. Gives |
597 starts at zero) and adds delta to it. | 760 the value of the element which is at line number 'line' in the |
761 description (count starts at zero) and adds delta to it, which must | |
762 (currently) be positive. | |
598 */ | 763 */ |
599 | 764 |
600 enum lrecord_description_type | 765 enum memory_description_type |
601 { | 766 { |
602 XD_LISP_OBJECT_ARRAY, | 767 XD_LISP_OBJECT_ARRAY, |
603 XD_LISP_OBJECT, | 768 XD_LISP_OBJECT, |
604 XD_LO_LINK, | 769 XD_LO_LINK, |
605 XD_OPAQUE_PTR, | 770 XD_OPAQUE_PTR, |
606 XD_STRUCT_PTR, | 771 XD_STRUCT_PTR, |
607 XD_STRUCT_ARRAY, | 772 XD_STRUCT_ARRAY, |
608 XD_OPAQUE_DATA_PTR, | 773 XD_OPAQUE_DATA_PTR, |
609 XD_UNION, | 774 XD_UNION, |
775 XD_UNION_DYNAMIC_SIZE, | |
610 XD_C_STRING, | 776 XD_C_STRING, |
611 XD_DOC_STRING, | 777 XD_DOC_STRING, |
612 XD_INT_RESET, | 778 XD_INT_RESET, |
613 XD_BYTECOUNT, | 779 XD_BYTECOUNT, |
614 XD_ELEMCOUNT, | 780 XD_ELEMCOUNT, |
615 XD_HASHCODE, | 781 XD_HASHCODE, |
616 XD_INT, | 782 XD_INT, |
617 XD_LONG, | 783 XD_LONG, |
618 XD_END, | 784 XD_END |
619 XD_SPECIFIER_END, | |
620 XD_CODING_SYSTEM_END | |
621 }; | 785 }; |
622 | 786 |
623 struct lrecord_description | 787 enum data_description_entry_flags |
624 { | 788 { |
625 enum lrecord_description_type type; | 789 /* If set, KKCC does not process this entry. |
626 int offset; | 790 |
791 (1) One obvious use is with things that pdump saves but which do not get | |
792 marked normally -- for example the next and prev fields in a marker. The | |
793 marker chain is weak, with its entries removed when they are finalized. | |
794 | |
795 (2) This can be set on structures not containing any Lisp objects, or (more | |
796 usefully) on structures that contain Lisp objects but where the objects | |
797 always occur in another structure as well. For example, the extent lists | |
798 kept by a buffer keep the extents in two lists, one sorted by the start | |
799 of the extent and the other by the end. There's no point in marking | |
800 both, since each contains the same objects as the other; but when dumping | |
801 (if we were to dump such a structure), when computing memory size, etc., | |
802 it's crucial to tag both sides. | |
803 */ | |
804 XD_FLAG_NO_KKCC = 1, | |
805 /* If set, pdump does not process this entry. */ | |
806 XD_FLAG_NO_PDUMP = 2, | |
807 /* Indicates that this is a "default" entry in a union map. */ | |
808 XD_FLAG_UNION_DEFAULT_ENTRY = 4, | |
809 /* Indicates that this is a free Lisp object we're marking. | |
810 Only relevant for ERROR_CHECK_GC. This occurs when we're marking | |
811 lcrecord-lists, where the objects have had their type changed to | |
812 lrecord_type_free and also have had their free bit set, but we mark | |
813 them as normal. */ | |
814 XD_FLAG_FREE_LISP_OBJECT = 8, | |
815 #if 0 | |
816 /* Suggestions for other possible flags: */ | |
817 | |
818 /* Eliminate XD_UNION_DYNAMIC_SIZE and replace it with a flag, like this. */ | |
819 XD_FLAG_UNION_DYNAMIC_SIZE = 16, | |
820 /* Require that everyone who uses a description map has to flag it, so | |
821 that it's easy to tell, when looking through the code, where the | |
822 description maps are and who's using them. This might also become | |
823 necessary if for some reason the format of the description map is | |
824 expanded and we need to stick a pointer in the second slot (although | |
825 we could still ensure that the second slot in the first entry was NULL | |
826 or <0). */ | |
827 XD_FLAG_DESCRIPTION_MAP = 32, | |
828 #endif | |
829 }; | |
830 | |
831 struct memory_description | |
832 { | |
833 enum memory_description_type type; | |
834 Bytecount offset; | |
627 EMACS_INT data1; | 835 EMACS_INT data1; |
628 const struct struct_description *data2; | 836 const struct sized_memory_description *data2; |
837 /* Indicates which subsystems process this entry, plus (potentially) other | |
838 flags that apply to this entry. */ | |
839 int flags; | |
629 }; | 840 }; |
630 | 841 |
631 struct struct_description | 842 struct sized_memory_description |
632 { | 843 { |
633 Bytecount size; | 844 Bytecount size; |
634 const struct lrecord_description *description; | 845 const struct memory_description *description; |
635 }; | 846 }; |
636 | 847 |
637 #define XD_INDIRECT(val, delta) (-1-((val)|(delta<<8))) | 848 extern const struct sized_memory_description lisp_object_description; |
638 | 849 |
639 #define XD_IS_INDIRECT(code) (code<0) | 850 #define XD_INDIRECT(val, delta) (-1 - (Bytecount) ((val) | ((delta) << 8))) |
640 #define XD_INDIRECT_VAL(code) ((-1-code) & 255) | 851 |
641 #define XD_INDIRECT_DELTA(code) (((-1-code)>>8) & 255) | 852 #define XD_IS_INDIRECT(code) ((code) < 0) |
642 | 853 #define XD_INDIRECT_VAL(code) ((-1 - (code)) & 255) |
643 #define XD_DYNARR_DESC(base_type, sub_desc) \ | 854 #define XD_INDIRECT_DELTA(code) ((-1 - (code)) >> 8) |
855 | |
856 #define XD_DYNARR_DESC(base_type, sub_desc) \ | |
644 { XD_STRUCT_PTR, offsetof (base_type, base), XD_INDIRECT(1, 0), sub_desc }, \ | 857 { XD_STRUCT_PTR, offsetof (base_type, base), XD_INDIRECT(1, 0), sub_desc }, \ |
645 { XD_INT, offsetof (base_type, cur) }, \ | 858 { XD_INT, offsetof (base_type, cur) }, \ |
646 { XD_INT_RESET, offsetof (base_type, max), XD_INDIRECT(1, 0) } | 859 { XD_INT_RESET, offsetof (base_type, max), XD_INDIRECT(1, 0) } \ |
860 | |
647 | 861 |
648 /* DEFINE_LRECORD_IMPLEMENTATION is for objects with constant size. | 862 /* DEFINE_LRECORD_IMPLEMENTATION is for objects with constant size. |
649 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION is for objects whose size varies. | 863 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION is for objects whose size varies. |
650 */ | 864 */ |
651 | 865 |
654 #else | 868 #else |
655 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype) | 869 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype) |
656 #endif | 870 #endif |
657 | 871 |
658 | 872 |
659 #ifdef USE_KKCC | |
660 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ | 873 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,structtype) \ |
661 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) | 874 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) |
662 | 875 |
663 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ | 876 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ |
664 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype) | 877 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype) |
677 | 890 |
678 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | 891 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ |
679 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | 892 MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) |
680 | 893 |
681 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 894 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
682 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 895 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
683 const struct lrecord_implementation lrecord_##c_name = \ | 896 const struct lrecord_implementation lrecord_##c_name = \ |
684 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 897 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
685 getprop, putprop, remprop, plist, size, sizer, \ | 898 getprop, putprop, remprop, plist, size, sizer, \ |
686 lrecord_type_##c_name, basic_p } | 899 lrecord_type_##c_name, basic_p } |
687 | 900 |
696 | 909 |
697 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | 910 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ |
698 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | 911 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) |
699 | 912 |
700 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 913 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
701 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | 914 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ |
702 int lrecord_type_##c_name; \ | 915 int lrecord_type_##c_name; \ |
703 struct lrecord_implementation lrecord_##c_name = \ | 916 struct lrecord_implementation lrecord_##c_name = \ |
704 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | 917 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ |
705 getprop, putprop, remprop, plist, size, sizer, \ | 918 getprop, putprop, remprop, plist, size, sizer, \ |
706 lrecord_type_last_built_in_type, basic_p } | 919 lrecord_type_last_built_in_type, basic_p } |
707 | |
708 #else /* not USE_KKCC */ | |
709 | |
710 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ | |
711 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) | |
712 | |
713 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ | |
714 MAKE_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype) | |
715 | |
716 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ | |
717 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) | |
718 | |
719 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ | |
720 MAKE_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype) | |
721 | |
722 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ | |
723 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) | |
724 | |
725 #define DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ | |
726 MAKE_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype) | |
727 | |
728 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | |
729 MAKE_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | |
730 | |
731 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | |
732 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | |
733 const struct lrecord_implementation lrecord_##c_name = \ | |
734 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | |
735 getprop, putprop, remprop, plist, size, sizer, \ | |
736 lrecord_type_##c_name, basic_p } | |
737 | |
738 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \ | |
739 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype) | |
740 | |
741 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \ | |
742 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype) | |
743 | |
744 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ | |
745 DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype) | |
746 | |
747 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | |
748 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,0,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) | |
749 | |
750 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,dumpable,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | |
751 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \ | |
752 int lrecord_type_##c_name; \ | |
753 struct lrecord_implementation lrecord_##c_name = \ | |
754 { name, dumpable, marker, printer, nuker, equal, hash, desc, \ | |
755 getprop, putprop, remprop, plist, size, sizer, \ | |
756 lrecord_type_last_built_in_type, basic_p } | |
757 #endif /* not USE_KKCC */ | |
758 | 920 |
759 extern Lisp_Object (*lrecord_markers[]) (Lisp_Object); | 921 extern Lisp_Object (*lrecord_markers[]) (Lisp_Object); |
760 | 922 |
761 #define INIT_LRECORD_IMPLEMENTATION(type) do { \ | 923 #define INIT_LRECORD_IMPLEMENTATION(type) do { \ |
762 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ | 924 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \ |
807 3. Add this header file to inline.c. | 969 3. Add this header file to inline.c. |
808 | 970 |
809 4. Create the methods for your object. Note that technically you don't | 971 4. Create the methods for your object. Note that technically you don't |
810 need any, but you will almost always want at least a mark method. | 972 need any, but you will almost always want at least a mark method. |
811 | 973 |
812 5. Define your object with DEFINE_LRECORD_IMPLEMENTATION() or some | 974 4. Create the data layout description for your object. See |
975 toolbar_button_description below; the comment above in `struct lrecord', | |
976 describing the purpose of the descriptions; and comments elsewhere in | |
977 this file describing the exact syntax of the description structures. | |
978 | |
979 6. Define your object with DEFINE_LRECORD_IMPLEMENTATION() or some | |
813 variant. | 980 variant. |
814 | 981 |
815 6. Include the header file in the .c file where you defined the object. | 982 7. Include the header file in the .c file where you defined the object. |
816 | 983 |
817 7. Put a call to INIT_LRECORD_IMPLEMENTATION() for the object in the | 984 8. Put a call to INIT_LRECORD_IMPLEMENTATION() for the object in the |
818 .c file's syms_of_foo() function. | 985 .c file's syms_of_foo() function. |
819 | 986 |
820 8. Add a type enum for the object to enum lrecord_type, earlier in this | 987 9. Add a type enum for the object to enum lrecord_type, earlier in this |
821 file. | 988 file. |
989 | |
990 --ben | |
822 | 991 |
823 An example: | 992 An example: |
824 | 993 |
825 ------------------------------ in toolbar.h ----------------------------- | 994 ------------------------------ in toolbar.h ----------------------------- |
826 | 995 |
868 | 1037 |
869 #include "toolbar.h" | 1038 #include "toolbar.h" |
870 | 1039 |
871 ... | 1040 ... |
872 | 1041 |
1042 static const struct memory_description toolbar_button_description [] = { | |
1043 { XD_LISP_OBJECT, offsetof (struct toolbar_button, next) }, | |
1044 { XD_LISP_OBJECT, offsetof (struct toolbar_button, frame) }, | |
1045 { XD_LISP_OBJECT, offsetof (struct toolbar_button, up_glyph) }, | |
1046 { XD_LISP_OBJECT, offsetof (struct toolbar_button, down_glyph) }, | |
1047 { XD_LISP_OBJECT, offsetof (struct toolbar_button, disabled_glyph) }, | |
1048 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_up_glyph) }, | |
1049 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_down_glyph) }, | |
1050 { XD_LISP_OBJECT, offsetof (struct toolbar_button, cap_disabled_glyph) }, | |
1051 { XD_LISP_OBJECT, offsetof (struct toolbar_button, callback) }, | |
1052 { XD_LISP_OBJECT, offsetof (struct toolbar_button, enabled_p) }, | |
1053 { XD_LISP_OBJECT, offsetof (struct toolbar_button, help_string) }, | |
1054 { XD_END } | |
1055 }; | |
1056 | |
873 static Lisp_Object | 1057 static Lisp_Object |
874 mark_toolbar_button (Lisp_Object obj) | 1058 mark_toolbar_button (Lisp_Object obj) |
875 { | 1059 \{ |
876 struct toolbar_button *data = XTOOLBAR_BUTTON (obj); | 1060 struct toolbar_button *data = XTOOLBAR_BUTTON (obj); |
877 mark_object (data->next); | 1061 mark_object (data->next); |
878 mark_object (data->frame); | 1062 mark_object (data->frame); |
879 mark_object (data->up_glyph); | 1063 mark_object (data->up_glyph); |
880 mark_object (data->down_glyph); | 1064 mark_object (data->down_glyph); |
889 | 1073 |
890 [[ If your object should never escape to Lisp, declare its print method | 1074 [[ If your object should never escape to Lisp, declare its print method |
891 as internal_object_printer instead of 0. ]] | 1075 as internal_object_printer instead of 0. ]] |
892 | 1076 |
893 DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button, | 1077 DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button, |
894 mark_toolbar_button, 0, | 1078 0, mark_toolbar_button, 0, 0, 0, 0, |
895 0, 0, 0, 0, struct toolbar_button); | 1079 toolbar_button_description, |
1080 struct toolbar_button); | |
896 | 1081 |
897 ... | 1082 ... |
898 | 1083 |
899 void | 1084 void |
900 syms_of_toolbar (void) | 1085 syms_of_toolbar (void) |
916 { | 1101 { |
917 ... | 1102 ... |
918 lrecord_type_toolbar_button, | 1103 lrecord_type_toolbar_button, |
919 ... | 1104 ... |
920 }; | 1105 }; |
1106 | |
1107 | |
1108 --ben | |
921 | 1109 |
922 */ | 1110 */ |
923 | 1111 |
924 /* | 1112 /* |
925 | 1113 |
1049 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \ | 1237 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \ |
1050 if (XTYPE (x) != lisp_enum) \ | 1238 if (XTYPE (x) != lisp_enum) \ |
1051 dead_wrong_type_argument (predicate, x); \ | 1239 dead_wrong_type_argument (predicate, x); \ |
1052 } while (0) | 1240 } while (0) |
1053 | 1241 |
1242 /*-------------------------- lcrecord-list -----------------------------*/ | |
1243 | |
1244 struct lcrecord_list | |
1245 { | |
1246 struct lcrecord_header header; | |
1247 Lisp_Object free; | |
1248 Elemcount size; | |
1249 const struct lrecord_implementation *implementation; | |
1250 }; | |
1251 | |
1252 DECLARE_LRECORD (lcrecord_list, struct lcrecord_list); | |
1253 #define XLCRECORD_LIST(x) XRECORD (x, lcrecord_list, struct lcrecord_list) | |
1254 #define wrap_lcrecord_list(p) wrap_record (p, lcrecord_list) | |
1255 #define LCRECORD_LISTP(x) RECORDP (x, lcrecord_list) | |
1256 /* #define CHECK_LCRECORD_LIST(x) CHECK_RECORD (x, lcrecord_list) | |
1257 Lcrecord lists should never escape to the Lisp level, so | |
1258 functions should not be doing this. */ | |
1259 | |
1054 /* Various ways of allocating lcrecords. All bytes (except lcrecord | 1260 /* Various ways of allocating lcrecords. All bytes (except lcrecord |
1055 header) are zeroed in returned structure. */ | 1261 header) are zeroed in returned structure. |
1056 | 1262 |
1057 void *alloc_lcrecord (Bytecount size, | 1263 See above for a discussion of the difference between plain lrecords and |
1058 const struct lrecord_implementation *); | 1264 lrecords. lcrecords themselves are divided into three types: (1) |
1059 | 1265 auto-managed, (2) hand-managed, and (3) unmanaged. "Managed" refers to |
1266 using a special object called an lcrecord-list to keep track of freed | |
1267 lcrecords, which can freed with free_lcrecord() or the like and later be | |
1268 recycled when a new lcrecord is required, rather than requiring new | |
1269 malloc(). Thus, allocation of lcrecords can be very | |
1270 cheap. (Technically, the lcrecord-list manager could divide up large | |
1271 chunks of memory and allocate out of that, mimicking what happens with | |
1272 lrecords. At that point, however, we'd want to rethink the whole | |
1273 division between lrecords and lcrecords.) | |
1274 | |
1275 NOTE: There is a fundamental limitation of lcrecord-lists, which is that | |
1276 they only handle blocks of a particular, fixed size. Thus, objects that | |
1277 can be of varying sizes need to do various tricks. These considerations | |
1278 in particular dictate the various types of management: | |
1279 | |
1280 -- "Auto-managed" means that you just go ahead and allocate the lcrecord | |
1281 whenever you want, using alloc_lcrecord_type(), and the appropriate | |
1282 lcrecord-list manager is automatically created. To free, you just call | |
1283 "free_lcrecord()" and the appropriate lcrecord-list manager is | |
1284 automatically located and called. The limitation here of course is that | |
1285 all your objects are of the same size. (#### Eventually we should have a | |
1286 more sophisticated system that tracks the sizes seen and creates one | |
1287 lcrecord list per size, indexed in a hash table. Usually there are only | |
1288 a limited number of sizes, so this works well.) | |
1289 | |
1290 -- "Hand-managed" exists because we haven't yet written the more | |
1291 sophisticated scheme for auto-handling different-sized lcrecords, as | |
1292 described in the end of the last paragraph. In this model, you go ahead | |
1293 and create the lcrecord-list objects yourself for the sizes you will | |
1294 need, using make_lcrecord_list(). Then, create lcrecords using | |
1295 alloc_managed_lcrecord(), passing in the lcrecord-list you created, and | |
1296 free them with free_managed_lcrecord(). | |
1297 | |
1298 -- "Unmanaged" means you simply allocate lcrecords, period. No | |
1299 lcrecord-lists, no way to free them. This may be suitable when the | |
1300 lcrecords are variable-sized and (a) you're too lazy to write the code | |
1301 to hand-manage them, or (b) the objects you create are always or almost | |
1302 always Lisp-visible, and thus there's no point in freeing them (and it | |
1303 wouldn't be safe to do so). You just create them with | |
1304 basic_alloc_lcrecord(), and that's it. | |
1305 | |
1306 --ben | |
1307 | |
1308 Here is an in-depth look at the steps required to create a allocate an | |
1309 lcrecord using the hand-managed style. Since this is the most | |
1310 complicated, you will learn a lot about the other styles as well. In | |
1311 addition, there is useful general information about what freeing an | |
1312 lcrecord really entails, and what are the precautions: | |
1313 | |
1314 1) Create an lcrecord-list object using make_lcrecord_list(). This is | |
1315 often done at initialization. Remember to staticpro_nodump() this | |
1316 object! The arguments to make_lcrecord_list() are the same as would be | |
1317 passed to basic_alloc_lcrecord(). | |
1318 | |
1319 2) Instead of calling basic_alloc_lcrecord(), call alloc_managed_lcrecord() | |
1320 and pass the lcrecord-list earlier created. | |
1321 | |
1322 3) When done with the lcrecord, call free_managed_lcrecord(). The | |
1323 standard freeing caveats apply: ** make sure there are no pointers to | |
1324 the object anywhere! ** | |
1325 | |
1326 4) Calling free_managed_lcrecord() is just like kissing the | |
1327 lcrecord goodbye as if it were garbage-collected. This means: | |
1328 -- the contents of the freed lcrecord are undefined, and the | |
1329 contents of something produced by alloc_managed_lcrecord() | |
1330 are undefined, just like for basic_alloc_lcrecord(). | |
1331 -- the mark method for the lcrecord's type will *NEVER* be called | |
1332 on freed lcrecords. | |
1333 -- the finalize method for the lcrecord's type will be called | |
1334 at the time that free_managed_lcrecord() is called. | |
1335 */ | |
1336 | |
1337 /* UNMANAGED MODEL: */ | |
1338 void *basic_alloc_lcrecord (Bytecount size, | |
1339 const struct lrecord_implementation *); | |
1340 | |
1341 /* HAND-MANAGED MODEL: */ | |
1342 Lisp_Object make_lcrecord_list (Elemcount size, | |
1343 const struct lrecord_implementation | |
1344 *implementation); | |
1345 Lisp_Object alloc_managed_lcrecord (Lisp_Object lcrecord_list); | |
1346 void free_managed_lcrecord (Lisp_Object lcrecord_list, Lisp_Object lcrecord); | |
1347 | |
1348 /* AUTO-MANAGED MODEL: */ | |
1060 void *alloc_automanaged_lcrecord (Bytecount size, | 1349 void *alloc_automanaged_lcrecord (Bytecount size, |
1061 const struct lrecord_implementation *); | 1350 const struct lrecord_implementation *); |
1062 | |
1063 #define alloc_unmanaged_lcrecord_type(type, lrecord_implementation) \ | |
1064 ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation)) | |
1065 | |
1066 #define alloc_lcrecord_type(type, lrecord_implementation) \ | 1351 #define alloc_lcrecord_type(type, lrecord_implementation) \ |
1067 ((type *) alloc_automanaged_lcrecord (sizeof (type), lrecord_implementation)) | 1352 ((type *) alloc_automanaged_lcrecord (sizeof (type), lrecord_implementation)) |
1068 | |
1069 void free_lcrecord (Lisp_Object rec); | 1353 void free_lcrecord (Lisp_Object rec); |
1070 | 1354 |
1071 | 1355 |
1072 /* Copy the data from one lcrecord structure into another, but don't | 1356 /* Copy the data from one lcrecord structure into another, but don't |
1073 overwrite the header information. */ | 1357 overwrite the header information. */ |
1081 | 1365 |
1082 #define zero_sized_lcrecord(lcr, size) \ | 1366 #define zero_sized_lcrecord(lcr, size) \ |
1083 memset ((char *) (lcr) + sizeof (struct lcrecord_header), 0, \ | 1367 memset ((char *) (lcr) + sizeof (struct lcrecord_header), 0, \ |
1084 (size) - sizeof (struct lcrecord_header)) | 1368 (size) - sizeof (struct lcrecord_header)) |
1085 | 1369 |
1086 #define zero_lcrecord(lcr) zero_sized_lcrecord(lcr, sizeof (*(lcr))) | 1370 #define zero_lcrecord(lcr) zero_sized_lcrecord (lcr, sizeof (*(lcr))) |
1371 | |
1372 DECLARE_INLINE_HEADER ( | |
1373 Bytecount | |
1374 detagged_lisp_object_size (const struct lrecord_header *h) | |
1375 ) | |
1376 { | |
1377 const struct lrecord_implementation *imp = LHEADER_IMPLEMENTATION (h); | |
1378 | |
1379 return (imp->size_in_bytes_method ? | |
1380 imp->size_in_bytes_method (h) : | |
1381 imp->static_size); | |
1382 } | |
1383 | |
1384 DECLARE_INLINE_HEADER ( | |
1385 Bytecount | |
1386 lisp_object_size (Lisp_Object o) | |
1387 ) | |
1388 { | |
1389 return detagged_lisp_object_size (XRECORD_LHEADER (o)); | |
1390 } | |
1391 | |
1392 | |
1393 /************************************************************************/ | |
1394 /* Dumping */ | |
1395 /************************************************************************/ | |
1396 | |
1397 /* dump_add_root_struct_ptr (&var, &desc) dumps the structure pointed to by | |
1398 `var'. This is for a single relocatable pointer located in the data | |
1399 segment (i.e. the block pointed to is in the heap). */ | |
1400 #ifdef PDUMP | |
1401 void dump_add_root_struct_ptr (void *, const struct sized_memory_description *); | |
1402 #else | |
1403 #define dump_add_root_struct_ptr(varaddr,descaddr) DO_NOTHING | |
1404 #endif | |
1405 | |
1406 /* dump_add_opaque (&var, size) dumps the opaque static structure `var'. | |
1407 This is for a static block of memory (in the data segment, not the | |
1408 heap), with no relocatable pointers in it. */ | |
1409 #ifdef PDUMP | |
1410 #define dump_add_opaque(varaddr,size) dump_add_root_block (varaddr, size, NULL) | |
1411 #else | |
1412 #define dump_add_opaque(varaddr,size) DO_NOTHING | |
1413 #endif | |
1414 | |
1415 /* dump_add_root_block (ptr, size, desc) dumps the static structure | |
1416 located at `var' of size SIZE and described by DESC. This is for a | |
1417 static block of memory (in the data segment, not the heap), with | |
1418 relocatable pointers in it. */ | |
1419 #ifdef PDUMP | |
1420 void dump_add_root_block (const void *ptraddress, Bytecount size, | |
1421 const struct memory_description *desc); | |
1422 #else | |
1423 #define dump_add_root_block(ptraddress,desc) DO_NOTHING | |
1424 #endif | |
1425 | |
1426 /* Call dump_add_opaque_int (&int_var) to dump `int_var', of type `int'. */ | |
1427 #ifdef PDUMP | |
1428 #define dump_add_opaque_int(int_varaddr) do { \ | |
1429 int *dao_ = (int_varaddr); /* type check */ \ | |
1430 dump_add_opaque (dao_, sizeof (*dao_)); \ | |
1431 } while (0) | |
1432 #else | |
1433 #define dump_add_opaque_int(int_varaddr) DO_NOTHING | |
1434 #endif | |
1435 | |
1436 /* Call dump_add_opaque_fixnum (&fixnum_var) to dump `fixnum_var', of type | |
1437 `Fixnum'. */ | |
1438 #ifdef PDUMP | |
1439 #define dump_add_opaque_fixnum(fixnum_varaddr) do { \ | |
1440 Fixnum *dao_ = (fixnum_varaddr); /* type check */ \ | |
1441 dump_add_opaque (dao_, sizeof (*dao_)); \ | |
1442 } while (0) | |
1443 #else | |
1444 #define dump_add_opaque_fixnum(fixnum_varaddr) DO_NOTHING | |
1445 #endif | |
1446 | |
1447 /* Call dump_add_root_lisp_object (&var) to ensure that var is properly | |
1448 updated after pdump. */ | |
1449 #ifdef PDUMP | |
1450 void dump_add_root_lisp_object (Lisp_Object *); | |
1451 #else | |
1452 #define dump_add_root_lisp_object(varaddr) DO_NOTHING | |
1453 #endif | |
1454 | |
1455 /* Call dump_add_weak_lisp_object (&var) to ensure that var is properly | |
1456 updated after pdump. var must point to a linked list of objects out of | |
1457 which some may not be dumped */ | |
1458 #ifdef PDUMP | |
1459 void dump_add_weak_object_chain (Lisp_Object *); | |
1460 #else | |
1461 #define dump_add_weak_object_chain(varaddr) DO_NOTHING | |
1462 #endif | |
1463 | |
1464 /* Nonzero means Emacs has already been initialized. | |
1465 Used during startup to detect startup of dumped Emacs. */ | |
1466 extern int initialized; | |
1467 | |
1468 #ifdef PDUMP | |
1469 | |
1470 void pdump_objects_unmark (void); | |
1471 void pdump (void); | |
1472 int pdump_load (const char *argv0); | |
1473 void pdump_backtrace (void); | |
1474 extern unsigned int dump_id; | |
1475 extern char *pdump_start, *pdump_end; | |
1476 | |
1477 #define DUMPEDP(adr) ((((char *)(adr)) < pdump_end) && (((char *)(adr)) >= pdump_start)) | |
1478 | |
1479 #else | |
1480 #define DUMPEDP(adr) 0 | |
1481 #endif | |
1482 | |
1483 /***********************************************************************/ | |
1484 /* data descriptions */ | |
1485 /***********************************************************************/ | |
1486 | |
1487 | |
1488 #if defined (USE_KKCC) || defined (PDUMP) | |
1489 | |
1490 extern int in_pdump; | |
1491 | |
1492 EMACS_INT lispdesc_indirect_count_1 (EMACS_INT code, | |
1493 const struct memory_description *idesc, | |
1494 const void *idata); | |
1495 const struct sized_memory_description *lispdesc_indirect_description_1 | |
1496 (const void *obj, const struct sized_memory_description *sdesc); | |
1497 Bytecount lispdesc_structure_size (const void *obj, | |
1498 const struct sized_memory_description * | |
1499 sdesc); | |
1500 | |
1501 DECLARE_INLINE_HEADER ( | |
1502 EMACS_INT | |
1503 lispdesc_indirect_count (EMACS_INT code, | |
1504 const struct memory_description *idesc, | |
1505 const void *idata) | |
1506 ) | |
1507 { | |
1508 if (XD_IS_INDIRECT (code)) | |
1509 code = lispdesc_indirect_count_1 (code, idesc, idata); | |
1510 return code; | |
1511 } | |
1512 | |
1513 DECLARE_INLINE_HEADER ( | |
1514 const struct sized_memory_description * | |
1515 lispdesc_indirect_description (const void *obj, | |
1516 const struct sized_memory_description *sdesc) | |
1517 ) | |
1518 { | |
1519 if (sdesc->description) | |
1520 return sdesc; | |
1521 else | |
1522 return lispdesc_indirect_description_1 (obj, sdesc); | |
1523 } | |
1524 | |
1525 | |
1526 /* Do standard XD_UNION processing. DESC1 is an entry in DESC, which | |
1527 describes the entire data structure. Returns NULL (do nothing, nothing | |
1528 matched), or a new value for DESC1. In the latter case, assign to DESC1 | |
1529 in your function and goto union_switcheroo. */ | |
1530 | |
1531 DECLARE_INLINE_HEADER ( | |
1532 const struct memory_description * | |
1533 lispdesc_process_xd_union (const struct memory_description *desc1, | |
1534 const struct memory_description *desc, | |
1535 const void *data) | |
1536 ) | |
1537 { | |
1538 int count = 0; | |
1539 EMACS_INT variant = lispdesc_indirect_count (desc1->data1, desc, | |
1540 data); | |
1541 desc1 = | |
1542 lispdesc_indirect_description (data, desc1->data2)->description; | |
1543 | |
1544 for (count = 0; desc1[count].type != XD_END; count++) | |
1545 { | |
1546 if ((desc1[count].flags & XD_FLAG_UNION_DEFAULT_ENTRY) || | |
1547 desc1[count].offset == variant) | |
1548 { | |
1549 return &desc1[count]; | |
1550 } | |
1551 } | |
1552 | |
1553 return NULL; | |
1554 } | |
1555 | |
1556 #endif /* defined (USE_KKCC) || defined (PDUMP) */ | |
1087 | 1557 |
1088 #endif /* INCLUDED_lrecord_h_ */ | 1558 #endif /* INCLUDED_lrecord_h_ */ |