Mercurial > hg > xemacs-beta
comparison src/dumper.c @ 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 | c925bacdda60 |
children | 1b0339b048ce |
comparison
equal
deleted
inserted
replaced
1203:5f2f8dcbfb3e | 1204:e22b0213b713 |
---|---|
28 #include "lisp.h" | 28 #include "lisp.h" |
29 | 29 |
30 #include "specifier.h" | 30 #include "specifier.h" |
31 #include "file-coding.h" | 31 #include "file-coding.h" |
32 #include "elhash.h" | 32 #include "elhash.h" |
33 #include "lstream.h" | |
33 #include "sysfile.h" | 34 #include "sysfile.h" |
34 #include "console-stream.h" | 35 #include "console-stream.h" |
35 #include "dumper.h" | |
36 | 36 |
37 #ifdef WIN32_NATIVE | 37 #ifdef WIN32_NATIVE |
38 #include "syswindows.h" | 38 #include "syswindows.h" |
39 #else | 39 #else |
40 #ifdef HAVE_MMAP | 40 #ifdef HAVE_MMAP |
44 | 44 |
45 typedef struct | 45 typedef struct |
46 { | 46 { |
47 const void *varaddress; | 47 const void *varaddress; |
48 Bytecount size; | 48 Bytecount size; |
49 } pdump_opaque; | 49 const struct memory_description *desc; |
50 } pdump_root_block; | |
50 | 51 |
51 typedef struct | 52 typedef struct |
52 { | 53 { |
53 Dynarr_declare (pdump_opaque); | 54 Dynarr_declare (pdump_root_block); |
54 } pdump_opaque_dynarr; | 55 } pdump_root_block_dynarr; |
55 | 56 |
56 typedef struct | 57 typedef struct |
57 { | 58 { |
58 void **ptraddress; | 59 void **ptraddress; |
59 const struct struct_description *desc; | 60 const struct sized_memory_description *desc; |
60 } pdump_root_struct_ptr; | 61 } pdump_root_struct_ptr; |
61 | 62 |
62 typedef struct | 63 typedef struct |
63 { | 64 { |
64 Dynarr_declare (pdump_root_struct_ptr); | 65 Dynarr_declare (pdump_root_struct_ptr); |
74 { | 75 { |
75 char **address; /* char * for ease of doing relocation */ | 76 char **address; /* char * for ease of doing relocation */ |
76 char * value; | 77 char * value; |
77 } pdump_static_pointer; | 78 } pdump_static_pointer; |
78 | 79 |
79 static pdump_opaque_dynarr *pdump_opaques; | 80 static pdump_root_block_dynarr *pdump_root_blocks; |
80 static pdump_root_struct_ptr_dynarr *pdump_root_struct_ptrs; | 81 static pdump_root_struct_ptr_dynarr *pdump_root_struct_ptrs; |
81 static Lisp_Object_ptr_dynarr *pdump_root_objects; | 82 static Lisp_Object_ptr_dynarr *pdump_root_lisp_objects; |
82 static Lisp_Object_ptr_dynarr *pdump_weak_object_chains; | 83 static Lisp_Object_ptr_dynarr *pdump_weak_object_chains; |
83 | 84 |
84 /* Mark SIZE bytes at non-heap address VARADDRESS for dumping as is, | 85 /* Mark SIZE bytes at non-heap address VARADDRESS for dumping, described |
85 without any bit-twiddling. */ | 86 by DESC. */ |
86 void | 87 void |
87 dump_add_opaque (const void *varaddress, Bytecount size) | 88 dump_add_root_block (const void *varaddress, Bytecount size, |
88 { | 89 const struct memory_description *desc) |
89 pdump_opaque info; | 90 { |
91 pdump_root_block info; | |
90 info.varaddress = varaddress; | 92 info.varaddress = varaddress; |
91 info.size = size; | 93 info.size = size; |
92 if (pdump_opaques == NULL) | 94 info.desc = desc; |
93 pdump_opaques = Dynarr_new (pdump_opaque); | 95 if (pdump_root_blocks == NULL) |
94 Dynarr_add (pdump_opaques, info); | 96 pdump_root_blocks = Dynarr_new (pdump_root_block); |
97 Dynarr_add (pdump_root_blocks, info); | |
95 } | 98 } |
96 | 99 |
97 /* Mark the struct described by DESC and pointed to by the pointer at | 100 /* Mark the struct described by DESC and pointed to by the pointer at |
98 non-heap address VARADDRESS for dumping. | 101 non-heap address VARADDRESS for dumping. |
99 All the objects reachable from this pointer will also be dumped. */ | 102 All the objects reachable from this pointer will also be dumped. */ |
100 void | 103 void |
101 dump_add_root_struct_ptr (void *ptraddress, | 104 dump_add_root_struct_ptr (void *ptraddress, |
102 const struct struct_description *desc) | 105 const struct sized_memory_description *desc) |
103 { | 106 { |
104 pdump_root_struct_ptr info; | 107 pdump_root_struct_ptr info; |
105 info.ptraddress = (void **) ptraddress; | 108 info.ptraddress = (void **) ptraddress; |
106 info.desc = desc; | 109 info.desc = desc; |
107 if (pdump_root_struct_ptrs == NULL) | 110 if (pdump_root_struct_ptrs == NULL) |
110 } | 113 } |
111 | 114 |
112 /* Mark the Lisp_Object at non-heap address VARADDRESS for dumping. | 115 /* Mark the Lisp_Object at non-heap address VARADDRESS for dumping. |
113 All the objects reachable from this var will also be dumped. */ | 116 All the objects reachable from this var will also be dumped. */ |
114 void | 117 void |
115 dump_add_root_object (Lisp_Object *varaddress) | 118 dump_add_root_lisp_object (Lisp_Object *varaddress) |
116 { | 119 { |
117 if (pdump_root_objects == NULL) | 120 if (pdump_root_lisp_objects == NULL) |
118 pdump_root_objects = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); | 121 pdump_root_lisp_objects = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); |
119 Dynarr_add (pdump_root_objects, varaddress); | 122 Dynarr_add (pdump_root_lisp_objects, varaddress); |
120 } | 123 } |
121 | 124 |
122 /* Mark the list pointed to by the Lisp_Object at VARADDRESS for dumping. */ | 125 /* Mark the list pointed to by the Lisp_Object at VARADDRESS for dumping. */ |
123 void | 126 void |
124 dump_add_weak_object_chain (Lisp_Object *varaddress) | 127 dump_add_weak_object_chain (Lisp_Object *varaddress) |
156 | 159 |
157 | 160 |
158 | 161 |
159 typedef struct | 162 typedef struct |
160 { | 163 { |
161 const struct lrecord_description *desc; | 164 const struct memory_description *desc; |
162 int count; | 165 int count; |
163 } pdump_reloc_table; | 166 } pdump_reloc_table; |
164 | 167 |
165 static char *pdump_rt_list = 0; | 168 static char *pdump_rt_list = 0; |
166 | 169 |
187 break; | 190 break; |
188 } | 191 } |
189 } | 192 } |
190 | 193 |
191 | 194 |
192 /* The structure of the file | 195 /* The structure of the dump file looks like this: |
193 0 - header | 196 0 - header |
194 - dumped objects | 197 - dumped objects |
195 stab_offset - nb_root_struct_ptrs*pair(void *, adr) | 198 stab_offset - nb_root_struct_ptrs*struct(void *, adr) |
196 for pointers to structures | 199 for global pointers to structures |
197 - nb_opaques*pair(void *, size) for raw bits to restore | 200 - nb_root_blocks*struct(void *, size, info) for global |
201 objects to restore | |
198 - relocation table | 202 - relocation table |
199 - root lisp object address/value couples with the count | 203 - root lisp object address/value couples with the count |
200 preceding the list | 204 preceding the list |
201 */ | 205 */ |
202 | 206 |
209 char signature[PDUMP_SIGNATURE_LEN]; | 213 char signature[PDUMP_SIGNATURE_LEN]; |
210 unsigned int id; | 214 unsigned int id; |
211 EMACS_UINT stab_offset; | 215 EMACS_UINT stab_offset; |
212 EMACS_UINT reloc_address; | 216 EMACS_UINT reloc_address; |
213 int nb_root_struct_ptrs; | 217 int nb_root_struct_ptrs; |
214 int nb_opaques; | 218 int nb_root_blocks; |
215 } pdump_header; | 219 } pdump_header; |
216 | 220 |
217 char *pdump_start; | 221 char *pdump_start; |
218 char *pdump_end; | 222 char *pdump_end; |
219 static Bytecount pdump_length; | 223 static Bytecount pdump_length; |
258 } pdump_entry_list; | 262 } pdump_entry_list; |
259 | 263 |
260 typedef struct pdump_struct_list_elt | 264 typedef struct pdump_struct_list_elt |
261 { | 265 { |
262 pdump_entry_list list; | 266 pdump_entry_list list; |
263 const struct struct_description *sdesc; | 267 const struct memory_description *desc; |
264 } pdump_struct_list_elt; | 268 } pdump_struct_list_elt; |
265 | 269 |
266 typedef struct | 270 typedef struct |
267 { | 271 { |
268 pdump_struct_list_elt *list; | 272 pdump_struct_list_elt *list; |
348 list->align = align; | 352 list->align = align; |
349 } | 353 } |
350 } | 354 } |
351 | 355 |
352 static pdump_entry_list * | 356 static pdump_entry_list * |
353 pdump_get_entry_list (const struct struct_description *sdesc) | 357 pdump_get_entry_list (const struct memory_description *desc) |
354 { | 358 { |
355 int i; | 359 int i; |
356 for (i=0; i<pdump_struct_table.count; i++) | 360 for (i=0; i<pdump_struct_table.count; i++) |
357 if (pdump_struct_table.list[i].sdesc == sdesc) | 361 if (pdump_struct_table.list[i].desc == desc) |
358 return &pdump_struct_table.list[i].list; | 362 return &pdump_struct_table.list[i].list; |
359 | 363 |
360 if (pdump_struct_table.size <= pdump_struct_table.count) | 364 if (pdump_struct_table.size <= pdump_struct_table.count) |
361 { | 365 { |
362 if (pdump_struct_table.size == -1) | 366 if (pdump_struct_table.size == -1) |
368 pdump_struct_table.size * sizeof (pdump_struct_list_elt)); | 372 pdump_struct_table.size * sizeof (pdump_struct_list_elt)); |
369 } | 373 } |
370 pdump_struct_table.list[pdump_struct_table.count].list.first = 0; | 374 pdump_struct_table.list[pdump_struct_table.count].list.first = 0; |
371 pdump_struct_table.list[pdump_struct_table.count].list.align = ALIGNOF (max_align_t); | 375 pdump_struct_table.list[pdump_struct_table.count].list.align = ALIGNOF (max_align_t); |
372 pdump_struct_table.list[pdump_struct_table.count].list.count = 0; | 376 pdump_struct_table.list[pdump_struct_table.count].list.count = 0; |
373 pdump_struct_table.list[pdump_struct_table.count].sdesc = sdesc; | 377 pdump_struct_table.list[pdump_struct_table.count].desc = desc; |
374 | 378 |
375 return &pdump_struct_table.list[pdump_struct_table.count++].list; | 379 return &pdump_struct_table.list[pdump_struct_table.count++].list; |
376 } | 380 } |
377 | 381 |
378 static struct | 382 static struct |
380 struct lrecord_header *obj; | 384 struct lrecord_header *obj; |
381 int position; | 385 int position; |
382 int offset; | 386 int offset; |
383 } backtrace[65536]; | 387 } backtrace[65536]; |
384 | 388 |
385 static int depth; | 389 static int pdump_depth; |
386 | 390 |
387 static void | 391 void |
388 pdump_backtrace (void) | 392 pdump_backtrace (void) |
389 { | 393 { |
390 int i; | 394 int i; |
391 stderr_out ("pdump backtrace :\n"); | 395 stderr_out ("pdump backtrace :\n"); |
392 for (i = 0; i < depth; i++) | 396 for (i = 0; i < pdump_depth; i++) |
393 { | 397 { |
394 if (!backtrace[i].obj) | 398 if (!backtrace[i].obj) |
395 stderr_out (" - ind. (%d, %d)\n", | 399 stderr_out (" - ind. (%d, %d)\n", |
396 backtrace[i].position, | 400 backtrace[i].position, |
397 backtrace[i].offset); | 401 backtrace[i].offset); |
398 else | 402 else |
399 { | 403 { |
400 stderr_out (" - %s (%d, %d)\n", | 404 stderr_out (" - %s (%d, %d)\n", |
401 LHEADER_IMPLEMENTATION (backtrace[i].obj)->name, | 405 LHEADER_IMPLEMENTATION (backtrace[i].obj)->name, |
402 backtrace[i].position, | 406 backtrace[i].position, |
403 backtrace[i].offset); | 407 backtrace[i].offset); |
404 } | 408 } |
405 } | 409 } |
410 } | |
411 | |
412 static void | |
413 pdump_bump_depth (void) | |
414 { | |
415 int me = pdump_depth++; | |
416 if (me > 65536) | |
417 { | |
418 stderr_out ("Backtrace overflow, loop ?\n"); | |
419 abort (); | |
420 } | |
421 backtrace[me].obj = 0; | |
422 backtrace[me].position = 0; | |
423 backtrace[me].offset = 0; | |
406 } | 424 } |
407 | 425 |
408 static void pdump_register_object (Lisp_Object obj); | 426 static void pdump_register_object (Lisp_Object obj); |
409 static void pdump_register_struct_contents (const void *data, | 427 static void pdump_register_struct_contents (const void *data, |
410 const struct struct_description * | 428 const struct sized_memory_description * |
411 sdesc, | 429 sdesc, |
412 int count); | 430 int count); |
413 static void pdump_register_struct (const void *data, | 431 static void pdump_register_struct (const void *data, |
414 const struct struct_description *sdesc, | 432 const struct sized_memory_description *sdesc, |
415 int count); | 433 int count); |
416 | 434 |
417 static EMACS_INT | 435 static void |
418 pdump_get_indirect_count (EMACS_INT code, | 436 pdump_register_sub (const void *data, const struct memory_description *desc) |
419 const struct lrecord_description *idesc, | |
420 const void *idata) | |
421 { | |
422 EMACS_INT count; | |
423 const void *irdata; | |
424 | |
425 int line = XD_INDIRECT_VAL (code); | |
426 int delta = XD_INDIRECT_DELTA (code); | |
427 | |
428 irdata = ((char *)idata) + idesc[line].offset; | |
429 switch (idesc[line].type) | |
430 { | |
431 case XD_BYTECOUNT: | |
432 count = *(Bytecount *)irdata; | |
433 break; | |
434 case XD_ELEMCOUNT: | |
435 count = *(Elemcount *)irdata; | |
436 break; | |
437 case XD_HASHCODE: | |
438 count = *(Hashcode *)irdata; | |
439 break; | |
440 case XD_INT: | |
441 count = *(int *)irdata; | |
442 break; | |
443 case XD_LONG: | |
444 count = *(long *)irdata; | |
445 break; | |
446 default: | |
447 stderr_out ("Unsupported count type : %d (line = %d, code=%ld)\n", | |
448 idesc[line].type, line, (long)code); | |
449 pdump_backtrace (); | |
450 count = 0; /* warning suppression */ | |
451 abort (); | |
452 } | |
453 count += delta; | |
454 return count; | |
455 } | |
456 | |
457 static void | |
458 pdump_register_sub (const void *data, const struct lrecord_description *desc, int me) | |
459 { | 437 { |
460 int pos; | 438 int pos; |
461 | 439 int me = pdump_depth - 1; |
462 restart: | 440 |
463 for (pos = 0; desc[pos].type != XD_END; pos++) | 441 for (pos = 0; desc[pos].type != XD_END; pos++) |
464 { | 442 { |
465 const void *rdata = (const char *)data + desc[pos].offset; | 443 const struct memory_description *desc1 = &desc[pos]; |
444 EMACS_INT offset = lispdesc_indirect_count (desc1->offset, desc, | |
445 data); | |
446 const void *rdata = (const char *) data + offset; | |
466 | 447 |
467 backtrace[me].position = pos; | 448 backtrace[me].position = pos; |
468 backtrace[me].offset = desc[pos].offset; | 449 backtrace[me].offset = offset; |
469 | 450 |
470 switch (desc[pos].type) | 451 union_switcheroo: |
452 | |
453 /* If the flag says don't dump, then don't dump. */ | |
454 if ((desc1->flags) & XD_FLAG_NO_PDUMP) | |
455 continue; | |
456 | |
457 switch (desc1->type) | |
471 { | 458 { |
472 case XD_SPECIFIER_END: | |
473 pos = 0; | |
474 desc = ((const Lisp_Specifier *)data)->methods->extra_description; | |
475 goto restart; | |
476 case XD_CODING_SYSTEM_END: | |
477 pos = 0; | |
478 desc = | |
479 ((const Lisp_Coding_System *)data)->methods->extra_description; | |
480 goto restart; | |
481 case XD_BYTECOUNT: | 459 case XD_BYTECOUNT: |
482 case XD_ELEMCOUNT: | 460 case XD_ELEMCOUNT: |
483 case XD_HASHCODE: | 461 case XD_HASHCODE: |
484 case XD_INT: | 462 case XD_INT: |
485 case XD_LONG: | 463 case XD_LONG: |
486 case XD_INT_RESET: | 464 case XD_INT_RESET: |
487 case XD_LO_LINK: | 465 case XD_LO_LINK: |
488 break; | 466 break; |
489 case XD_OPAQUE_DATA_PTR: | 467 case XD_OPAQUE_DATA_PTR: |
490 { | 468 { |
491 EMACS_INT count = desc[pos].data1; | 469 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, |
492 if (XD_IS_INDIRECT (count)) | 470 data); |
493 count = pdump_get_indirect_count (count, desc, data); | |
494 | 471 |
495 pdump_add_entry (&pdump_opaque_data_list, | 472 pdump_add_entry (&pdump_opaque_data_list, |
496 *(void **)rdata, count, 1); | 473 *(void **)rdata, count, 1); |
497 break; | 474 break; |
498 } | 475 } |
499 case XD_C_STRING: | 476 case XD_C_STRING: |
500 { | 477 { |
501 const char *str = *(const char **)rdata; | 478 const char *str = * (const char **) rdata; |
502 if (str) | 479 if (str) |
503 pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1); | 480 pdump_add_entry (&pdump_opaque_data_list, str, strlen (str) + 1, |
481 1); | |
504 break; | 482 break; |
505 } | 483 } |
506 case XD_DOC_STRING: | 484 case XD_DOC_STRING: |
507 { | 485 { |
508 const char *str = *(const char **)rdata; | 486 const char *str = * (const char **) rdata; |
509 if ((EMACS_INT)str > 0) | 487 if ((EMACS_INT) str > 0) |
510 pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1); | 488 pdump_add_entry (&pdump_opaque_data_list, str, strlen (str) + 1, |
489 1); | |
511 break; | 490 break; |
512 } | 491 } |
513 case XD_LISP_OBJECT: | 492 case XD_LISP_OBJECT: |
514 { | 493 { |
515 const Lisp_Object *pobj = (const Lisp_Object *)rdata; | 494 const Lisp_Object *pobj = (const Lisp_Object *) rdata; |
516 | 495 |
517 assert (desc[pos].data1 == 0); | 496 assert (desc1->data1 == 0); |
518 | 497 |
519 backtrace[me].offset = (const char *)pobj - (const char *)data; | 498 backtrace[me].offset = (const char *) pobj - (const char *) data; |
520 pdump_register_object (*pobj); | 499 pdump_register_object (*pobj); |
521 break; | 500 break; |
522 } | 501 } |
523 case XD_LISP_OBJECT_ARRAY: | 502 case XD_LISP_OBJECT_ARRAY: |
524 { | 503 { |
525 int i; | 504 int i; |
526 EMACS_INT count = desc[pos].data1; | 505 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, |
527 if (XD_IS_INDIRECT (count)) | 506 data); |
528 count = pdump_get_indirect_count (count, desc, data); | |
529 | 507 |
530 for (i = 0; i < count; i++) | 508 for (i = 0; i < count; i++) |
531 { | 509 { |
532 const Lisp_Object *pobj = ((const Lisp_Object *)rdata) + i; | 510 const Lisp_Object *pobj = ((const Lisp_Object *) rdata) + i; |
533 Lisp_Object dobj = *pobj; | 511 Lisp_Object dobj = *pobj; |
534 | 512 |
535 backtrace[me].offset = (const char *)pobj - (const char *)data; | 513 backtrace[me].offset = |
514 (const char *) pobj - (const char *) data; | |
536 pdump_register_object (dobj); | 515 pdump_register_object (dobj); |
537 } | 516 } |
538 break; | 517 break; |
539 } | 518 } |
540 case XD_STRUCT_PTR: | 519 case XD_STRUCT_PTR: |
541 { | 520 { |
542 EMACS_INT count = desc[pos].data1; | 521 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, |
543 const struct struct_description *sdesc = desc[pos].data2; | 522 data); |
523 const struct sized_memory_description *sdesc = | |
524 lispdesc_indirect_description (data, desc1->data2); | |
544 const char *dobj = *(const char **)rdata; | 525 const char *dobj = *(const char **)rdata; |
545 if (dobj) | 526 if (dobj) |
546 { | 527 pdump_register_struct (dobj, sdesc, count); |
547 if (XD_IS_INDIRECT (count)) | |
548 count = pdump_get_indirect_count (count, desc, data); | |
549 | |
550 pdump_register_struct (dobj, sdesc, count); | |
551 } | |
552 break; | 528 break; |
553 } | 529 } |
554 case XD_STRUCT_ARRAY: | 530 case XD_STRUCT_ARRAY: |
555 { | 531 { |
556 EMACS_INT count = desc[pos].data1; | 532 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc, |
557 const struct struct_description *sdesc = desc[pos].data2; | 533 data); |
558 | 534 const struct sized_memory_description *sdesc = |
559 if (XD_IS_INDIRECT (count)) | 535 lispdesc_indirect_description (data, desc1->data2); |
560 count = pdump_get_indirect_count (count, desc, data); | |
561 | 536 |
562 pdump_register_struct_contents (rdata, sdesc, count); | 537 pdump_register_struct_contents (rdata, sdesc, count); |
563 break; | 538 break; |
564 } | 539 } |
565 case XD_UNION: | 540 case XD_UNION: |
566 abort (); /* #### IMPLEMENT ME! NEEDED FOR UNICODE SUPPORT */ | 541 case XD_UNION_DYNAMIC_SIZE: |
542 desc1 = lispdesc_process_xd_union (desc1, desc, data); | |
543 if (desc1) | |
544 goto union_switcheroo; | |
545 break; | |
567 | 546 |
568 default: | 547 default: |
569 stderr_out ("Unsupported dump type : %d\n", desc[pos].type); | 548 stderr_out ("Unsupported dump type : %d\n", desc1->type); |
570 pdump_backtrace (); | 549 pdump_backtrace (); |
571 abort (); | 550 abort (); |
572 }; | 551 } |
573 } | 552 } |
574 } | 553 } |
575 | 554 |
576 static void | 555 static void |
577 pdump_register_object (Lisp_Object obj) | 556 pdump_register_object (Lisp_Object obj) |
589 if (pdump_get_entry (objh)) | 568 if (pdump_get_entry (objh)) |
590 return; | 569 return; |
591 | 570 |
592 imp = LHEADER_IMPLEMENTATION (objh); | 571 imp = LHEADER_IMPLEMENTATION (objh); |
593 | 572 |
594 #ifdef USE_KKCC | |
595 if (imp->description | 573 if (imp->description |
596 && RECORD_DUMPABLE(objh)) | 574 && RECORD_DUMPABLE (objh)) |
597 #else /* not USE_KKCC */ | 575 { |
598 if (imp->description) | 576 pdump_bump_depth (); |
599 #endif /* not USE_KKCC */ | 577 backtrace[pdump_depth - 1].obj = objh; |
600 { | |
601 int me = depth++; | |
602 if (me > 65536) | |
603 { | |
604 stderr_out ("Backtrace overflow, loop ?\n"); | |
605 abort (); | |
606 } | |
607 backtrace[me].obj = objh; | |
608 backtrace[me].position = 0; | |
609 backtrace[me].offset = 0; | |
610 | |
611 pdump_add_entry (pdump_object_table + objh->type, | 578 pdump_add_entry (pdump_object_table + objh->type, |
612 objh, | 579 objh, detagged_lisp_object_size (objh), 1); |
613 imp->static_size ? | 580 pdump_register_sub (objh, imp->description); |
614 imp->static_size : | 581 --pdump_depth; |
615 imp->size_in_bytes_method (objh), | |
616 1); | |
617 pdump_register_sub (objh, imp->description, me); | |
618 --depth; | |
619 } | 582 } |
620 else | 583 else |
621 { | 584 { |
622 pdump_alert_undump_object[objh->type]++; | 585 pdump_alert_undump_object[objh->type]++; |
623 stderr_out ("Undumpable object type : %s\n", imp->name); | 586 stderr_out ("Undumpable object type : %s\n", imp->name); |
624 pdump_backtrace (); | 587 pdump_backtrace (); |
625 } | 588 } |
626 } | |
627 | |
628 /* Return the size of the memory block (NOT necessarily a structure!) | |
629 described by SDESC and pointed to by OBJ. If SDESC records an | |
630 explicit size (i.e. non-zero), it is simply returned; otherwise, | |
631 the size is calculated by the maximum offset and the size of the | |
632 object at that offset, rounded up to the maximum alignment. In | |
633 this case, we may need the object, for example when retrieving an | |
634 "indirect count" of an inlined array (the count is not constant, | |
635 but is specified by one of the elements of the memory block). (It | |
636 is generally not a problem if we return an overly large size -- we | |
637 will simply end up reserving more space than necessary; but if the | |
638 size is too small we could be in serious trouble, in particular | |
639 with nested inlined structures, where there may be alignment | |
640 padding in the middle of a block. #### In fact there is an (at | |
641 least theoretical) problem with an overly large size -- we may | |
642 trigger a protection fault when reading from invalid memory. We | |
643 need to handle this -- perhaps in a stupid but dependable way, | |
644 i.e. by trapping SIGSEGV and SIGBUS.) */ | |
645 | |
646 static Bytecount | |
647 pdump_structure_size (const void *obj, const struct struct_description *sdesc) | |
648 { | |
649 int max_offset = -1; | |
650 int max_offset_pos = -1; | |
651 int size_at_max = 0; | |
652 int pos; | |
653 const struct lrecord_description *desc; | |
654 void *rdata; | |
655 | |
656 if (sdesc->size) | |
657 return sdesc->size; | |
658 | |
659 desc = sdesc->description; | |
660 | |
661 for (pos = 0; desc[pos].type != XD_END; pos++) | |
662 { | |
663 if (desc[pos].offset == max_offset) | |
664 { | |
665 stderr_out ("Two relocatable elements at same offset?\n"); | |
666 abort (); | |
667 } | |
668 else if (desc[pos].offset > max_offset) | |
669 { | |
670 max_offset = desc[pos].offset; | |
671 max_offset_pos = pos; | |
672 } | |
673 } | |
674 | |
675 if (max_offset_pos < 0) | |
676 return 0; | |
677 | |
678 pos = max_offset_pos; | |
679 rdata = (char *) obj + desc[pos].offset; | |
680 | |
681 switch (desc[pos].type) | |
682 { | |
683 case XD_LISP_OBJECT_ARRAY: | |
684 { | |
685 EMACS_INT val = desc[pos].data1; | |
686 if (XD_IS_INDIRECT (val)) | |
687 val = pdump_get_indirect_count (val, desc, obj); | |
688 size_at_max = val * sizeof (Lisp_Object); | |
689 break; | |
690 } | |
691 case XD_LISP_OBJECT: | |
692 case XD_LO_LINK: | |
693 size_at_max = sizeof (Lisp_Object); | |
694 break; | |
695 case XD_OPAQUE_PTR: | |
696 size_at_max = sizeof (void *); | |
697 break; | |
698 case XD_STRUCT_PTR: | |
699 { | |
700 EMACS_INT val = desc[pos].data1; | |
701 if (XD_IS_INDIRECT (val)) | |
702 val = pdump_get_indirect_count (val, desc, obj); | |
703 size_at_max = val * sizeof (void *); | |
704 break; | |
705 } | |
706 break; | |
707 case XD_STRUCT_ARRAY: | |
708 { | |
709 EMACS_INT val = desc[pos].data1; | |
710 | |
711 if (XD_IS_INDIRECT (val)) | |
712 val = pdump_get_indirect_count (val, desc, obj); | |
713 | |
714 size_at_max = val * pdump_structure_size (rdata, desc[pos].data2); | |
715 break; | |
716 } | |
717 break; | |
718 case XD_OPAQUE_DATA_PTR: | |
719 size_at_max = sizeof (void *); | |
720 break; | |
721 case XD_UNION: | |
722 abort (); /* #### IMPLEMENT ME! NEEDED FOR UNICODE | |
723 SUPPORT */ | |
724 break; | |
725 case XD_C_STRING: | |
726 size_at_max = sizeof (void *); | |
727 break; | |
728 case XD_DOC_STRING: | |
729 size_at_max = sizeof (void *); | |
730 break; | |
731 case XD_INT_RESET: | |
732 size_at_max = sizeof (int); | |
733 break; | |
734 case XD_BYTECOUNT: | |
735 size_at_max = sizeof (Bytecount); | |
736 break; | |
737 case XD_ELEMCOUNT: | |
738 size_at_max = sizeof (Elemcount); | |
739 break; | |
740 case XD_HASHCODE: | |
741 size_at_max = sizeof (Hashcode); | |
742 break; | |
743 case XD_INT: | |
744 size_at_max = sizeof (int); | |
745 break; | |
746 case XD_LONG: | |
747 size_at_max = sizeof (long); | |
748 break; | |
749 case XD_SPECIFIER_END: | |
750 case XD_CODING_SYSTEM_END: | |
751 stderr_out | |
752 ("Should not be seeing XD_SPECIFIER_END or\n" | |
753 "XD_CODING_SYSTEM_END outside of struct Lisp_Specifier\n" | |
754 "and struct Lisp_Coding_System.\n"); | |
755 abort (); | |
756 default: | |
757 stderr_out ("Unsupported dump type : %d\n", desc[pos].type); | |
758 abort (); | |
759 } | |
760 | |
761 /* We have no way of knowing the required alignment for this structure, | |
762 so just max it maximally aligned. */ | |
763 return MAX_ALIGN_SIZE (max_offset + size_at_max); | |
764 } | 589 } |
765 | 590 |
766 /* Register the referenced objects in the array of COUNT objects of | 591 /* Register the referenced objects in the array of COUNT objects of |
767 located at DATA; each object is described by SDESC. "Object" here | 592 located at DATA; each object is described by SDESC. "Object" here |
768 simply means any block of memory; it need not actually be a C | 593 simply means any block of memory; it need not actually be a C |
774 and thus should not be registered. See pdump_register_struct(), | 599 and thus should not be registered. See pdump_register_struct(), |
775 which does register the memory block. */ | 600 which does register the memory block. */ |
776 | 601 |
777 static void | 602 static void |
778 pdump_register_struct_contents (const void *data, | 603 pdump_register_struct_contents (const void *data, |
779 const struct struct_description *sdesc, | 604 const struct sized_memory_description *sdesc, |
780 int count) | 605 int count) |
781 | 606 |
782 { | 607 { |
783 int me = depth++; | |
784 int i; | 608 int i; |
785 Bytecount elsize; | 609 Bytecount elsize; |
786 | 610 |
787 if (me>65536) | 611 pdump_bump_depth (); |
788 { | 612 elsize = lispdesc_structure_size (data, sdesc); |
789 stderr_out ("Backtrace overflow, loop ?\n"); | |
790 abort (); | |
791 } | |
792 backtrace[me].obj = 0; | |
793 backtrace[me].position = 0; | |
794 backtrace[me].offset = 0; | |
795 | |
796 elsize = pdump_structure_size (data, sdesc); | |
797 | |
798 for (i = 0; i < count; i++) | 613 for (i = 0; i < count; i++) |
799 { | 614 { |
800 pdump_register_sub (((char *) data) + elsize * i, | 615 pdump_register_sub (((char *) data) + elsize * i, sdesc->description); |
801 sdesc->description, | 616 } |
802 me); | 617 --pdump_depth; |
803 } | |
804 --depth; | |
805 } | 618 } |
806 | 619 |
807 /* Register the array of COUNT objects of located at DATA; each object is | 620 /* Register the array of COUNT objects of located at DATA; each object is |
808 described by SDESC. "Object" here simply means any block of memory; | 621 described by SDESC. "Object" here simply means any block of memory; |
809 it need not actually be a C "struct". It could be a single integer | 622 it need not actually be a C "struct". It could be a single integer |
812 This is like pdump_register_struct_contents() but also registers | 625 This is like pdump_register_struct_contents() but also registers |
813 the memory block itself. */ | 626 the memory block itself. */ |
814 | 627 |
815 static void | 628 static void |
816 pdump_register_struct (const void *data, | 629 pdump_register_struct (const void *data, |
817 const struct struct_description *sdesc, | 630 const struct sized_memory_description *sdesc, |
818 int count) | 631 int count) |
819 { | 632 { |
820 if (data && !pdump_get_entry (data)) | 633 if (data && !pdump_get_entry (data)) |
821 { | 634 { |
822 pdump_add_entry (pdump_get_entry_list (sdesc), data, | 635 pdump_add_entry (pdump_get_entry_list (sdesc->description), data, |
823 pdump_structure_size (data, sdesc), count); | 636 lispdesc_structure_size (data, sdesc), count); |
824 | 637 |
825 pdump_register_struct_contents (data, sdesc, count); | 638 pdump_register_struct_contents (data, sdesc, count); |
826 } | 639 } |
827 } | 640 } |
828 | 641 |
829 /* Store the already-calculated new pointer offsets for all pointers | 642 /* Store the already-calculated new pointer offsets for all pointers in the |
830 in the COUNT contiguous blocks of memory, each described by DESC | 643 COUNT contiguous blocks of memory, each described by DESC and of size |
831 and of size SIZE, whose original is located at ORIG_DATA and the | 644 SIZE, whose original is located at ORIG_DATA and the modifiable copy at |
832 modifiable copy at DATA. | 645 DATA. We examine the description to figure out where the pointers are, |
833 | 646 and then look up the replacement values using pdump_get_entry(). |
834 This is done just before writing the modified block of memory to | 647 |
835 the dump file. The new pointer offsets have been carefully | 648 This is done just before writing the modified block of memory to the |
836 calculated so that the data being pointed gets written at that | 649 dump file. The new pointer offsets have been carefully calculated so |
837 offset in the dump file. That way, the dump file is a correct | 650 that the data being pointed gets written at that offset in the dump |
838 memory image except perhaps for a constant that needs to be added | 651 file. That way, the dump file is a correct memory image except perhaps |
839 to all pointers. (#### In fact, we SHOULD be starting up a dumped | 652 for a constant that needs to be added to all pointers. (#### In fact, we |
840 XEmacs, seeing where the dumped file gets loaded into memory, and | 653 SHOULD be starting up a dumped XEmacs, seeing where the dumped file gets |
841 then rewriting the dumped file after relocating all the pointers | 654 loaded into memory, and then rewriting the dumped file after relocating |
842 relative to this memory location. That way, if the file gets | 655 all the pointers relative to this memory location. That way, if the |
843 loaded again at the same location, which will be common, we don't | 656 file gets loaded again at the same location, which will be common, we |
844 have to do any relocating, which is both faster at startup and | 657 don't have to do any relocating, which is both faster at startup and |
845 allows the read-only part of the dumped data to be shared read-only | 658 allows the read-only part of the dumped data to be shared read-only |
846 between different invocations of XEmacs.) | 659 between different invocations of XEmacs.) |
847 | 660 |
848 #### Do we distinguish between read-only and writable dumped data? | 661 #### Do we distinguish between read-only and writable dumped data? |
849 Should we? It's tricky because the dumped data, once loaded again, | 662 Should we? It's tricky because the dumped data, once loaded again, |
850 cannot really be free()d or garbage collected since it's all stored | 663 cannot really be free()d or garbage collected since it's all stored in |
851 in one contiguous block of data with no malloc() headers, and we | 664 one contiguous block of data with no malloc() headers, and we don't keep |
852 don't keep track of the pointers used internally in malloc() and | 665 track of the pointers used internally in malloc() and the Lisp allocator |
853 the Lisp allocator to track allocated blocks of memory. */ | 666 to track allocated blocks of memory. */ |
854 | 667 |
855 static void | 668 static void |
856 pdump_store_new_pointer_offsets (int count, void *data, const void *orig_data, | 669 pdump_store_new_pointer_offsets (int count, void *data, const void *orig_data, |
857 const struct lrecord_description *desc, | 670 const struct memory_description *desc, |
858 int size) | 671 int size) |
859 { | 672 { |
860 int pos, i; | 673 int pos, i; |
861 /* Process each block one by one */ | 674 /* Process each block one by one */ |
862 for (i = 0; i < count; i++) | 675 for (i = 0; i < count; i++) |
863 { | 676 { |
864 /* CUR points to the beginning of each block in the new data. */ | 677 /* CUR points to the beginning of each block in the new data. */ |
865 char *cur = ((char *)data) + i*size; | 678 char *cur = ((char *)data) + i*size; |
866 restart: | |
867 /* Scan each line of the description for relocatable pointers */ | 679 /* Scan each line of the description for relocatable pointers */ |
868 for (pos = 0; desc[pos].type != XD_END; pos++) | 680 for (pos = 0; desc[pos].type != XD_END; pos++) |
869 { | 681 { |
870 /* RDATA points to the beginning of each element in the new data. */ | 682 /* RDATA points to the beginning of each element in the new data. */ |
871 void *rdata = cur + desc[pos].offset; | 683 const struct memory_description *desc1 = &desc[pos]; |
872 switch (desc[pos].type) | 684 /* #### Change ORIG_DATA to DATA. See below. */ |
685 void *rdata = cur + lispdesc_indirect_count (desc1->offset, desc, | |
686 orig_data); | |
687 union_switcheroo: | |
688 | |
689 /* If the flag says don't dump, then don't dump. */ | |
690 if ((desc1->flags) & XD_FLAG_NO_PDUMP) | |
691 continue; | |
692 | |
693 switch (desc1->type) | |
873 { | 694 { |
874 case XD_SPECIFIER_END: | |
875 desc = ((const Lisp_Specifier *)(orig_data))-> | |
876 methods->extra_description; | |
877 goto restart; | |
878 case XD_CODING_SYSTEM_END: | |
879 desc = ((const Lisp_Coding_System *)(orig_data))-> | |
880 methods->extra_description; | |
881 goto restart; | |
882 case XD_BYTECOUNT: | 695 case XD_BYTECOUNT: |
883 case XD_ELEMCOUNT: | 696 case XD_ELEMCOUNT: |
884 case XD_HASHCODE: | 697 case XD_HASHCODE: |
885 case XD_INT: | 698 case XD_INT: |
886 case XD_LONG: | 699 case XD_LONG: |
887 break; | 700 break; |
888 case XD_INT_RESET: | 701 case XD_INT_RESET: |
889 { | 702 { |
890 EMACS_INT val = desc[pos].data1; | 703 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, |
891 if (XD_IS_INDIRECT (val)) | 704 orig_data); |
892 val = pdump_get_indirect_count (val, desc, orig_data); | |
893 * (int *) rdata = val; | 705 * (int *) rdata = val; |
894 break; | 706 break; |
895 } | 707 } |
896 case XD_OPAQUE_DATA_PTR: | 708 case XD_OPAQUE_DATA_PTR: |
897 case XD_C_STRING: | 709 case XD_C_STRING: |
912 traverse down the chain of objects until we find a | 724 traverse down the chain of objects until we find a |
913 referenced one. (The Qnil or Qunbound that ends the | 725 referenced one. (The Qnil or Qunbound that ends the |
914 chain will always be a referenced object.) */ | 726 chain will always be a referenced object.) */ |
915 Lisp_Object obj = * (Lisp_Object *) rdata; | 727 Lisp_Object obj = * (Lisp_Object *) rdata; |
916 pdump_entry_list_elt *elt1; | 728 pdump_entry_list_elt *elt1; |
729 /* #### Figure out how to handle indirect offsets here. | |
730 #### In general, when computing indirect counts, do we | |
731 really need to use the orig_data pointer? Why not just | |
732 use the new stuff? | |
733 | |
734 No, we don't usually need orig_data. We only need it | |
735 when fetching pointers out of the data, not integers. | |
736 This currently occurs only with description maps. We | |
737 should change the other places to DATA to emphasize | |
738 this. */ | |
739 assert (!XD_IS_INDIRECT (desc1->offset)); | |
917 for (;;) | 740 for (;;) |
918 { | 741 { |
919 elt1 = pdump_get_entry (XRECORD_LHEADER (obj)); | 742 elt1 = pdump_get_entry (XRECORD_LHEADER (obj)); |
920 if (elt1) | 743 if (elt1) |
921 break; | 744 break; |
922 obj = * (Lisp_Object *) (desc[pos].offset + | 745 obj = * (Lisp_Object *) (desc1->offset + |
923 (char *)(XRECORD_LHEADER (obj))); | 746 (char *)(XRECORD_LHEADER (obj))); |
924 } | 747 } |
925 * (EMACS_INT *) rdata = elt1->save_offset; | 748 * (EMACS_INT *) rdata = elt1->save_offset; |
926 break; | 749 break; |
927 } | 750 } |
928 case XD_LISP_OBJECT: | 751 case XD_LISP_OBJECT: |
929 { | 752 { |
930 Lisp_Object *pobj = (Lisp_Object *) rdata; | 753 Lisp_Object *pobj = (Lisp_Object *) rdata; |
931 | 754 |
932 assert (desc[pos].data1 == 0); | 755 assert (desc1->data1 == 0); |
933 | 756 |
934 if (POINTER_TYPE_P (XTYPE (*pobj)) && XRECORD_LHEADER (*pobj)) | 757 if (POINTER_TYPE_P (XTYPE (*pobj)) && XRECORD_LHEADER (*pobj)) |
935 * (EMACS_INT *) pobj = | 758 * (EMACS_INT *) pobj = |
936 pdump_get_entry (XRECORD_LHEADER (*pobj))->save_offset; | 759 pdump_get_entry (XRECORD_LHEADER (*pobj))->save_offset; |
937 break; | 760 break; |
938 } | 761 } |
939 case XD_LISP_OBJECT_ARRAY: | 762 case XD_LISP_OBJECT_ARRAY: |
940 { | 763 { |
941 EMACS_INT num = desc[pos].data1; | 764 EMACS_INT num = lispdesc_indirect_count (desc1->data1, desc, |
765 orig_data); | |
942 int j; | 766 int j; |
943 if (XD_IS_INDIRECT (num)) | |
944 num = pdump_get_indirect_count (num, desc, orig_data); | |
945 | 767 |
946 for (j = 0; j < num; j++) | 768 for (j = 0; j < num; j++) |
947 { | 769 { |
948 Lisp_Object *pobj = ((Lisp_Object *) rdata) + j; | 770 Lisp_Object *pobj = ((Lisp_Object *) rdata) + j; |
949 if (POINTER_TYPE_P (XTYPE (*pobj)) && | 771 if (POINTER_TYPE_P (XTYPE (*pobj)) && |
961 pdump_get_entry ((void *)str)->save_offset; | 783 pdump_get_entry ((void *)str)->save_offset; |
962 break; | 784 break; |
963 } | 785 } |
964 case XD_STRUCT_ARRAY: | 786 case XD_STRUCT_ARRAY: |
965 { | 787 { |
966 EMACS_INT num = desc[pos].data1; | 788 EMACS_INT num = lispdesc_indirect_count (desc1->data1, desc, |
967 if (XD_IS_INDIRECT (num)) | 789 orig_data); |
968 num = pdump_get_indirect_count (num, desc, orig_data); | 790 const struct sized_memory_description *sdesc = |
791 lispdesc_indirect_description (orig_data, desc1->data2); | |
969 | 792 |
970 pdump_store_new_pointer_offsets | 793 pdump_store_new_pointer_offsets |
971 (num, rdata, | 794 (num, rdata, |
972 ((char *) rdata - (char *) data) + (char *) orig_data, | 795 ((char *) rdata - (char *) data) + (char *) orig_data, |
973 desc[pos].data2->description, | 796 sdesc->description, |
974 pdump_structure_size | 797 lispdesc_structure_size |
975 (((char *) rdata - (char *) data) + (char *) orig_data, | 798 (((char *) rdata - (char *) data) + (char *) orig_data, |
976 desc[pos].data2)); | 799 sdesc)); |
977 break; | 800 break; |
978 } | 801 } |
979 case XD_UNION: | 802 case XD_UNION: |
980 abort (); /* #### IMPLEMENT ME! NEEDED FOR UNICODE | 803 case XD_UNION_DYNAMIC_SIZE: |
981 SUPPORT */ | 804 desc1 = lispdesc_process_xd_union (desc1, desc, orig_data); |
805 if (desc1) | |
806 goto union_switcheroo; | |
807 break; | |
982 | 808 |
983 default: | 809 default: |
984 stderr_out ("Unsupported dump type : %d\n", desc[pos].type); | 810 stderr_out ("Unsupported dump type : %d\n", desc1->type); |
985 abort (); | 811 abort (); |
986 } | 812 } |
987 } | 813 } |
988 } | 814 } |
989 } | 815 } |
995 integer/character) are relocated to the (pre-computed) offset in | 821 integer/character) are relocated to the (pre-computed) offset in |
996 the dump file. */ | 822 the dump file. */ |
997 | 823 |
998 static void | 824 static void |
999 pdump_dump_data (pdump_entry_list_elt *elt, | 825 pdump_dump_data (pdump_entry_list_elt *elt, |
1000 const struct lrecord_description *desc) | 826 const struct memory_description *desc) |
1001 { | 827 { |
1002 Bytecount size = elt->size; | 828 Bytecount size = elt->size; |
1003 int count = elt->count; | 829 int count = elt->count; |
1004 if (desc) | 830 if (desc) |
1005 { | 831 { |
1011 } | 837 } |
1012 retry_fwrite (desc ? pdump_buf : elt->obj, size, count, pdump_out); | 838 retry_fwrite (desc ? pdump_buf : elt->obj, size, count, pdump_out); |
1013 } | 839 } |
1014 | 840 |
1015 /* Relocate a single memory block at DATA, described by DESC, from its | 841 /* Relocate a single memory block at DATA, described by DESC, from its |
1016 assumed load location to its actual one by adding DELTA to all | 842 assumed load location to its actual one by adding DELTA to all pointers |
1017 pointers in the block. Does not recursively relocate any other | 843 in the block. Does not recursively relocate any other memory blocks |
1018 memory blocks pointed to. (We already have a list of all memory | 844 pointed to. (We already have a list of all memory blocks in the dump |
1019 blocks in the dump file.) */ | 845 file.) This is used once the dump data has been loaded back in, both |
846 for blocks sitting in the dumped data and in global data objects whose | |
847 contents have been restored from the dumped data. */ | |
1020 | 848 |
1021 static void | 849 static void |
1022 pdump_reloc_one (void *data, EMACS_INT delta, | 850 pdump_reloc_one (void *data, EMACS_INT delta, |
1023 const struct lrecord_description *desc) | 851 const struct memory_description *desc) |
1024 { | 852 { |
1025 int pos; | 853 int pos; |
1026 | 854 |
1027 restart: | |
1028 for (pos = 0; desc[pos].type != XD_END; pos++) | 855 for (pos = 0; desc[pos].type != XD_END; pos++) |
1029 { | 856 { |
1030 void *rdata = (char *)data + desc[pos].offset; | 857 const struct memory_description *desc1 = &desc[pos]; |
1031 switch (desc[pos].type) | 858 void *rdata = (char *) data + lispdesc_indirect_count (desc1->offset, |
859 desc, data); | |
860 | |
861 union_switcheroo: | |
862 | |
863 /* If the flag says don't dump, then don't dump. */ | |
864 if ((desc1->flags) & XD_FLAG_NO_PDUMP) | |
865 continue; | |
866 | |
867 switch (desc1->type) | |
1032 { | 868 { |
1033 case XD_SPECIFIER_END: | |
1034 pos = 0; | |
1035 desc = ((const Lisp_Specifier *)data)->methods->extra_description; | |
1036 goto restart; | |
1037 case XD_CODING_SYSTEM_END: | |
1038 pos = 0; | |
1039 desc = | |
1040 ((const Lisp_Coding_System *)data)->methods->extra_description; | |
1041 goto restart; | |
1042 case XD_BYTECOUNT: | 869 case XD_BYTECOUNT: |
1043 case XD_ELEMCOUNT: | 870 case XD_ELEMCOUNT: |
1044 case XD_HASHCODE: | 871 case XD_HASHCODE: |
1045 case XD_INT: | 872 case XD_INT: |
1046 case XD_LONG: | 873 case XD_LONG: |
1058 } | 885 } |
1059 case XD_LISP_OBJECT: | 886 case XD_LISP_OBJECT: |
1060 { | 887 { |
1061 Lisp_Object *pobj = (Lisp_Object *) rdata; | 888 Lisp_Object *pobj = (Lisp_Object *) rdata; |
1062 | 889 |
1063 assert (desc[pos].data1 == 0); | 890 assert (desc1->data1 == 0); |
1064 | 891 |
1065 if (POINTER_TYPE_P (XTYPE (*pobj)) | 892 if (POINTER_TYPE_P (XTYPE (*pobj)) |
1066 && ! EQ (*pobj, Qnull_pointer)) | 893 && ! EQ (*pobj, Qnull_pointer)) |
1067 *pobj = wrap_pointer_1 ((char *) XPNTR (*pobj) + delta); | 894 *pobj = wrap_pointer_1 ((char *) XPNTR (*pobj) + delta); |
1068 | 895 |
1069 break; | 896 break; |
1070 } | 897 } |
1071 case XD_LISP_OBJECT_ARRAY: | 898 case XD_LISP_OBJECT_ARRAY: |
1072 { | 899 { |
1073 EMACS_INT num = desc[pos].data1; | 900 EMACS_INT num = lispdesc_indirect_count (desc1->data1, desc, |
901 data); | |
1074 int j; | 902 int j; |
1075 if (XD_IS_INDIRECT (num)) | |
1076 num = pdump_get_indirect_count (num, desc, data); | |
1077 | 903 |
1078 for (j=0; j<num; j++) | 904 for (j=0; j<num; j++) |
1079 { | 905 { |
1080 Lisp_Object *pobj = (Lisp_Object *) rdata + j; | 906 Lisp_Object *pobj = (Lisp_Object *) rdata + j; |
1081 | 907 |
1092 *(EMACS_INT *)rdata = str + delta; | 918 *(EMACS_INT *)rdata = str + delta; |
1093 break; | 919 break; |
1094 } | 920 } |
1095 case XD_STRUCT_ARRAY: | 921 case XD_STRUCT_ARRAY: |
1096 { | 922 { |
1097 EMACS_INT num = desc[pos].data1; | 923 EMACS_INT num = lispdesc_indirect_count (desc1->data1, desc, |
924 data); | |
1098 int j; | 925 int j; |
1099 const struct struct_description *sdesc = desc[pos].data2; | 926 const struct sized_memory_description *sdesc = |
1100 Bytecount size = pdump_structure_size (rdata, sdesc); | 927 lispdesc_indirect_description (data, desc1->data2); |
1101 | 928 Bytecount size = lispdesc_structure_size (rdata, sdesc); |
1102 if (XD_IS_INDIRECT (num)) | 929 |
1103 num = pdump_get_indirect_count (num, desc, data); | |
1104 /* Note: We are recursing over data in the block itself */ | 930 /* Note: We are recursing over data in the block itself */ |
1105 for (j = 0; j < num; j++) | 931 for (j = 0; j < num; j++) |
1106 pdump_reloc_one ((char *) rdata + j * size, delta, | 932 pdump_reloc_one ((char *) rdata + j * size, delta, |
1107 sdesc->description); | 933 sdesc->description); |
1108 | 934 |
1109 break; | 935 break; |
1110 } | 936 } |
1111 | |
1112 case XD_UNION: | 937 case XD_UNION: |
1113 abort (); /* #### IMPLEMENT ME! NEEDED FOR UNICODE SUPPORT */ | 938 case XD_UNION_DYNAMIC_SIZE: |
939 desc1 = lispdesc_process_xd_union (desc1, desc, data); | |
940 if (desc1) | |
941 goto union_switcheroo; | |
942 break; | |
943 | |
1114 default: | 944 default: |
1115 stderr_out ("Unsupported dump type : %d\n", desc[pos].type); | 945 stderr_out ("Unsupported dump type : %d\n", desc1->type); |
1116 abort (); | 946 abort (); |
1117 }; | 947 } |
1118 } | 948 } |
1119 } | 949 } |
1120 | 950 |
1121 static void | 951 static void |
1122 pdump_allocate_offset (pdump_entry_list_elt *elt, | 952 pdump_allocate_offset (pdump_entry_list_elt *elt, |
1123 const struct lrecord_description *desc) | 953 const struct memory_description *desc) |
1124 { | 954 { |
1125 Bytecount size = elt->count * elt->size; | 955 Bytecount size = elt->count * elt->size; |
1126 elt->save_offset = cur_offset; | 956 elt->save_offset = cur_offset; |
1127 if (size>max_size) | 957 if (size>max_size) |
1128 max_size = size; | 958 max_size = size; |
1129 cur_offset += size; | 959 cur_offset += size; |
1130 } | 960 } |
1131 | 961 |
1132 static void | 962 static void |
1133 pdump_scan_by_alignment (void (*f)(pdump_entry_list_elt *, | 963 pdump_scan_by_alignment (void (*f)(pdump_entry_list_elt *, |
1134 const struct lrecord_description *)) | 964 const struct memory_description *)) |
1135 { | 965 { |
1136 int align; | 966 int align; |
1137 | 967 |
1138 for (align = ALIGNOF (max_align_t); align; align>>=1) | 968 for (align = ALIGNOF (max_align_t); align; align>>=1) |
1139 { | 969 { |
1148 for (i=0; i<pdump_struct_table.count; i++) | 978 for (i=0; i<pdump_struct_table.count; i++) |
1149 { | 979 { |
1150 pdump_struct_list_elt list = pdump_struct_table.list[i]; | 980 pdump_struct_list_elt list = pdump_struct_table.list[i]; |
1151 if (list.list.align == align) | 981 if (list.list.align == align) |
1152 for (elt = list.list.first; elt; elt = elt->next) | 982 for (elt = list.list.first; elt; elt = elt->next) |
1153 f (elt, list.sdesc->description); | 983 f (elt, list.desc); |
1154 } | 984 } |
1155 | 985 |
1156 for (elt = pdump_opaque_data_list.first; elt; elt = elt->next) | 986 for (elt = pdump_opaque_data_list.first; elt; elt = elt->next) |
1157 if (pdump_size_to_align (elt->size) == align) | 987 if (pdump_size_to_align (elt->size) == align) |
1158 f (elt, 0); | 988 f (elt, 0); |
1173 PDUMP_ALIGN_OUTPUT (pdump_static_pointer); | 1003 PDUMP_ALIGN_OUTPUT (pdump_static_pointer); |
1174 retry_fwrite (data, sizeof (pdump_static_pointer), count, pdump_out); | 1004 retry_fwrite (data, sizeof (pdump_static_pointer), count, pdump_out); |
1175 } | 1005 } |
1176 | 1006 |
1177 static void | 1007 static void |
1178 pdump_dump_opaques (void) | 1008 pdump_dump_root_blocks (void) |
1179 { | 1009 { |
1180 int i; | 1010 int i; |
1181 for (i = 0; i < Dynarr_length (pdump_opaques); i++) | 1011 for (i = 0; i < Dynarr_length (pdump_root_blocks); i++) |
1182 { | 1012 { |
1183 pdump_opaque *info = Dynarr_atp (pdump_opaques, i); | 1013 pdump_root_block *info = Dynarr_atp (pdump_root_blocks, i); |
1184 PDUMP_WRITE_ALIGNED (pdump_opaque, *info); | 1014 PDUMP_WRITE_ALIGNED (pdump_root_block, *info); |
1185 retry_fwrite (info->varaddress, info->size, 1, pdump_out); | 1015 retry_fwrite (info->varaddress, info->size, 1, pdump_out); |
1186 } | 1016 } |
1187 } | 1017 } |
1188 | 1018 |
1189 static void | 1019 static void |
1214 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); | 1044 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); |
1215 | 1045 |
1216 for (i=0; i<pdump_struct_table.count; i++) | 1046 for (i=0; i<pdump_struct_table.count; i++) |
1217 { | 1047 { |
1218 elt = pdump_struct_table.list[i].list.first; | 1048 elt = pdump_struct_table.list[i].list.first; |
1219 rt.desc = pdump_struct_table.list[i].sdesc->description; | 1049 rt.desc = pdump_struct_table.list[i].desc; |
1220 rt.count = pdump_struct_table.list[i].list.count; | 1050 rt.count = pdump_struct_table.list[i].list.count; |
1221 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); | 1051 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); |
1222 while (elt) | 1052 while (elt) |
1223 { | 1053 { |
1224 EMACS_INT rdata = pdump_get_entry (elt->obj)->save_offset; | 1054 EMACS_INT rdata = pdump_get_entry (elt->obj)->save_offset; |
1235 rt.count = 0; | 1065 rt.count = 0; |
1236 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); | 1066 PDUMP_WRITE_ALIGNED (pdump_reloc_table, rt); |
1237 } | 1067 } |
1238 | 1068 |
1239 static void | 1069 static void |
1240 pdump_dump_root_objects (void) | 1070 pdump_dump_root_lisp_objects (void) |
1241 { | 1071 { |
1242 Elemcount count = (Dynarr_length (pdump_root_objects) + | 1072 Elemcount count = (Dynarr_length (pdump_root_lisp_objects) + |
1243 Dynarr_length (pdump_weak_object_chains)); | 1073 Dynarr_length (pdump_weak_object_chains)); |
1244 Elemcount i; | 1074 Elemcount i; |
1245 | 1075 |
1246 PDUMP_WRITE_ALIGNED (Elemcount, count); | 1076 PDUMP_WRITE_ALIGNED (Elemcount, count); |
1247 PDUMP_ALIGN_OUTPUT (pdump_static_Lisp_Object); | 1077 PDUMP_ALIGN_OUTPUT (pdump_static_Lisp_Object); |
1248 | 1078 |
1249 for (i = 0; i < Dynarr_length (pdump_root_objects); i++) | 1079 for (i = 0; i < Dynarr_length (pdump_root_lisp_objects); i++) |
1250 { | 1080 { |
1251 pdump_static_Lisp_Object obj; | 1081 pdump_static_Lisp_Object obj; |
1252 obj.address = Dynarr_at (pdump_root_objects, i); | 1082 obj.address = Dynarr_at (pdump_root_lisp_objects, i); |
1253 obj.value = * obj.address; | 1083 obj.value = * obj.address; |
1254 | 1084 |
1255 if (POINTER_TYPE_P (XTYPE (obj.value))) | 1085 if (POINTER_TYPE_P (XTYPE (obj.value))) |
1256 obj.value = | 1086 obj.value = |
1257 wrap_pointer_1 ((void *) pdump_get_entry (XRECORD_LHEADER | 1087 wrap_pointer_1 ((void *) pdump_get_entry (XRECORD_LHEADER |
1268 obj.address = Dynarr_at (pdump_weak_object_chains, i); | 1098 obj.address = Dynarr_at (pdump_weak_object_chains, i); |
1269 obj.value = * obj.address; | 1099 obj.value = * obj.address; |
1270 | 1100 |
1271 for (;;) | 1101 for (;;) |
1272 { | 1102 { |
1273 const struct lrecord_description *desc; | 1103 const struct memory_description *desc; |
1274 int pos; | 1104 int pos; |
1275 elt = pdump_get_entry (XRECORD_LHEADER (obj.value)); | 1105 elt = pdump_get_entry (XRECORD_LHEADER (obj.value)); |
1276 if (elt) | 1106 if (elt) |
1277 break; | 1107 break; |
1278 desc = XRECORD_LHEADER_IMPLEMENTATION (obj.value)->description; | 1108 desc = XRECORD_LHEADER_IMPLEMENTATION (obj.value)->description; |
1279 for (pos = 0; desc[pos].type != XD_LO_LINK; pos++) | 1109 for (pos = 0; desc[pos].type != XD_LO_LINK; pos++) |
1280 assert (desc[pos].type != XD_END); | 1110 assert (desc[pos].type != XD_END); |
1281 | 1111 |
1282 obj.value = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj.value))); | 1112 /* #### Figure out how to handle indirect offsets here. */ |
1113 assert (!XD_IS_INDIRECT (desc[pos].offset)); | |
1114 obj.value = | |
1115 * (Lisp_Object *) (desc[pos].offset + | |
1116 (char *) (XRECORD_LHEADER (obj.value))); | |
1283 } | 1117 } |
1284 obj.value = wrap_pointer_1 ((void *) elt->save_offset); | 1118 obj.value = wrap_pointer_1 ((void *) elt->save_offset); |
1285 | 1119 |
1286 PDUMP_WRITE (pdump_static_Lisp_Object, obj); | 1120 PDUMP_WRITE (pdump_static_Lisp_Object, obj); |
1287 } | 1121 } |
1293 int i; | 1127 int i; |
1294 Lisp_Object t_console, t_device, t_frame; | 1128 Lisp_Object t_console, t_device, t_frame; |
1295 int none; | 1129 int none; |
1296 pdump_header header; | 1130 pdump_header header; |
1297 | 1131 |
1132 in_pdump = 1; | |
1133 | |
1298 pdump_object_table = xnew_array (pdump_entry_list, lrecord_type_count); | 1134 pdump_object_table = xnew_array (pdump_entry_list, lrecord_type_count); |
1299 pdump_alert_undump_object = xnew_array (int, lrecord_type_count); | 1135 pdump_alert_undump_object = xnew_array (int, lrecord_type_count); |
1300 | 1136 |
1301 assert (ALIGNOF (max_align_t) <= pdump_align_table[0]); | 1137 assert (ALIGNOF (max_align_t) <= pdump_align_table[0]); |
1302 | 1138 |
1310 t_console = Vterminal_console; Vterminal_console = Qnil; | 1146 t_console = Vterminal_console; Vterminal_console = Qnil; |
1311 t_frame = Vterminal_frame; Vterminal_frame = Qnil; | 1147 t_frame = Vterminal_frame; Vterminal_frame = Qnil; |
1312 t_device = Vterminal_device; Vterminal_device = Qnil; | 1148 t_device = Vterminal_device; Vterminal_device = Qnil; |
1313 | 1149 |
1314 dump_add_opaque (&lrecord_implementations_table, | 1150 dump_add_opaque (&lrecord_implementations_table, |
1315 lrecord_type_count * sizeof (lrecord_implementations_table[0])); | 1151 lrecord_type_count * |
1152 sizeof (lrecord_implementations_table[0])); | |
1316 dump_add_opaque (&lrecord_markers, | 1153 dump_add_opaque (&lrecord_markers, |
1317 lrecord_type_count * sizeof (lrecord_markers[0])); | 1154 lrecord_type_count * sizeof (lrecord_markers[0])); |
1318 | 1155 |
1319 pdump_hash = xnew_array_and_zero (pdump_entry_list_elt *, PDUMP_HASHSIZE); | 1156 pdump_hash = xnew_array_and_zero (pdump_entry_list_elt *, PDUMP_HASHSIZE); |
1320 | 1157 |
1329 pdump_struct_table.size = -1; | 1166 pdump_struct_table.size = -1; |
1330 | 1167 |
1331 pdump_opaque_data_list.first = 0; | 1168 pdump_opaque_data_list.first = 0; |
1332 pdump_opaque_data_list.align = ALIGNOF (max_align_t); | 1169 pdump_opaque_data_list.align = ALIGNOF (max_align_t); |
1333 pdump_opaque_data_list.count = 0; | 1170 pdump_opaque_data_list.count = 0; |
1334 depth = 0; | 1171 pdump_depth = 0; |
1335 | 1172 |
1336 for (i=0; i<Dynarr_length (pdump_root_objects); i++) | 1173 for (i = 0; i < Dynarr_length (pdump_root_lisp_objects); i++) |
1337 pdump_register_object (* Dynarr_at (pdump_root_objects, i)); | 1174 pdump_register_object (* Dynarr_at (pdump_root_lisp_objects, i)); |
1338 | 1175 |
1339 none = 1; | 1176 none = 1; |
1340 for (i=0; i<lrecord_type_count; i++) | 1177 for (i=0; i<lrecord_type_count; i++) |
1341 if (pdump_alert_undump_object[i]) | 1178 if (pdump_alert_undump_object[i]) |
1342 { | 1179 { |
1343 if (none) | 1180 if (none) |
1344 printf ("Undumpable types list :\n"); | 1181 printf ("Undumpable types list :\n"); |
1345 none = 0; | 1182 none = 0; |
1346 printf (" - %s (%d)\n", lrecord_implementations_table[i]->name, pdump_alert_undump_object[i]); | 1183 printf (" - %s (%d)\n", lrecord_implementations_table[i]->name, |
1184 pdump_alert_undump_object[i]); | |
1347 } | 1185 } |
1348 if (!none) | 1186 if (!none) |
1349 return; | 1187 { |
1188 in_pdump = 0; | |
1189 return; | |
1190 } | |
1350 | 1191 |
1351 for (i=0; i<Dynarr_length (pdump_root_struct_ptrs); i++) | 1192 for (i=0; i<Dynarr_length (pdump_root_struct_ptrs); i++) |
1352 { | 1193 { |
1353 pdump_root_struct_ptr info = Dynarr_at (pdump_root_struct_ptrs, i); | 1194 pdump_root_struct_ptr info = Dynarr_at (pdump_root_struct_ptrs, i); |
1354 pdump_register_struct (*(info.ptraddress), info.desc, 1); | 1195 pdump_register_struct (*(info.ptraddress), info.desc, 1); |
1356 | 1197 |
1357 memcpy (header.signature, PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN); | 1198 memcpy (header.signature, PDUMP_SIGNATURE, PDUMP_SIGNATURE_LEN); |
1358 header.id = dump_id; | 1199 header.id = dump_id; |
1359 header.reloc_address = 0; | 1200 header.reloc_address = 0; |
1360 header.nb_root_struct_ptrs = Dynarr_length (pdump_root_struct_ptrs); | 1201 header.nb_root_struct_ptrs = Dynarr_length (pdump_root_struct_ptrs); |
1361 header.nb_opaques = Dynarr_length (pdump_opaques); | 1202 header.nb_root_blocks = Dynarr_length (pdump_root_blocks); |
1362 | 1203 |
1363 cur_offset = MAX_ALIGN_SIZE (sizeof (header)); | 1204 cur_offset = MAX_ALIGN_SIZE (sizeof (header)); |
1364 max_size = 0; | 1205 max_size = 0; |
1365 | 1206 |
1366 pdump_scan_by_alignment (pdump_allocate_offset); | 1207 pdump_scan_by_alignment (pdump_allocate_offset); |
1384 pdump_scan_by_alignment (pdump_dump_data); | 1225 pdump_scan_by_alignment (pdump_dump_data); |
1385 | 1226 |
1386 fseek (pdump_out, header.stab_offset, SEEK_SET); | 1227 fseek (pdump_out, header.stab_offset, SEEK_SET); |
1387 | 1228 |
1388 pdump_dump_root_struct_ptrs (); | 1229 pdump_dump_root_struct_ptrs (); |
1389 pdump_dump_opaques (); | 1230 pdump_dump_root_blocks (); |
1390 pdump_dump_rtables (); | 1231 pdump_dump_rtables (); |
1391 pdump_dump_root_objects (); | 1232 pdump_dump_root_lisp_objects (); |
1392 | 1233 |
1393 retry_fclose (pdump_out); | 1234 retry_fclose (pdump_out); |
1394 retry_close (pdump_fd); | 1235 retry_close (pdump_fd); |
1395 | 1236 |
1396 free (pdump_buf); | 1237 free (pdump_buf); |
1398 free (pdump_hash); | 1239 free (pdump_hash); |
1399 | 1240 |
1400 Vterminal_console = t_console; | 1241 Vterminal_console = t_console; |
1401 Vterminal_frame = t_frame; | 1242 Vterminal_frame = t_frame; |
1402 Vterminal_device = t_device; | 1243 Vterminal_device = t_device; |
1244 in_pdump = 0; | |
1403 } | 1245 } |
1404 | 1246 |
1405 static int | 1247 static int |
1406 pdump_load_check (void) | 1248 pdump_load_check (void) |
1407 { | 1249 { |
1418 { | 1260 { |
1419 int i; | 1261 int i; |
1420 char *p; | 1262 char *p; |
1421 EMACS_INT delta; | 1263 EMACS_INT delta; |
1422 EMACS_INT count; | 1264 EMACS_INT count; |
1423 pdump_header *header = (pdump_header *)pdump_start; | 1265 pdump_header *header = (pdump_header *) pdump_start; |
1424 | 1266 |
1425 pdump_end = pdump_start + pdump_length; | 1267 pdump_end = pdump_start + pdump_length; |
1426 | 1268 |
1427 delta = ((EMACS_INT)pdump_start) - header->reloc_address; | 1269 delta = ((EMACS_INT) pdump_start) - header->reloc_address; |
1428 p = pdump_start + header->stab_offset; | 1270 p = pdump_start + header->stab_offset; |
1429 | 1271 |
1430 /* Put back the pdump_root_struct_ptrs */ | 1272 /* Put back the pdump_root_struct_ptrs */ |
1431 p = (char *) ALIGN_PTR (p, pdump_static_pointer); | 1273 p = (char *) ALIGN_PTR (p, pdump_static_pointer); |
1432 for (i=0; i<header->nb_root_struct_ptrs; i++) | 1274 for (i = 0; i < header->nb_root_struct_ptrs; i++) |
1433 { | 1275 { |
1434 pdump_static_pointer ptr = PDUMP_READ (p, pdump_static_pointer); | 1276 pdump_static_pointer ptr = PDUMP_READ (p, pdump_static_pointer); |
1435 (* ptr.address) = ptr.value + delta; | 1277 (* ptr.address) = ptr.value + delta; |
1436 } | 1278 } |
1437 | 1279 |
1438 /* Put back the pdump_opaques */ | 1280 /* Put back the pdump_root_blocks and relocate */ |
1439 for (i=0; i<header->nb_opaques; i++) | 1281 for (i = 0; i < header->nb_root_blocks; i++) |
1440 { | 1282 { |
1441 pdump_opaque info = PDUMP_READ_ALIGNED (p, pdump_opaque); | 1283 pdump_root_block info = PDUMP_READ_ALIGNED (p, pdump_root_block); |
1442 memcpy ((void*)info.varaddress, p, info.size); | 1284 memcpy ((void *) info.varaddress, p, info.size); |
1285 if (info.desc) | |
1286 pdump_reloc_one ((void *) info.varaddress, delta, info.desc); | |
1443 p += info.size; | 1287 p += info.size; |
1444 } | 1288 } |
1445 | 1289 |
1446 /* Do the relocations */ | 1290 /* Relocate the heap objects */ |
1447 pdump_rt_list = p; | 1291 pdump_rt_list = p; |
1448 count = 2; | 1292 count = 2; |
1449 for (;;) | 1293 for (;;) |
1450 { | 1294 { |
1451 pdump_reloc_table rt = PDUMP_READ_ALIGNED (p, pdump_reloc_table); | 1295 pdump_reloc_table rt = PDUMP_READ_ALIGNED (p, pdump_reloc_table); |
1452 p = (char *) ALIGN_PTR (p, char *); | 1296 p = (char *) ALIGN_PTR (p, char *); |
1453 if (rt.desc) | 1297 if (rt.desc) |
1454 { | 1298 { |
1455 char **reloc = (char **)p; | 1299 char **reloc = (char **) p; |
1456 for (i=0; i < rt.count; i++) | 1300 for (i = 0; i < rt.count; i++) |
1457 { | 1301 { |
1458 reloc[i] += delta; | 1302 reloc[i] += delta; |
1459 pdump_reloc_one (reloc[i], delta, rt.desc); | 1303 pdump_reloc_one (reloc[i], delta, rt.desc); |
1460 } | 1304 } |
1461 p += rt.count * sizeof (char *); | 1305 p += rt.count * sizeof (char *); |
1462 } else | 1306 } |
1463 if (!(--count)) | 1307 else if (!(--count)) |
1464 break; | 1308 break; |
1465 } | 1309 } |
1466 | 1310 |
1467 /* Put the pdump_root_objects variables in place */ | 1311 /* Put the pdump_root_lisp_objects variables in place */ |
1468 i = PDUMP_READ_ALIGNED (p, Elemcount); | 1312 i = PDUMP_READ_ALIGNED (p, Elemcount); |
1469 p = (char *) ALIGN_PTR (p, pdump_static_Lisp_Object); | 1313 p = (char *) ALIGN_PTR (p, pdump_static_Lisp_Object); |
1470 while (i--) | 1314 while (i--) |
1471 { | 1315 { |
1472 pdump_static_Lisp_Object obj = PDUMP_READ (p, pdump_static_Lisp_Object); | 1316 pdump_static_Lisp_Object obj = PDUMP_READ (p, pdump_static_Lisp_Object); |
1486 p = (char *) ALIGN_PTR (p, Lisp_Object); | 1330 p = (char *) ALIGN_PTR (p, Lisp_Object); |
1487 if (!rt.desc) | 1331 if (!rt.desc) |
1488 break; | 1332 break; |
1489 if (rt.desc == hash_table_description) | 1333 if (rt.desc == hash_table_description) |
1490 { | 1334 { |
1491 for (i=0; i < rt.count; i++) | 1335 for (i = 0; i < rt.count; i++) |
1492 pdump_reorganize_hash_table (PDUMP_READ (p, Lisp_Object)); | 1336 pdump_reorganize_hash_table (PDUMP_READ (p, Lisp_Object)); |
1493 break; | 1337 break; |
1494 } else | 1338 } |
1495 p += sizeof (Lisp_Object) * rt.count; | 1339 else |
1340 p += sizeof (Lisp_Object) * rt.count; | |
1496 } | 1341 } |
1497 | 1342 |
1498 return 1; | 1343 return 1; |
1499 } | 1344 } |
1500 | 1345 |
1530 0, /* Max size, low half */ | 1375 0, /* Max size, low half */ |
1531 NULL); /* Unnamed */ | 1376 NULL); /* Unnamed */ |
1532 if (pdump_hMap == INVALID_HANDLE_VALUE) | 1377 if (pdump_hMap == INVALID_HANDLE_VALUE) |
1533 return 0; | 1378 return 0; |
1534 | 1379 |
1535 pdump_start = MapViewOfFile (pdump_hMap, | 1380 pdump_start = (char *) MapViewOfFile (pdump_hMap, |
1536 FILE_MAP_COPY, /* Copy on write */ | 1381 FILE_MAP_COPY, /* Copy on write */ |
1537 0, /* Start at zero */ | 1382 0, /* Start at zero */ |
1538 0, | 1383 0, |
1539 0); /* Map all of it */ | 1384 0); /* Map all of it */ |
1540 pdump_free = pdump_file_unmap; | 1385 pdump_free = pdump_file_unmap; |
1541 return 1; | 1386 return 1; |
1542 } | 1387 } |
1543 | 1388 |
1544 /* pdump_resource_free is called (via the pdump_free pointer) to release | 1389 /* pdump_resource_free is called (via the pdump_free pointer) to release |
1569 hRes = FindResourceA (NULL, MAKEINTRESOURCE (101), "DUMP"); | 1414 hRes = FindResourceA (NULL, MAKEINTRESOURCE (101), "DUMP"); |
1570 if (hRes == NULL) | 1415 if (hRes == NULL) |
1571 return 0; | 1416 return 0; |
1572 | 1417 |
1573 /* Found it, use the data in the resource */ | 1418 /* Found it, use the data in the resource */ |
1574 hResLoad = LoadResource (NULL, hRes); | 1419 hResLoad = (HRSRC) LoadResource (NULL, hRes); |
1575 if (hResLoad == NULL) | 1420 if (hResLoad == NULL) |
1576 return 0; | 1421 return 0; |
1577 | 1422 |
1578 pdump_start = LockResource (hResLoad); | 1423 pdump_start = (char *) LockResource (hResLoad); |
1579 if (pdump_start == NULL) | 1424 if (pdump_start == NULL) |
1580 return 0; | 1425 return 0; |
1581 | 1426 |
1582 pdump_free = pdump_resource_free; | 1427 pdump_free = pdump_resource_free; |
1583 pdump_length = SizeofResource (NULL, hRes); | 1428 pdump_length = SizeofResource (NULL, hRes); |
1694 GetModuleFileNameA (NULL, exe_path, PATH_MAX); | 1539 GetModuleFileNameA (NULL, exe_path, PATH_MAX); |
1695 #else /* !WIN32_NATIVE */ | 1540 #else /* !WIN32_NATIVE */ |
1696 Extbyte *w; | 1541 Extbyte *w; |
1697 const Extbyte *dir, *p; | 1542 const Extbyte *dir, *p; |
1698 | 1543 |
1544 in_pdump = 1; | |
1699 dir = argv0; | 1545 dir = argv0; |
1700 if (dir[0] == '-') | 1546 if (dir[0] == '-') |
1701 { | 1547 { |
1702 /* XEmacs as a login shell, oh goody! */ | 1548 /* XEmacs as a login shell, oh goody! */ |
1703 dir = getenv ("SHELL"); /* not egetenv -- not yet initialized */ | 1549 dir = getenv ("SHELL"); /* not egetenv -- not yet initialized */ |
1751 #endif /* WIN32_NATIVE */ | 1597 #endif /* WIN32_NATIVE */ |
1752 | 1598 |
1753 if (pdump_file_try (exe_path)) | 1599 if (pdump_file_try (exe_path)) |
1754 { | 1600 { |
1755 pdump_load_finish (); | 1601 pdump_load_finish (); |
1602 in_pdump = 0; | |
1756 return 1; | 1603 return 1; |
1757 } | 1604 } |
1758 | 1605 |
1759 #ifdef WIN32_NATIVE | 1606 #ifdef WIN32_NATIVE |
1760 if (pdump_resource_get ()) | 1607 if (pdump_resource_get ()) |
1761 { | 1608 { |
1762 if (pdump_load_check ()) | 1609 if (pdump_load_check ()) |
1763 { | 1610 { |
1764 pdump_load_finish (); | 1611 pdump_load_finish (); |
1612 in_pdump = 0; | |
1765 return 1; | 1613 return 1; |
1766 } | 1614 } |
1767 pdump_free (); | 1615 pdump_free (); |
1768 } | 1616 } |
1769 #endif | 1617 #endif |
1770 | 1618 |
1619 in_pdump = 0; | |
1771 return 0; | 1620 return 0; |
1772 } | 1621 } |