comparison src/alloc.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 3136b3c99ceb
children f0af455e89d9
comparison
equal deleted inserted replaced
1203:5f2f8dcbfb3e 1204:e22b0213b713
48 #include "chartab.h" 48 #include "chartab.h"
49 #include "device.h" 49 #include "device.h"
50 #include "elhash.h" 50 #include "elhash.h"
51 #include "events.h" 51 #include "events.h"
52 #include "extents-impl.h" 52 #include "extents-impl.h"
53 #include "file-coding.h"
53 #include "frame-impl.h" 54 #include "frame-impl.h"
54 #include "glyphs.h" 55 #include "glyphs.h"
55 #include "opaque.h" 56 #include "opaque.h"
57 #include "lstream.h"
56 #include "process.h" 58 #include "process.h"
57 #include "redisplay.h" 59 #include "redisplay.h"
58 #include "specifier.h" 60 #include "specifier.h"
59 #include "sysfile.h" 61 #include "sysfile.h"
60 #include "sysdep.h" 62 #include "sysdep.h"
61 #include "window.h" 63 #include "window.h"
62 #include "console-stream.h" 64 #include "console-stream.h"
63 65
64 #ifdef USE_KKCC
65 #include "file-coding.h"
66 #endif /* USE_KKCC */
67
68 #ifdef DOUG_LEA_MALLOC 66 #ifdef DOUG_LEA_MALLOC
69 #include <malloc.h> 67 #include <malloc.h>
70 #endif
71
72 #ifdef PDUMP
73 #include "dumper.h"
74 #endif 68 #endif
75 69
76 EXFUN (Fgarbage_collect, 0); 70 EXFUN (Fgarbage_collect, 0);
77 71
78 static void recompute_need_to_garbage_collect (void); 72 static void recompute_need_to_garbage_collect (void);
197 Lisp_Object Qgarbage_collecting; 191 Lisp_Object Qgarbage_collecting;
198 192
199 /* Non-zero means we're in the process of doing the dump */ 193 /* Non-zero means we're in the process of doing the dump */
200 int purify_flag; 194 int purify_flag;
201 195
196 /* Non-zero means we're pdumping out or in */
197 #ifdef PDUMP
198 int in_pdump;
199 #endif
200
202 #ifdef ERROR_CHECK_TYPES 201 #ifdef ERROR_CHECK_TYPES
203 202
204 Error_Behavior ERROR_ME, ERROR_ME_NOT, ERROR_ME_WARN, ERROR_ME_DEBUG_WARN; 203 Error_Behavior ERROR_ME, ERROR_ME_NOT, ERROR_ME_WARN, ERROR_ME_DEBUG_WARN;
205 204
206 #endif 205 #endif
366 UINT_32_BIT *ptr4 = (UINT_32_BIT *) ptr; 365 UINT_32_BIT *ptr4 = (UINT_32_BIT *) ptr;
367 Bytecount beefs = size >> 2; 366 Bytecount beefs = size >> 2;
368 367
369 /* In practice, size will always be a multiple of four. */ 368 /* In practice, size will always be a multiple of four. */
370 while (beefs--) 369 while (beefs--)
371 (*ptr4++) = 0xDEADBEEF; 370 (*ptr4++) = 0xDEADBEEF; /* -559038737 base 10 */
372 } 371 }
373 372
374 #else /* !ERROR_CHECK_GC */ 373 #else /* !ERROR_CHECK_GC */
375 374
376 375
410 cons counting. #### (Or perhaps, we should decrement it when an object 409 cons counting. #### (Or perhaps, we should decrement it when an object
411 get freed?) */ 410 get freed?) */
412 411
413 /* But we do now (as of 3-27-02) go and zero out the memory. This is a 412 /* But we do now (as of 3-27-02) go and zero out the memory. This is a
414 good thing, as it will guarantee we won't get any intermittent bugs 413 good thing, as it will guarantee we won't get any intermittent bugs
415 coming from an uninitiated field. The speed loss if unnoticeable, 414 coming from an uninitiated field. The speed loss is unnoticeable,
416 esp. as the object are not large -- large stuff like buffer text and 415 esp. as the objects are not large -- large stuff like buffer text and
417 redisplay structures and allocated separately. */ 416 redisplay structures are allocated separately. */
418 memset (val, 0, size); 417 memset (val, 0, size);
419 418
420 if (need_to_check_c_alloca) 419 if (need_to_check_c_alloca)
421 xemacs_c_alloca (0); 420 xemacs_c_alloca (0);
422 421
427 /* lcrecords are chained together through their "next" field. 426 /* lcrecords are chained together through their "next" field.
428 After doing the mark phase, GC will walk this linked list 427 After doing the mark phase, GC will walk this linked list
429 and free any lcrecord which hasn't been marked. */ 428 and free any lcrecord which hasn't been marked. */
430 static struct lcrecord_header *all_lcrecords; 429 static struct lcrecord_header *all_lcrecords;
431 430
431 /* The most basic of the lcrecord allocation functions. Not usually called
432 directly. Allocates an lrecord not managed by any lcrecord-list, of a
433 specified size. See lrecord.h. */
434
432 void * 435 void *
433 alloc_lcrecord (Bytecount size, 436 basic_alloc_lcrecord (Bytecount size,
434 const struct lrecord_implementation *implementation) 437 const struct lrecord_implementation *implementation)
435 { 438 {
436 struct lcrecord_header *lcheader; 439 struct lcrecord_header *lcheader;
437 440
438 type_checking_assert 441 type_checking_assert
439 ((implementation->static_size == 0 ? 442 ((implementation->static_size == 0 ?
506 { 509 {
507 if (LHEADER_IMPLEMENTATION (&header->lheader)->finalizer && 510 if (LHEADER_IMPLEMENTATION (&header->lheader)->finalizer &&
508 !header->free) 511 !header->free)
509 LHEADER_IMPLEMENTATION (&header->lheader)->finalizer (header, 1); 512 LHEADER_IMPLEMENTATION (&header->lheader)->finalizer (header, 1);
510 } 513 }
514 }
515
516 /* Bitwise copy all parts of a Lisp object other than the header */
517
518 void
519 copy_lisp_object (Lisp_Object dst, Lisp_Object src)
520 {
521 const struct lrecord_implementation *imp =
522 XRECORD_LHEADER_IMPLEMENTATION (src);
523 Bytecount size = lisp_object_size (src);
524
525 assert (imp == XRECORD_LHEADER_IMPLEMENTATION (dst));
526 assert (size == lisp_object_size (dst));
527
528 if (imp->basic_p)
529 memcpy ((char *) XRECORD_LHEADER (dst) + sizeof (struct lrecord_header),
530 (char *) XRECORD_LHEADER (src) + sizeof (struct lrecord_header),
531 size - sizeof (struct lrecord_header));
532 else
533 memcpy ((char *) XRECORD_LHEADER (dst) + sizeof (struct lcrecord_header),
534 (char *) XRECORD_LHEADER (src) + sizeof (struct lcrecord_header),
535 size - sizeof (struct lcrecord_header));
511 } 536 }
512 537
513 538
514 /************************************************************************/ 539 /************************************************************************/
515 /* Debugger support */ 540 /* Debugger support */
595 a string_chars_block, although something like half as big might 620 a string_chars_block, although something like half as big might
596 make more sense) are malloc()ed separately and not stored in 621 make more sense) are malloc()ed separately and not stored in
597 string_chars_blocks. Furthermore, no one string stretches across 622 string_chars_blocks. Furthermore, no one string stretches across
598 two string_chars_blocks. 623 two string_chars_blocks.
599 624
600 Vectors are each malloc()ed separately, similar to lcrecords. 625 Vectors are each malloc()ed separately as lcrecords.
601 626
602 In the following discussion, we use conses, but it applies equally 627 In the following discussion, we use conses, but it applies equally
603 well to the other fixed-size types. 628 well to the other fixed-size types.
604 629
605 We store cons cells inside of cons_blocks, allocating a new 630 We store cons cells inside of cons_blocks, allocating a new
784 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result) do { \ 809 #define ALLOCATE_FIXED_TYPE_1(type, structtype, result) do { \
785 if (gc_count_num_##type##_freelist > \ 810 if (gc_count_num_##type##_freelist > \
786 MINIMUM_ALLOWED_FIXED_TYPE_CELLS_##type) \ 811 MINIMUM_ALLOWED_FIXED_TYPE_CELLS_##type) \
787 { \ 812 { \
788 result = (structtype *) type##_free_list; \ 813 result = (structtype *) type##_free_list; \
789 /* Before actually using the chain pointer, \ 814 assert (LRECORD_FREE_P (result)); \
790 we complement all its bits; see FREE_FIXED_TYPE(). */ \ 815 /* Before actually using the chain pointer, we complement \
816 all its bits; see PUT_FIXED_TYPE_ON_FREE_LIST(). */ \
791 type##_free_list = (Lisp_Free *) \ 817 type##_free_list = (Lisp_Free *) \
792 (~ (EMACS_UINT) (type##_free_list->chain)); \ 818 (~ (EMACS_UINT) (type##_free_list->chain)); \
793 gc_count_num_##type##_freelist--; \ 819 gc_count_num_##type##_freelist--; \
794 } \ 820 } \
795 else \ 821 else \
880 906
881 /* TYPE and STRUCTTYPE are the same as in ALLOCATE_FIXED_TYPE(). */ 907 /* TYPE and STRUCTTYPE are the same as in ALLOCATE_FIXED_TYPE(). */
882 908
883 #define FREE_FIXED_TYPE(type, structtype, ptr) do { \ 909 #define FREE_FIXED_TYPE(type, structtype, ptr) do { \
884 structtype *FFT_ptr = (ptr); \ 910 structtype *FFT_ptr = (ptr); \
911 gc_checking_assert (!LRECORD_FREE_P (FFT_ptr)); \
885 ADDITIONAL_FREE_##type (FFT_ptr); \ 912 ADDITIONAL_FREE_##type (FFT_ptr); \
886 deadbeef_memory (FFT_ptr, sizeof (structtype)); \ 913 deadbeef_memory (FFT_ptr, sizeof (structtype)); \
887 PUT_FIXED_TYPE_ON_FREE_LIST (type, structtype, FFT_ptr); \ 914 PUT_FIXED_TYPE_ON_FREE_LIST (type, structtype, FFT_ptr); \
888 MARK_LRECORD_AS_FREE (FFT_ptr); \ 915 MARK_LRECORD_AS_FREE (FFT_ptr); \
889 } while (0) 916 } while (0)
894 We attempt to undo the changes made to the allocation counters 921 We attempt to undo the changes made to the allocation counters
895 as a result of this structure being allocated. This is not 922 as a result of this structure being allocated. This is not
896 completely necessary but helps keep things saner: e.g. this way, 923 completely necessary but helps keep things saner: e.g. this way,
897 repeatedly allocating and freeing a cons will not result in 924 repeatedly allocating and freeing a cons will not result in
898 the consing-since-gc counter advancing, which would cause a GC 925 the consing-since-gc counter advancing, which would cause a GC
899 and somewhat defeat the purpose of explicitly freeing. */ 926 and somewhat defeat the purpose of explicitly freeing.
900 927
928 We also disable this mechanism entirely when ALLOC_NO_POOLS is
929 set, which is used for Purify and the like. */
930
931 #ifndef ALLOC_NO_POOLS
901 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(type, structtype, ptr) \ 932 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(type, structtype, ptr) \
902 do { FREE_FIXED_TYPE (type, structtype, ptr); \ 933 do { FREE_FIXED_TYPE (type, structtype, ptr); \
903 DECREMENT_CONS_COUNTER (sizeof (structtype)); \ 934 DECREMENT_CONS_COUNTER (sizeof (structtype)); \
904 gc_count_num_##type##_freelist++; \ 935 gc_count_num_##type##_freelist++; \
905 } while (0) 936 } while (0)
937 #else
938 #define FREE_FIXED_TYPE_WHEN_NOT_IN_GC(type, structtype, ptr)
939 #endif
906 940
907 941
908 942
909 /************************************************************************/ 943 /************************************************************************/
910 /* Cons allocation */ 944 /* Cons allocation */
937 return internal_equal (ob1, ob2, depth); 971 return internal_equal (ob1, ob2, depth);
938 } 972 }
939 return 0; 973 return 0;
940 } 974 }
941 975
942 static const struct lrecord_description cons_description[] = { 976 static const struct memory_description cons_description[] = {
943 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car_) }, 977 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car_) },
944 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr_) }, 978 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr_) },
945 { XD_END } 979 { XD_END }
946 }; 980 };
947 981
948 #ifdef USE_KKCC
949 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("cons", cons, 982 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("cons", cons,
950 1, /*dumpable-flag*/ 983 1, /*dumpable-flag*/
951 mark_cons, print_cons, 0, 984 mark_cons, print_cons, 0,
952 cons_equal, 985 cons_equal,
953 /* 986 /*
956 * handle conses. 989 * handle conses.
957 */ 990 */
958 0, 991 0,
959 cons_description, 992 cons_description,
960 Lisp_Cons); 993 Lisp_Cons);
961 #else /* not USE_KKCC */
962 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("cons", cons,
963 mark_cons, print_cons, 0,
964 cons_equal,
965 /*
966 * No `hash' method needed.
967 * internal_hash knows how to
968 * handle conses.
969 */
970 0,
971 cons_description,
972 Lisp_Cons);
973 #endif /* not USE_KKCC */
974 994
975 DEFUN ("cons", Fcons, 2, 2, 0, /* 995 DEFUN ("cons", Fcons, 2, 2, 0, /*
976 Create a new cons, give it CAR and CDR as components, and return it. 996 Create a new cons, give it CAR and CDR as components, and return it.
977 */ 997 */
978 (car, cdr)) 998 (car, cdr))
1166 internal_array_hash (XVECTOR_DATA (obj), 1186 internal_array_hash (XVECTOR_DATA (obj),
1167 XVECTOR_LENGTH (obj), 1187 XVECTOR_LENGTH (obj),
1168 depth + 1)); 1188 depth + 1));
1169 } 1189 }
1170 1190
1171 static const struct lrecord_description vector_description[] = { 1191 static const struct memory_description vector_description[] = {
1172 { XD_LONG, offsetof (Lisp_Vector, size) }, 1192 { XD_LONG, offsetof (Lisp_Vector, size) },
1173 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Vector, contents), XD_INDIRECT(0, 0) }, 1193 { XD_LISP_OBJECT_ARRAY, offsetof (Lisp_Vector, contents), XD_INDIRECT(0, 0) },
1174 { XD_END } 1194 { XD_END }
1175 }; 1195 };
1176 1196
1177 #ifdef USE_KKCC 1197 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("vector", vector,
1178 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION("vector", vector, 1198 1, /*dumpable-flag*/
1179 1, /*dumpable-flag*/ 1199 mark_vector, print_vector, 0,
1180 mark_vector, print_vector, 0, 1200 vector_equal,
1181 vector_equal, 1201 vector_hash,
1182 vector_hash, 1202 vector_description,
1183 vector_description, 1203 size_vector, Lisp_Vector);
1184 size_vector, Lisp_Vector);
1185 #else /* not USE_KKCC */
1186 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION("vector", vector,
1187 mark_vector, print_vector, 0,
1188 vector_equal,
1189 vector_hash,
1190 vector_description,
1191 size_vector, Lisp_Vector);
1192 #endif /* not USE_KKCC */
1193 /* #### should allocate `small' vectors from a frob-block */ 1204 /* #### should allocate `small' vectors from a frob-block */
1194 static Lisp_Vector * 1205 static Lisp_Vector *
1195 make_vector_internal (Elemcount sizei) 1206 make_vector_internal (Elemcount sizei)
1196 { 1207 {
1197 /* no vector_next */ 1208 /* no `next' field; we use lcrecords */
1198 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object, 1209 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Vector, Lisp_Object,
1199 contents, sizei); 1210 contents, sizei);
1200 Lisp_Vector *p = (Lisp_Vector *) alloc_lcrecord (sizem, &lrecord_vector); 1211 Lisp_Vector *p =
1212 (Lisp_Vector *) basic_alloc_lcrecord (sizem, &lrecord_vector);
1201 1213
1202 p->size = sizei; 1214 p->size = sizei;
1203 return p; 1215 return p;
1204 } 1216 }
1205 1217
1342 1354
1343 /************************************************************************/ 1355 /************************************************************************/
1344 /* Bit Vector allocation */ 1356 /* Bit Vector allocation */
1345 /************************************************************************/ 1357 /************************************************************************/
1346 1358
1347 static Lisp_Object all_bit_vectors;
1348
1349 /* #### should allocate `small' bit vectors from a frob-block */ 1359 /* #### should allocate `small' bit vectors from a frob-block */
1350 static Lisp_Bit_Vector * 1360 static Lisp_Bit_Vector *
1351 make_bit_vector_internal (Elemcount sizei) 1361 make_bit_vector_internal (Elemcount sizei)
1352 { 1362 {
1363 /* no `next' field; we use lcrecords */
1353 Elemcount num_longs = BIT_VECTOR_LONG_STORAGE (sizei); 1364 Elemcount num_longs = BIT_VECTOR_LONG_STORAGE (sizei);
1354 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, 1365 Bytecount sizem = FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector,
1355 unsigned long, 1366 unsigned long,
1356 bits, num_longs); 1367 bits, num_longs);
1357 Lisp_Bit_Vector *p = (Lisp_Bit_Vector *) allocate_lisp_storage (sizem); 1368 Lisp_Bit_Vector *p = (Lisp_Bit_Vector *)
1358 set_lheader_implementation (&p->lheader, &lrecord_bit_vector); 1369 basic_alloc_lcrecord (sizem, &lrecord_bit_vector);
1359
1360 INCREMENT_CONS_COUNTER (sizem, "bit-vector");
1361 1370
1362 bit_vector_length (p) = sizei; 1371 bit_vector_length (p) = sizei;
1363 bit_vector_next (p) = all_bit_vectors;
1364 /* make sure the extra bits in the last long are 0; the calling
1365 functions might not set them. */
1366 p->bits[num_longs - 1] = 0;
1367 all_bit_vectors = wrap_bit_vector (p);
1368 return p; 1372 return p;
1369 } 1373 }
1370 1374
1371 Lisp_Object 1375 Lisp_Object
1372 make_bit_vector (Elemcount length, Lisp_Object bit) 1376 make_bit_vector (Elemcount length, Lisp_Object bit)
1688 set_lheader_implementation (&e->lheader, &lrecord_event); 1692 set_lheader_implementation (&e->lheader, &lrecord_event);
1689 1693
1690 return wrap_event (e); 1694 return wrap_event (e);
1691 } 1695 }
1692 1696
1693 #ifdef USE_KKCC 1697 #ifdef EVENT_DATA_AS_OBJECTS
1694 DECLARE_FIXED_TYPE_ALLOC (key_data, Lisp_Key_Data); 1698 DECLARE_FIXED_TYPE_ALLOC (key_data, Lisp_Key_Data);
1695 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_key_data 1000 1699 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_key_data 1000
1696 1700
1697 Lisp_Object 1701 Lisp_Object
1698 allocate_key_data (void) 1702 make_key_data (void)
1699 { 1703 {
1700 Lisp_Key_Data *d; 1704 Lisp_Key_Data *d;
1701 1705
1702 ALLOCATE_FIXED_TYPE (key_data, Lisp_Key_Data, d); 1706 ALLOCATE_FIXED_TYPE (key_data, Lisp_Key_Data, d);
1707 xzero (*d);
1703 set_lheader_implementation (&d->lheader, &lrecord_key_data); 1708 set_lheader_implementation (&d->lheader, &lrecord_key_data);
1704 1709 d->keysym = Qnil;
1705 return wrap_key_data(d); 1710
1711 return wrap_key_data (d);
1706 } 1712 }
1707 1713
1708 DECLARE_FIXED_TYPE_ALLOC (button_data, Lisp_Button_Data); 1714 DECLARE_FIXED_TYPE_ALLOC (button_data, Lisp_Button_Data);
1709 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_button_data 1000 1715 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_button_data 1000
1710 1716
1711 Lisp_Object 1717 Lisp_Object
1712 allocate_button_data (void) 1718 make_button_data (void)
1713 { 1719 {
1714 Lisp_Button_Data *d; 1720 Lisp_Button_Data *d;
1715 1721
1716 ALLOCATE_FIXED_TYPE (button_data, Lisp_Button_Data, d); 1722 ALLOCATE_FIXED_TYPE (button_data, Lisp_Button_Data, d);
1723 xzero (*d);
1717 set_lheader_implementation (&d->lheader, &lrecord_button_data); 1724 set_lheader_implementation (&d->lheader, &lrecord_button_data);
1718 1725
1719 return wrap_button_data(d); 1726 return wrap_button_data (d);
1720 } 1727 }
1721 1728
1722 DECLARE_FIXED_TYPE_ALLOC (motion_data, Lisp_Motion_Data); 1729 DECLARE_FIXED_TYPE_ALLOC (motion_data, Lisp_Motion_Data);
1723 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_motion_data 1000 1730 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_motion_data 1000
1724 1731
1725 Lisp_Object 1732 Lisp_Object
1726 allocate_motion_data (void) 1733 make_motion_data (void)
1727 { 1734 {
1728 Lisp_Motion_Data *d; 1735 Lisp_Motion_Data *d;
1729 1736
1730 ALLOCATE_FIXED_TYPE (motion_data, Lisp_Motion_Data, d); 1737 ALLOCATE_FIXED_TYPE (motion_data, Lisp_Motion_Data, d);
1738 xzero (*d);
1731 set_lheader_implementation (&d->lheader, &lrecord_motion_data); 1739 set_lheader_implementation (&d->lheader, &lrecord_motion_data);
1732 1740
1733 return wrap_motion_data(d); 1741 return wrap_motion_data (d);
1734 } 1742 }
1735 1743
1736 DECLARE_FIXED_TYPE_ALLOC (process_data, Lisp_Process_Data); 1744 DECLARE_FIXED_TYPE_ALLOC (process_data, Lisp_Process_Data);
1737 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_process_data 1000 1745 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_process_data 1000
1738 1746
1739 Lisp_Object 1747 Lisp_Object
1740 allocate_process_data (void) 1748 make_process_data (void)
1741 { 1749 {
1742 Lisp_Process_Data *d; 1750 Lisp_Process_Data *d;
1743 1751
1744 ALLOCATE_FIXED_TYPE (process_data, Lisp_Process_Data, d); 1752 ALLOCATE_FIXED_TYPE (process_data, Lisp_Process_Data, d);
1753 xzero (*d);
1745 set_lheader_implementation (&d->lheader, &lrecord_process_data); 1754 set_lheader_implementation (&d->lheader, &lrecord_process_data);
1746 1755 d->process = Qnil;
1747 return wrap_process_data(d); 1756
1757 return wrap_process_data (d);
1748 } 1758 }
1749 1759
1750 DECLARE_FIXED_TYPE_ALLOC (timeout_data, Lisp_Timeout_Data); 1760 DECLARE_FIXED_TYPE_ALLOC (timeout_data, Lisp_Timeout_Data);
1751 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_timeout_data 1000 1761 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_timeout_data 1000
1752 1762
1753 Lisp_Object 1763 Lisp_Object
1754 allocate_timeout_data (void) 1764 make_timeout_data (void)
1755 { 1765 {
1756 Lisp_Timeout_Data *d; 1766 Lisp_Timeout_Data *d;
1757 1767
1758 ALLOCATE_FIXED_TYPE (timeout_data, Lisp_Timeout_Data, d); 1768 ALLOCATE_FIXED_TYPE (timeout_data, Lisp_Timeout_Data, d);
1769 xzero (*d);
1759 set_lheader_implementation (&d->lheader, &lrecord_timeout_data); 1770 set_lheader_implementation (&d->lheader, &lrecord_timeout_data);
1760 1771 d->function = Qnil;
1761 return wrap_timeout_data(d); 1772 d->object = Qnil;
1773
1774 return wrap_timeout_data (d);
1762 } 1775 }
1763 1776
1764 DECLARE_FIXED_TYPE_ALLOC (magic_data, Lisp_Magic_Data); 1777 DECLARE_FIXED_TYPE_ALLOC (magic_data, Lisp_Magic_Data);
1765 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_magic_data 1000 1778 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_magic_data 1000
1766 1779
1767 Lisp_Object 1780 Lisp_Object
1768 allocate_magic_data (void) 1781 make_magic_data (void)
1769 { 1782 {
1770 Lisp_Magic_Data *d; 1783 Lisp_Magic_Data *d;
1771 1784
1772 ALLOCATE_FIXED_TYPE (magic_data, Lisp_Magic_Data, d); 1785 ALLOCATE_FIXED_TYPE (magic_data, Lisp_Magic_Data, d);
1786 xzero (*d);
1773 set_lheader_implementation (&d->lheader, &lrecord_magic_data); 1787 set_lheader_implementation (&d->lheader, &lrecord_magic_data);
1774 1788
1775 return wrap_magic_data(d); 1789 return wrap_magic_data (d);
1776 } 1790 }
1777 1791
1778 DECLARE_FIXED_TYPE_ALLOC (magic_eval_data, Lisp_Magic_Eval_Data); 1792 DECLARE_FIXED_TYPE_ALLOC (magic_eval_data, Lisp_Magic_Eval_Data);
1779 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_magic_eval_data 1000 1793 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_magic_eval_data 1000
1780 1794
1781 Lisp_Object 1795 Lisp_Object
1782 allocate_magic_eval_data (void) 1796 make_magic_eval_data (void)
1783 { 1797 {
1784 Lisp_Magic_Eval_Data *d; 1798 Lisp_Magic_Eval_Data *d;
1785 1799
1786 ALLOCATE_FIXED_TYPE (magic_eval_data, Lisp_Magic_Eval_Data, d); 1800 ALLOCATE_FIXED_TYPE (magic_eval_data, Lisp_Magic_Eval_Data, d);
1801 xzero (*d);
1787 set_lheader_implementation (&d->lheader, &lrecord_magic_eval_data); 1802 set_lheader_implementation (&d->lheader, &lrecord_magic_eval_data);
1788 1803 d->object = Qnil;
1789 return wrap_magic_eval_data(d); 1804
1805 return wrap_magic_eval_data (d);
1790 } 1806 }
1791 1807
1792 DECLARE_FIXED_TYPE_ALLOC (eval_data, Lisp_Eval_Data); 1808 DECLARE_FIXED_TYPE_ALLOC (eval_data, Lisp_Eval_Data);
1793 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_eval_data 1000 1809 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_eval_data 1000
1794 1810
1795 Lisp_Object 1811 Lisp_Object
1796 allocate_eval_data (void) 1812 make_eval_data (void)
1797 { 1813 {
1798 Lisp_Eval_Data *d; 1814 Lisp_Eval_Data *d;
1799 1815
1800 ALLOCATE_FIXED_TYPE (eval_data, Lisp_Eval_Data, d); 1816 ALLOCATE_FIXED_TYPE (eval_data, Lisp_Eval_Data, d);
1817 xzero (*d);
1801 set_lheader_implementation (&d->lheader, &lrecord_eval_data); 1818 set_lheader_implementation (&d->lheader, &lrecord_eval_data);
1802 1819 d->function = Qnil;
1803 return wrap_eval_data(d); 1820 d->object = Qnil;
1821
1822 return wrap_eval_data (d);
1804 } 1823 }
1805 1824
1806 DECLARE_FIXED_TYPE_ALLOC (misc_user_data, Lisp_Misc_User_Data); 1825 DECLARE_FIXED_TYPE_ALLOC (misc_user_data, Lisp_Misc_User_Data);
1807 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_misc_user_data 1000 1826 #define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_misc_user_data 1000
1808 1827
1809 Lisp_Object 1828 Lisp_Object
1810 allocate_misc_user_data (void) 1829 make_misc_user_data (void)
1811 { 1830 {
1812 Lisp_Misc_User_Data *d; 1831 Lisp_Misc_User_Data *d;
1813 1832
1814 ALLOCATE_FIXED_TYPE (misc_user_data, Lisp_Misc_User_Data, d); 1833 ALLOCATE_FIXED_TYPE (misc_user_data, Lisp_Misc_User_Data, d);
1834 xzero (*d);
1815 set_lheader_implementation (&d->lheader, &lrecord_misc_user_data); 1835 set_lheader_implementation (&d->lheader, &lrecord_misc_user_data);
1816 1836 d->function = Qnil;
1817 return wrap_misc_user_data(d); 1837 d->object = Qnil;
1818 } 1838
1819 #endif /* USE_KKCC */ 1839 return wrap_misc_user_data (d);
1840 }
1841
1842 #endif /* EVENT_DATA_AS_OBJECTS */
1820 1843
1821 /************************************************************************/ 1844 /************************************************************************/
1822 /* Marker allocation */ 1845 /* Marker allocation */
1823 /************************************************************************/ 1846 /************************************************************************/
1824 1847
1862 /* String allocation */ 1885 /* String allocation */
1863 /************************************************************************/ 1886 /************************************************************************/
1864 1887
1865 /* The data for "short" strings generally resides inside of structs of type 1888 /* The data for "short" strings generally resides inside of structs of type
1866 string_chars_block. The Lisp_String structure is allocated just like any 1889 string_chars_block. The Lisp_String structure is allocated just like any
1867 other Lisp object (except for vectors), and these are freelisted when 1890 other basic lrecord, and these are freelisted when they get garbage
1868 they get garbage collected. The data for short strings get compacted, 1891 collected. The data for short strings get compacted, but the data for
1869 but the data for large strings do not. 1892 large strings do not.
1870 1893
1871 Previously Lisp_String structures were relocated, but this caused a lot 1894 Previously Lisp_String structures were relocated, but this caused a lot
1872 of bus-errors because the C code didn't include enough GCPRO's for 1895 of bus-errors because the C code didn't include enough GCPRO's for
1873 strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so 1896 strings (since EVERY REFERENCE to a short string needed to be GCPRO'd so
1874 that the reference would get relocated). 1897 that the reference would get relocated).
1894 Bytecount len; 1917 Bytecount len;
1895 return (((len = XSTRING_LENGTH (obj1)) == XSTRING_LENGTH (obj2)) && 1918 return (((len = XSTRING_LENGTH (obj1)) == XSTRING_LENGTH (obj2)) &&
1896 !memcmp (XSTRING_DATA (obj1), XSTRING_DATA (obj2), len)); 1919 !memcmp (XSTRING_DATA (obj1), XSTRING_DATA (obj2), len));
1897 } 1920 }
1898 1921
1899 static const struct lrecord_description string_description[] = { 1922 static const struct memory_description string_description[] = {
1900 { XD_BYTECOUNT, offsetof (Lisp_String, size_) }, 1923 { XD_BYTECOUNT, offsetof (Lisp_String, size_) },
1901 { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data_), XD_INDIRECT(0, 1) }, 1924 { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data_), XD_INDIRECT(0, 1) },
1902 { XD_LISP_OBJECT, offsetof (Lisp_String, plist) }, 1925 { XD_LISP_OBJECT, offsetof (Lisp_String, plist) },
1903 { XD_END } 1926 { XD_END }
1904 }; 1927 };
1953 /* No `finalize', or `hash' methods. 1976 /* No `finalize', or `hash' methods.
1954 internal_hash() already knows how to hash strings and finalization 1977 internal_hash() already knows how to hash strings and finalization
1955 is done with the ADDITIONAL_FREE_string macro, which is the 1978 is done with the ADDITIONAL_FREE_string macro, which is the
1956 standard way to do finalization when using 1979 standard way to do finalization when using
1957 SWEEP_FIXED_TYPE_BLOCK(). */ 1980 SWEEP_FIXED_TYPE_BLOCK(). */
1958 #ifdef USE_KKCC
1959 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string, 1981 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string,
1960 1, /*dumpable-flag*/ 1982 1, /*dumpable-flag*/
1961 mark_string, print_string, 1983 mark_string, print_string,
1962 0, string_equal, 0, 1984 0, string_equal, 0,
1963 string_description, 1985 string_description,
1964 string_getprop, 1986 string_getprop,
1965 string_putprop, 1987 string_putprop,
1966 string_remprop, 1988 string_remprop,
1967 string_plist, 1989 string_plist,
1968 Lisp_String); 1990 Lisp_String);
1969 #else /* not USE_KKCC */
1970 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("string", string,
1971 mark_string, print_string,
1972 0, string_equal, 0,
1973 string_description,
1974 string_getprop,
1975 string_putprop,
1976 string_remprop,
1977 string_plist,
1978 Lisp_String);
1979 #endif /* not USE_KKCC */
1980 /* String blocks contain this many useful bytes. */ 1991 /* String blocks contain this many useful bytes. */
1981 #define STRING_CHARS_BLOCK_SIZE \ 1992 #define STRING_CHARS_BLOCK_SIZE \
1982 ((Bytecount) (8192 - MALLOC_OVERHEAD - \ 1993 ((Bytecount) (8192 - MALLOC_OVERHEAD - \
1983 ((2 * sizeof (struct string_chars_block *)) \ 1994 ((2 * sizeof (struct string_chars_block *)) \
1984 + sizeof (EMACS_INT)))) 1995 + sizeof (EMACS_INT))))
2482 /************************************************************************/ 2493 /************************************************************************/
2483 /* lcrecord lists */ 2494 /* lcrecord lists */
2484 /************************************************************************/ 2495 /************************************************************************/
2485 2496
2486 /* Lcrecord lists are used to manage the allocation of particular 2497 /* Lcrecord lists are used to manage the allocation of particular
2487 sorts of lcrecords, to avoid calling alloc_lcrecord() (and thus 2498 sorts of lcrecords, to avoid calling basic_alloc_lcrecord() (and thus
2488 malloc() and garbage-collection junk) as much as possible. 2499 malloc() and garbage-collection junk) as much as possible.
2489 It is similar to the Blocktype class. 2500 It is similar to the Blocktype class.
2490 2501
2491 It works like this: 2502 See detailed comment in lcrecord.h.
2492 2503 */
2493 1) Create an lcrecord-list object using make_lcrecord_list(). 2504
2494 This is often done at initialization. Remember to staticpro_nodump 2505 const struct memory_description free_description[] = {
2495 this object! The arguments to make_lcrecord_list() are the 2506 { XD_LISP_OBJECT, offsetof (struct free_lcrecord_header, chain), 0, 0,
2496 same as would be passed to alloc_lcrecord(). 2507 XD_FLAG_FREE_LISP_OBJECT },
2497 2) Instead of calling alloc_lcrecord(), call allocate_managed_lcrecord() 2508 { XD_END }
2498 and pass the lcrecord-list earlier created. 2509 };
2499 3) When done with the lcrecord, call free_managed_lcrecord(). 2510
2500 The standard freeing caveats apply: ** make sure there are no 2511 DEFINE_LRECORD_IMPLEMENTATION ("free", free,
2501 pointers to the object anywhere! ** 2512 0, /*dumpable-flag*/
2502 4) Calling free_managed_lcrecord() is just like kissing the 2513 0, internal_object_printer,
2503 lcrecord goodbye as if it were garbage-collected. This means: 2514 0, 0, 0, free_description,
2504 -- the contents of the freed lcrecord are undefined, and the 2515 struct free_lcrecord_header);
2505 contents of something produced by allocate_managed_lcrecord() 2516
2506 are undefined, just like for alloc_lcrecord(). 2517 const struct memory_description lcrecord_list_description[] = {
2507 -- the mark method for the lcrecord's type will *NEVER* be called 2518 { XD_LISP_OBJECT, offsetof (struct lcrecord_list, free), 0, 0,
2508 on freed lcrecords. 2519 XD_FLAG_FREE_LISP_OBJECT },
2509 -- the finalize method for the lcrecord's type will be called 2520 { XD_END }
2510 at the time that free_managed_lcrecord() is called. 2521 };
2511
2512 */
2513 2522
2514 static Lisp_Object 2523 static Lisp_Object
2515 mark_lcrecord_list (Lisp_Object obj) 2524 mark_lcrecord_list (Lisp_Object obj)
2516 { 2525 {
2517 struct lcrecord_list *list = XLCRECORD_LIST (obj); 2526 struct lcrecord_list *list = XLCRECORD_LIST (obj);
2526 gc_checking_assert 2535 gc_checking_assert
2527 (/* There should be no other pointers to the free list. */ 2536 (/* There should be no other pointers to the free list. */
2528 ! MARKED_RECORD_HEADER_P (lheader) 2537 ! MARKED_RECORD_HEADER_P (lheader)
2529 && 2538 &&
2530 /* Only lcrecords should be here. */ 2539 /* Only lcrecords should be here. */
2531 ! LHEADER_IMPLEMENTATION (lheader)->basic_p 2540 ! list->implementation->basic_p
2532 && 2541 &&
2533 /* Only free lcrecords should be here. */ 2542 /* Only free lcrecords should be here. */
2534 free_header->lcheader.free 2543 free_header->lcheader.free
2535 && 2544 &&
2536 /* The type of the lcrecord must be right. */ 2545 /* The type of the lcrecord must be right. */
2537 LHEADER_IMPLEMENTATION (lheader) == list->implementation 2546 lheader->type == lrecord_type_free
2538 && 2547 &&
2539 /* So must the size. */ 2548 /* So must the size. */
2540 (LHEADER_IMPLEMENTATION (lheader)->static_size == 0 || 2549 (list->implementation->static_size == 0 ||
2541 LHEADER_IMPLEMENTATION (lheader)->static_size == list->size) 2550 list->implementation->static_size == list->size)
2542 ); 2551 );
2543 2552
2544 MARK_RECORD_HEADER (lheader); 2553 MARK_RECORD_HEADER (lheader);
2545 chain = free_header->chain; 2554 chain = free_header->chain;
2546 } 2555 }
2547 2556
2548 return Qnil; 2557 return Qnil;
2549 } 2558 }
2550 2559
2551 #ifdef USE_KKCC
2552 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list, 2560 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list,
2553 0, /*dumpable-flag*/ 2561 0, /*dumpable-flag*/
2554 mark_lcrecord_list, internal_object_printer, 2562 mark_lcrecord_list, internal_object_printer,
2555 0, 0, 0, 0, struct lcrecord_list); 2563 0, 0, 0, lcrecord_list_description,
2556 #else /* not USE_KKCC */ 2564 struct lcrecord_list);
2557 DEFINE_LRECORD_IMPLEMENTATION ("lcrecord-list", lcrecord_list,
2558 mark_lcrecord_list, internal_object_printer,
2559 0, 0, 0, 0, struct lcrecord_list);
2560 #endif /* not USE_KKCC */
2561 2565
2562 Lisp_Object 2566 Lisp_Object
2563 make_lcrecord_list (Elemcount size, 2567 make_lcrecord_list (Elemcount size,
2564 const struct lrecord_implementation *implementation) 2568 const struct lrecord_implementation *implementation)
2565 { 2569 {
2566 struct lcrecord_list *p = 2570 /* Don't use alloc_lcrecord_type() avoid infinite recursion
2567 /* Avoid infinite recursion allocating this */ 2571 allocating this, */
2568 alloc_unmanaged_lcrecord_type (struct lcrecord_list, 2572 struct lcrecord_list *p = (struct lcrecord_list *)
2569 &lrecord_lcrecord_list); 2573 basic_alloc_lcrecord (sizeof (struct lcrecord_list),
2574 &lrecord_lcrecord_list);
2570 2575
2571 p->implementation = implementation; 2576 p->implementation = implementation;
2572 p->size = size; 2577 p->size = size;
2573 p->free = Qnil; 2578 p->free = Qnil;
2574 return wrap_lcrecord_list (p); 2579 return wrap_lcrecord_list (p);
2575 } 2580 }
2576 2581
2577 Lisp_Object 2582 Lisp_Object
2578 allocate_managed_lcrecord (Lisp_Object lcrecord_list) 2583 alloc_managed_lcrecord (Lisp_Object lcrecord_list)
2579 { 2584 {
2580 struct lcrecord_list *list = XLCRECORD_LIST (lcrecord_list); 2585 struct lcrecord_list *list = XLCRECORD_LIST (lcrecord_list);
2581 if (!NILP (list->free)) 2586 if (!NILP (list->free))
2582 { 2587 {
2583 Lisp_Object val = list->free; 2588 Lisp_Object val = list->free;
2584 struct free_lcrecord_header *free_header = 2589 struct free_lcrecord_header *free_header =
2585 (struct free_lcrecord_header *) XPNTR (val); 2590 (struct free_lcrecord_header *) XPNTR (val);
2591 struct lrecord_header *lheader = &free_header->lcheader.lheader;
2586 2592
2587 #ifdef ERROR_CHECK_GC 2593 #ifdef ERROR_CHECK_GC
2588 struct lrecord_header *lheader = &free_header->lcheader.lheader; 2594 /* Major overkill here. */
2589
2590 /* There should be no other pointers to the free list. */ 2595 /* There should be no other pointers to the free list. */
2591 assert (! MARKED_RECORD_HEADER_P (lheader)); 2596 assert (! MARKED_RECORD_HEADER_P (lheader));
2592 /* Only lcrecords should be here. */
2593 assert (! LHEADER_IMPLEMENTATION (lheader)->basic_p);
2594 /* Only free lcrecords should be here. */ 2597 /* Only free lcrecords should be here. */
2595 assert (free_header->lcheader.free); 2598 assert (free_header->lcheader.free);
2599 assert (lheader->type == lrecord_type_free);
2600 /* Only lcrecords should be here. */
2601 assert (! (list->implementation->basic_p));
2602 #if 0 /* Not used anymore, now that we set the type of the header to
2603 lrecord_type_free. */
2596 /* The type of the lcrecord must be right. */ 2604 /* The type of the lcrecord must be right. */
2597 assert (LHEADER_IMPLEMENTATION (lheader) == list->implementation); 2605 assert (LHEADER_IMPLEMENTATION (lheader) == list->implementation);
2606 #endif /* 0 */
2598 /* So must the size. */ 2607 /* So must the size. */
2599 assert (LHEADER_IMPLEMENTATION (lheader)->static_size == 0 || 2608 assert (list->implementation->static_size == 0 ||
2600 LHEADER_IMPLEMENTATION (lheader)->static_size == list->size); 2609 list->implementation->static_size == list->size);
2601 #endif /* ERROR_CHECK_GC */ 2610 #endif /* ERROR_CHECK_GC */
2602 2611
2603 list->free = free_header->chain; 2612 list->free = free_header->chain;
2604 free_header->lcheader.free = 0; 2613 free_header->lcheader.free = 0;
2614 /* Put back the correct type, as we set it to lrecord_type_free. */
2615 lheader->type = list->implementation->lrecord_type_index;
2616 zero_sized_lcrecord (free_header, list->size);
2605 return val; 2617 return val;
2606 } 2618 }
2607 else 2619 else
2608 return wrap_pointer_1 (alloc_lcrecord (list->size, list->implementation)); 2620 return wrap_pointer_1 (basic_alloc_lcrecord (list->size,
2621 list->implementation));
2609 } 2622 }
2610 2623
2611 /* "Free" a Lisp object LCRECORD by placing it on its associated free list 2624 /* "Free" a Lisp object LCRECORD by placing it on its associated free list
2612 LCRECORD_LIST; next time allocate_managed_lcrecord() is called with the 2625 LCRECORD_LIST; next time alloc_managed_lcrecord() is called with the
2613 same LCRECORD_LIST as its parameter, it will return an object from the 2626 same LCRECORD_LIST as its parameter, it will return an object from the
2614 free list, which may be this one. Be VERY VERY SURE there are no 2627 free list, which may be this one. Be VERY VERY SURE there are no
2615 pointers to this object hanging around anywhere where they might be 2628 pointers to this object hanging around anywhere where they might be
2616 used! 2629 used!
2617 2630
2639 problems. */ 2652 problems. */
2640 gc_checking_assert (!gc_in_progress); 2653 gc_checking_assert (!gc_in_progress);
2641 2654
2642 /* Make sure the size is correct. This will catch, for example, 2655 /* Make sure the size is correct. This will catch, for example,
2643 putting a window configuration on the wrong free list. */ 2656 putting a window configuration on the wrong free list. */
2644 gc_checking_assert ((implementation->size_in_bytes_method ? 2657 gc_checking_assert (detagged_lisp_object_size (lheader) == list->size);
2645 implementation->size_in_bytes_method (lheader) :
2646 implementation->static_size)
2647 == list->size);
2648 /* Make sure the object isn't already freed. */ 2658 /* Make sure the object isn't already freed. */
2649 gc_checking_assert (!free_header->lcheader.free); 2659 gc_checking_assert (!free_header->lcheader.free);
2650 2660
2651 if (implementation->finalizer) 2661 if (implementation->finalizer)
2652 implementation->finalizer (lheader, 0); 2662 implementation->finalizer (lheader, 0);
2663 /* Yes, there are two ways to indicate freeness -- the type is
2664 lrecord_type_free or the ->free flag is set. We used to do only the
2665 latter; now we do the former as well for KKCC purposes. Probably
2666 safer in any case, as we will lose quicker this way than keeping
2667 around an lrecord of apparently correct type but bogus junk in it. */
2668 MARK_LRECORD_AS_FREE (lheader);
2653 free_header->chain = list->free; 2669 free_header->chain = list->free;
2654 free_header->lcheader.free = 1; 2670 free_header->lcheader.free = 1;
2655 list->free = lcrecord; 2671 list->free = lcrecord;
2656 } 2672 }
2657 2673
2663 { 2679 {
2664 if (EQ (all_lcrecord_lists[imp->lrecord_type_index], Qzero)) 2680 if (EQ (all_lcrecord_lists[imp->lrecord_type_index], Qzero))
2665 all_lcrecord_lists[imp->lrecord_type_index] = 2681 all_lcrecord_lists[imp->lrecord_type_index] =
2666 make_lcrecord_list (size, imp); 2682 make_lcrecord_list (size, imp);
2667 2683
2668 return XPNTR (allocate_managed_lcrecord 2684 return XPNTR (alloc_managed_lcrecord
2669 (all_lcrecord_lists[imp->lrecord_type_index])); 2685 (all_lcrecord_lists[imp->lrecord_type_index]));
2670 } 2686 }
2671 2687
2672 void 2688 void
2673 free_lcrecord (Lisp_Object rec) 2689 free_lcrecord (Lisp_Object rec)
2714 in the heap; we only dump heap objects. Hence we use a trivial 2730 in the heap; we only dump heap objects. Hence we use a trivial
2715 description, as for pointerless objects. (Note that the data segment 2731 description, as for pointerless objects. (Note that the data segment
2716 objects, which are global variables like Qfoo or Vbar, themselves are 2732 objects, which are global variables like Qfoo or Vbar, themselves are
2717 pointers to heap objects. Each needs to be described to pdump as a 2733 pointers to heap objects. Each needs to be described to pdump as a
2718 "root pointer"; this happens in the call to staticpro(). */ 2734 "root pointer"; this happens in the call to staticpro(). */
2719 static const struct lrecord_description staticpro_description_1[] = { 2735 static const struct memory_description staticpro_description_1[] = {
2720 { XD_END } 2736 { XD_END }
2721 }; 2737 };
2722 2738
2723 static const struct struct_description staticpro_description = { 2739 static const struct sized_memory_description staticpro_description = {
2724 sizeof (Lisp_Object *), 2740 sizeof (Lisp_Object *),
2725 staticpro_description_1 2741 staticpro_description_1
2726 }; 2742 };
2727 2743
2728 static const struct lrecord_description staticpros_description_1[] = { 2744 static const struct memory_description staticpros_description_1[] = {
2729 XD_DYNARR_DESC (Lisp_Object_ptr_dynarr, &staticpro_description), 2745 XD_DYNARR_DESC (Lisp_Object_ptr_dynarr, &staticpro_description),
2730 { XD_END } 2746 { XD_END }
2731 }; 2747 };
2732 2748
2733 static const struct struct_description staticpros_description = { 2749 static const struct sized_memory_description staticpros_description = {
2734 sizeof (Lisp_Object_ptr_dynarr), 2750 sizeof (Lisp_Object_ptr_dynarr),
2735 staticpros_description_1 2751 staticpros_description_1
2736 }; 2752 };
2737 2753
2738 #ifdef DEBUG_XEMACS 2754 #ifdef DEBUG_XEMACS
2739 2755
2740 static const struct lrecord_description staticpro_one_name_description_1[] = { 2756 static const struct memory_description staticpro_one_name_description_1[] = {
2741 { XD_C_STRING, 0 }, 2757 { XD_C_STRING, 0 },
2742 { XD_END } 2758 { XD_END }
2743 }; 2759 };
2744 2760
2745 static const struct struct_description staticpro_one_name_description = { 2761 static const struct sized_memory_description staticpro_one_name_description = {
2746 sizeof (char *), 2762 sizeof (char *),
2747 staticpro_one_name_description_1 2763 staticpro_one_name_description_1
2748 }; 2764 };
2749 2765
2750 static const struct lrecord_description staticpro_names_description_1[] = { 2766 static const struct memory_description staticpro_names_description_1[] = {
2751 XD_DYNARR_DESC (char_ptr_dynarr, &staticpro_one_name_description), 2767 XD_DYNARR_DESC (char_ptr_dynarr, &staticpro_one_name_description),
2752 { XD_END } 2768 { XD_END }
2753 }; 2769 };
2754 2770
2755 static const struct struct_description staticpro_names_description = { 2771
2772 extern const struct sized_memory_description staticpro_names_description;
2773
2774 const struct sized_memory_description staticpro_names_description = {
2756 sizeof (char_ptr_dynarr), 2775 sizeof (char_ptr_dynarr),
2757 staticpro_names_description_1 2776 staticpro_names_description_1
2758 }; 2777 };
2759 2778
2760 /* Help debug crashes gc-marking a staticpro'ed object. */ 2779 /* Help debug crashes gc-marking a staticpro'ed object. */
2767 void 2786 void
2768 staticpro_1 (Lisp_Object *varaddress, char *varname) 2787 staticpro_1 (Lisp_Object *varaddress, char *varname)
2769 { 2788 {
2770 Dynarr_add (staticpros, varaddress); 2789 Dynarr_add (staticpros, varaddress);
2771 Dynarr_add (staticpro_names, varname); 2790 Dynarr_add (staticpro_names, varname);
2772 dump_add_root_object (varaddress); 2791 dump_add_root_lisp_object (varaddress);
2773 } 2792 }
2774 2793
2775 2794
2776 Lisp_Object_ptr_dynarr *staticpros_nodump; 2795 Lisp_Object_ptr_dynarr *staticpros_nodump;
2777 char_ptr_dynarr *staticpro_nodump_names; 2796 char_ptr_dynarr *staticpro_nodump_names;
2804 garbage collection, and for dumping. */ 2823 garbage collection, and for dumping. */
2805 void 2824 void
2806 staticpro (Lisp_Object *varaddress) 2825 staticpro (Lisp_Object *varaddress)
2807 { 2826 {
2808 Dynarr_add (staticpros, varaddress); 2827 Dynarr_add (staticpros, varaddress);
2809 dump_add_root_object (varaddress); 2828 dump_add_root_lisp_object (varaddress);
2810 } 2829 }
2811 2830
2812 2831
2813 Lisp_Object_ptr_dynarr *staticpros_nodump; 2832 Lisp_Object_ptr_dynarr *staticpros_nodump;
2814 2833
2859 #else 2878 #else
2860 #define GC_CHECK_LHEADER_INVARIANTS(lheader) 2879 #define GC_CHECK_LHEADER_INVARIANTS(lheader)
2861 #endif 2880 #endif
2862 2881
2863 2882
2864 2883 static const struct memory_description lisp_object_description_1[] = {
2865 #ifdef USE_KKCC 2884 { XD_LISP_OBJECT, 0 },
2866 /* The following functions implement the new mark algorithm. 2885 { XD_END }
2867 They mark objects according to their descriptions. They 2886 };
2868 are modeled on the corresponding pdumper procedures. */ 2887
2869 2888 const struct sized_memory_description lisp_object_description = {
2870 static void mark_struct_contents (const void *data, 2889 sizeof (Lisp_Object),
2871 const struct struct_description * 2890 lisp_object_description_1
2872 sdesc, 2891 };
2873 int count); 2892
2893 #if defined (USE_KKCC) || defined (PDUMP)
2874 2894
2875 /* This function extracts the value of a count variable described somewhere 2895 /* This function extracts the value of a count variable described somewhere
2876 else in the description. It is converted corresponding to the type */ 2896 else in the description. It is converted corresponding to the type */
2877 static EMACS_INT 2897 EMACS_INT
2878 get_indirect_count (EMACS_INT code, 2898 lispdesc_indirect_count_1 (EMACS_INT code,
2879 const struct lrecord_description *idesc, 2899 const struct memory_description *idesc,
2880 const void *idata) 2900 const void *idata)
2881 { 2901 {
2882 EMACS_INT count; 2902 EMACS_INT count;
2883 const void *irdata; 2903 const void *irdata;
2884 2904
2885 int line = XD_INDIRECT_VAL (code); 2905 int line = XD_INDIRECT_VAL (code);
2886 int delta = XD_INDIRECT_DELTA (code); 2906 int delta = XD_INDIRECT_DELTA (code);
2887 2907
2888 irdata = ((char *)idata) + idesc[line].offset; 2908 irdata = ((char *) idata) +
2909 lispdesc_indirect_count (idesc[line].offset, idesc, idata);
2889 switch (idesc[line].type) 2910 switch (idesc[line].type)
2890 { 2911 {
2891 case XD_BYTECOUNT: 2912 case XD_BYTECOUNT:
2892 count = *(Bytecount *)irdata; 2913 count = * (Bytecount *) irdata;
2893 break; 2914 break;
2894 case XD_ELEMCOUNT: 2915 case XD_ELEMCOUNT:
2895 count = *(Elemcount *)irdata; 2916 count = * (Elemcount *) irdata;
2896 break; 2917 break;
2897 case XD_HASHCODE: 2918 case XD_HASHCODE:
2898 count = *(Hashcode *)irdata; 2919 count = * (Hashcode *) irdata;
2899 break; 2920 break;
2900 case XD_INT: 2921 case XD_INT:
2901 count = *(int *)irdata; 2922 count = * (int *) irdata;
2902 break; 2923 break;
2903 case XD_LONG: 2924 case XD_LONG:
2904 count = *(long *)irdata; 2925 count = * (long *) irdata;
2905 break; 2926 break;
2906 default: 2927 default:
2907 stderr_out ("Unsupported count type : %d (line = %d, code = %ld)\n", 2928 stderr_out ("Unsupported count type : %d (line = %d, code = %ld)\n",
2908 idesc[line].type, line, (long)code); 2929 idesc[line].type, line, (long) code);
2930 #ifdef PDUMP
2931 if (in_pdump)
2932 pdump_backtrace ();
2933 #endif
2909 count = 0; /* warning suppression */ 2934 count = 0; /* warning suppression */
2910 abort (); 2935 abort ();
2911 } 2936 }
2912 count += delta; 2937 count += delta;
2913 return count; 2938 return count;
2914 } 2939 }
2940
2941 /* SDESC is a "description map" (basically, a list of offsets used for
2942 successive indirections) and OBJ is the first object to indirect off of.
2943 Return the description ultimately found. */
2944
2945 const struct sized_memory_description *
2946 lispdesc_indirect_description_1 (const void *obj,
2947 const struct sized_memory_description *sdesc)
2948 {
2949 int pos;
2950
2951 for (pos = 0; sdesc[pos].size >= 0; pos++)
2952 obj = * (const void **) ((const char *) obj + sdesc[pos].size);
2953
2954 return (const struct sized_memory_description *) obj;
2955 }
2956
2957 /* Compute the size of the data at RDATA, described by a single entry
2958 DESC1 in a description array. OBJ and DESC are used for
2959 XD_INDIRECT references. */
2960
2961 static Bytecount
2962 lispdesc_one_description_line_size (void *rdata,
2963 const struct memory_description *desc1,
2964 const void *obj,
2965 const struct memory_description *desc)
2966 {
2967 union_switcheroo:
2968 switch (desc1->type)
2969 {
2970 case XD_LISP_OBJECT_ARRAY:
2971 {
2972 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj);
2973 return (val * sizeof (Lisp_Object));
2974 }
2975 case XD_LISP_OBJECT:
2976 case XD_LO_LINK:
2977 return sizeof (Lisp_Object);
2978 case XD_OPAQUE_PTR:
2979 return sizeof (void *);
2980 case XD_STRUCT_PTR:
2981 {
2982 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj);
2983 return val * sizeof (void *);
2984 }
2985 case XD_STRUCT_ARRAY:
2986 {
2987 EMACS_INT val = lispdesc_indirect_count (desc1->data1, desc, obj);
2988
2989 return (val *
2990 lispdesc_structure_size
2991 (rdata, lispdesc_indirect_description (obj, desc1->data2)));
2992 }
2993 case XD_OPAQUE_DATA_PTR:
2994 return sizeof (void *);
2995 case XD_UNION_DYNAMIC_SIZE:
2996 {
2997 /* If an explicit size was given in the first-level structure
2998 description, use it; else compute size based on current union
2999 constant. */
3000 const struct sized_memory_description *sdesc =
3001 lispdesc_indirect_description (obj, desc1->data2);
3002 if (sdesc->size)
3003 return sdesc->size;
3004 else
3005 {
3006 desc1 = lispdesc_process_xd_union (desc1, desc, obj);
3007 if (desc1)
3008 goto union_switcheroo;
3009 break;
3010 }
3011 }
3012 case XD_UNION:
3013 {
3014 /* If an explicit size was given in the first-level structure
3015 description, use it; else compute size based on maximum of all
3016 possible structures. */
3017 const struct sized_memory_description *sdesc =
3018 lispdesc_indirect_description (obj, desc1->data2);
3019 if (sdesc->size)
3020 return sdesc->size;
3021 else
3022 {
3023 int count;
3024 Bytecount max_size = -1, size;
3025
3026 desc1 = sdesc->description;
3027
3028 for (count = 0; desc1[count].type != XD_END; count++)
3029 {
3030 size = lispdesc_one_description_line_size (rdata,
3031 &desc1[count],
3032 obj, desc);
3033 if (size > max_size)
3034 max_size = size;
3035 }
3036 return max_size;
3037 }
3038 }
3039 case XD_C_STRING:
3040 return sizeof (void *);
3041 case XD_DOC_STRING:
3042 return sizeof (void *);
3043 case XD_INT_RESET:
3044 return sizeof (int);
3045 case XD_BYTECOUNT:
3046 return sizeof (Bytecount);
3047 case XD_ELEMCOUNT:
3048 return sizeof (Elemcount);
3049 case XD_HASHCODE:
3050 return sizeof (Hashcode);
3051 case XD_INT:
3052 return sizeof (int);
3053 case XD_LONG:
3054 return sizeof (long);
3055 default:
3056 stderr_out ("Unsupported dump type : %d\n", desc1->type);
3057 abort ();
3058 }
3059
3060 return 0;
3061 }
3062
3063
3064 /* Return the size of the memory block (NOT necessarily a structure!)
3065 described by SDESC and pointed to by OBJ. If SDESC records an
3066 explicit size (i.e. non-zero), it is simply returned; otherwise,
3067 the size is calculated by the maximum offset and the size of the
3068 object at that offset, rounded up to the maximum alignment. In
3069 this case, we may need the object, for example when retrieving an
3070 "indirect count" of an inlined array (the count is not constant,
3071 but is specified by one of the elements of the memory block). (It
3072 is generally not a problem if we return an overly large size -- we
3073 will simply end up reserving more space than necessary; but if the
3074 size is too small we could be in serious trouble, in particular
3075 with nested inlined structures, where there may be alignment
3076 padding in the middle of a block. #### In fact there is an (at
3077 least theoretical) problem with an overly large size -- we may
3078 trigger a protection fault when reading from invalid memory. We
3079 need to handle this -- perhaps in a stupid but dependable way,
3080 i.e. by trapping SIGSEGV and SIGBUS.) */
3081
3082 Bytecount
3083 lispdesc_structure_size (const void *obj,
3084 const struct sized_memory_description *sdesc)
3085 {
3086 EMACS_INT max_offset = -1;
3087 int max_offset_pos = -1;
3088 int pos;
3089 const struct memory_description *desc;
3090
3091 if (sdesc->size)
3092 return sdesc->size;
3093
3094 desc = sdesc->description;
3095
3096 for (pos = 0; desc[pos].type != XD_END; pos++)
3097 {
3098 EMACS_INT offset = lispdesc_indirect_count (desc[pos].offset, desc, obj);
3099 if (offset == max_offset)
3100 {
3101 stderr_out ("Two relocatable elements at same offset?\n");
3102 abort ();
3103 }
3104 else if (offset > max_offset)
3105 {
3106 max_offset = offset;
3107 max_offset_pos = pos;
3108 }
3109 }
3110
3111 if (max_offset_pos < 0)
3112 return 0;
3113
3114 {
3115 Bytecount size_at_max;
3116 size_at_max =
3117 lispdesc_one_description_line_size ((char *) obj + max_offset,
3118 &desc[max_offset_pos], obj, desc);
3119
3120 /* We have no way of knowing the required alignment for this structure,
3121 so just make it maximally aligned. */
3122 return MAX_ALIGN_SIZE (max_offset + size_at_max);
3123 }
3124 }
3125
3126 #endif /* defined (USE_KKCC) || defined (PDUMP) */
3127
3128 #ifdef USE_KKCC
3129 /* The following functions implement the new mark algorithm.
3130 They mark objects according to their descriptions. They
3131 are modeled on the corresponding pdumper procedures. */
3132
3133 static void mark_struct_contents (const void *data,
3134 const struct sized_memory_description *sdesc,
3135 int count);
3136
3137
3138 #ifdef ERROR_CHECK_GC
3139 void
3140 mark_object_maybe_checking_free (Lisp_Object obj, int allow_free)
3141 {
3142
3143 if (!allow_free && XTYPE (obj) == Lisp_Type_Record)
3144 {
3145 struct lrecord_header *lheader = XRECORD_LHEADER (obj);
3146 gc_checking_assert (LHEADER_IMPLEMENTATION (lheader)->basic_p ||
3147 ! ((struct lcrecord_header *) lheader)->free);
3148 }
3149 mark_object (obj);
3150 }
3151 #else
3152 #define mark_object_maybe_checking_free (obj, allow_free) mark_object (obj)
3153 #endif /* ERROR_CHECK_GC */
2915 3154
2916 /* This function is called to mark the elements of an object. It processes 3155 /* This function is called to mark the elements of an object. It processes
2917 the description of the object and calls mark object with every described 3156 the description of the object and calls mark object with every described
2918 object. */ 3157 object. */
2919 static void 3158 static void
2920 mark_with_description (const void *lheader, const struct lrecord_description *desc) 3159 mark_with_description (const void *data,
3160 const struct memory_description *desc)
2921 { 3161 {
2922 int pos; 3162 int pos;
2923 3163 static const Lisp_Object *last_occurred_object = (Lisp_Object *) 0;
2924 static const Lisp_Object *last_occured_object = (Lisp_Object *) 0; 3164 static int mark_last_occurred_object = 0;
2925 static int mark_last_occured_object = 0; 3165 #ifdef ERROR_CHECK_GC
2926 3166 static int last_occurred_flags;
2927 reprocess_desc: 3167 #endif
2928 for (pos=0; desc[pos].type != XD_END; pos++) 3168
2929 { 3169 for (pos = 0; desc[pos].type != XD_END; pos++)
2930 const void *rdata = (const char *)lheader + desc[pos].offset; 3170 {
2931 switch (desc[pos].type) { 3171 const struct memory_description *desc1 = &desc[pos];
2932 case XD_LISP_OBJECT: 3172 const void *rdata =
3173 (const char *) data + lispdesc_indirect_count (desc1->offset,
3174 desc, data);
3175 union_switcheroo:
3176
3177 /* If the flag says don't mark, then don't mark. */
3178 if ((desc1->flags) & XD_FLAG_NO_KKCC)
3179 continue;
3180
3181 switch (desc1->type)
2933 { 3182 {
2934 const Lisp_Object *stored_obj = (const Lisp_Object *)rdata; 3183 case XD_BYTECOUNT:
2935 3184 case XD_ELEMCOUNT:
2936 if (EQ (*stored_obj, Qnull_pointer)) 3185 case XD_HASHCODE:
3186 case XD_INT:
3187 case XD_LONG:
3188 case XD_INT_RESET:
3189 case XD_LO_LINK:
3190 case XD_OPAQUE_PTR:
3191 case XD_OPAQUE_DATA_PTR:
3192 case XD_C_STRING:
3193 case XD_DOC_STRING:
3194 break;
3195 case XD_LISP_OBJECT:
3196 {
3197 const Lisp_Object *stored_obj = (const Lisp_Object *) rdata;
3198
3199 /* Because of the way that tagged objects work (pointers and
3200 Lisp_Objects have the same representation), XD_LISP_OBJECT
3201 can be used for untagged pointers. They might be NULL,
3202 though. */
3203 if (EQ (*stored_obj, Qnull_pointer))
3204 break;
3205
3206 if (desc[pos+1].type == XD_END)
3207 {
3208 mark_last_occurred_object = 1;
3209 last_occurred_object = stored_obj;
3210 #ifdef ERROR_CHECK_GC
3211 last_occurred_flags = desc1->flags;
3212 #endif
3213 break;
3214 }
3215 else
3216 mark_object_maybe_checking_free
3217 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT);
3218
2937 break; 3219 break;
2938 3220 }
2939 if (desc[pos+1].type == XD_END) 3221 case XD_LISP_OBJECT_ARRAY:
2940 { 3222 {
2941 mark_last_occured_object = 1; 3223 int i;
2942 last_occured_object = stored_obj; 3224 EMACS_INT count =
2943 break; 3225 lispdesc_indirect_count (desc1->data1, desc, data);
2944 } 3226
2945 else 3227 for (i = 0; i < count; i++)
2946 { 3228 {
2947 mark_object (*stored_obj); 3229 const Lisp_Object *stored_obj =
2948 } 3230 (const Lisp_Object *) rdata + i;
2949 3231
2950 3232 if (EQ (*stored_obj, Qnull_pointer))
3233 break;
3234
3235 mark_object_maybe_checking_free
3236 (*stored_obj, (desc1->flags) & XD_FLAG_FREE_LISP_OBJECT);
3237 }
3238 break;
3239 }
3240 case XD_STRUCT_PTR:
3241 {
3242 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc,
3243 data);
3244 const struct sized_memory_description *sdesc =
3245 lispdesc_indirect_description (data, desc1->data2);
3246 const char *dobj = * (const char **) rdata;
3247 if (dobj)
3248 mark_struct_contents (dobj, sdesc, count);
3249 break;
3250 }
3251 case XD_STRUCT_ARRAY:
3252 {
3253 EMACS_INT count = lispdesc_indirect_count (desc1->data1, desc,
3254 data);
3255 const struct sized_memory_description *sdesc =
3256 lispdesc_indirect_description (data, desc1->data2);
3257
3258 mark_struct_contents (rdata, sdesc, count);
3259 break;
3260 }
3261 case XD_UNION:
3262 case XD_UNION_DYNAMIC_SIZE:
3263 desc1 = lispdesc_process_xd_union (desc1, desc, data);
3264 if (desc1)
3265 goto union_switcheroo;
2951 break; 3266 break;
2952 }
2953 case XD_LISP_OBJECT_ARRAY:
2954 {
2955 int i;
2956 EMACS_INT count = desc[pos].data1;
2957 if (XD_IS_INDIRECT (count))
2958 count = get_indirect_count (count, desc, lheader);
2959
2960 for (i = 0; i < count; i++)
2961 {
2962 const Lisp_Object *stored_obj = ((const Lisp_Object *)rdata) + i;
2963
2964 if (EQ (*stored_obj, Qnull_pointer))
2965 break;
2966
2967 mark_object (*stored_obj);
2968 }
2969 break;
2970 }
2971 case XD_SPECIFIER_END:
2972 desc = ((const Lisp_Specifier *)lheader)->methods->extra_description;
2973 goto reprocess_desc;
2974 break;
2975 case XD_CODING_SYSTEM_END:
2976 desc = ((const Lisp_Coding_System *)lheader)->methods->extra_description;
2977 goto reprocess_desc;
2978 break;
2979 case XD_BYTECOUNT:
2980 break;
2981 case XD_ELEMCOUNT:
2982 break;
2983 case XD_HASHCODE:
2984 break;
2985 case XD_INT:
2986 break;
2987 case XD_LONG:
2988 break;
2989 case XD_INT_RESET:
2990 break;
2991 case XD_LO_LINK:
2992 break;
2993 case XD_OPAQUE_PTR:
2994 break;
2995 case XD_OPAQUE_DATA_PTR:
2996 break;
2997 case XD_C_STRING:
2998 break;
2999 case XD_DOC_STRING:
3000 break;
3001 case XD_STRUCT_PTR:
3002 {
3003 EMACS_INT count = desc[pos].data1;
3004 const struct struct_description *sdesc = desc[pos].data2;
3005 const char *dobj = *(const char **)rdata;
3006 if (dobj)
3007 {
3008 if (XD_IS_INDIRECT (count))
3009 count = get_indirect_count (count, desc, lheader);
3010 mark_struct_contents (dobj, sdesc, count);
3011 }
3012 break;
3013 }
3014 case XD_STRUCT_ARRAY:
3015 {
3016 EMACS_INT count = desc[pos].data1;
3017 const struct struct_description *sdesc = desc[pos].data2;
3018
3019 if (XD_IS_INDIRECT (count))
3020 count = get_indirect_count (count, desc, lheader);
3021
3022 mark_struct_contents (rdata, sdesc, count);
3023 break;
3024 }
3025 case XD_UNION:
3026 {
3027 int count = 0;
3028 int variant = desc[pos].data1;
3029 const struct struct_description *sdesc = desc[pos].data2;
3030 const char *dobj = *(const char **)rdata;
3031 if (XD_IS_INDIRECT (variant))
3032 variant = get_indirect_count (variant, desc, lheader);
3033
3034 for (count=0; sdesc[count].size != XD_END; count++)
3035 {
3036 if (sdesc[count].size == variant)
3037 {
3038 mark_with_description(dobj, sdesc[count].description);
3039 break;
3040 }
3041 }
3042 break;
3043 }
3044 3267
3045 default: 3268 default:
3046 stderr_out ("Unsupported description type : %d\n", desc[pos].type); 3269 stderr_out ("Unsupported description type : %d\n", desc1->type);
3047 abort ();
3048 }
3049 }
3050
3051 if (mark_last_occured_object)
3052 {
3053 mark_object(*last_occured_object);
3054 mark_last_occured_object = 0;
3055 }
3056 }
3057
3058
3059 /* This function calculates the size of a described struct. */
3060 static Bytecount
3061 structure_size (const void *obj, const struct struct_description *sdesc)
3062 {
3063 int max_offset = -1;
3064 int max_offset_pos = -1;
3065 int size_at_max = 0;
3066 int pos;
3067 const struct lrecord_description *desc;
3068 void *rdata;
3069
3070 if (sdesc->size)
3071 return sdesc->size;
3072
3073 desc = sdesc->description;
3074
3075 for (pos = 0; desc[pos].type != XD_END; pos++)
3076 {
3077 if (desc[pos].offset == max_offset)
3078 {
3079 stderr_out ("Two relocatable elements at same offset?\n");
3080 abort (); 3270 abort ();
3081 } 3271 }
3082 else if (desc[pos].offset > max_offset) 3272 }
3083 { 3273
3084 max_offset = desc[pos].offset; 3274 if (mark_last_occurred_object)
3085 max_offset_pos = pos; 3275 {
3086 } 3276 /* NOTE: The second parameter isn't even evaluated
3087 } 3277 non-ERROR_CHECK_GC, so it's OK for the variable not to exist.
3088 3278 */
3089 if (max_offset_pos < 0) 3279 mark_object_maybe_checking_free (*last_occurred_object,
3090 return 0; 3280 last_occurred_flags &
3091 3281 XD_FLAG_FREE_LISP_OBJECT);
3092 pos = max_offset_pos; 3282 mark_last_occurred_object = 0;
3093 rdata = (char *) obj + desc[pos].offset; 3283 }
3094 3284 }
3095 switch (desc[pos].type)
3096 {
3097 case XD_LISP_OBJECT_ARRAY:
3098 {
3099 EMACS_INT val = desc[pos].data1;
3100 if (XD_IS_INDIRECT (val))
3101 val = get_indirect_count (val, desc, obj);
3102 size_at_max = val * sizeof (Lisp_Object);
3103 break;
3104 }
3105 case XD_LISP_OBJECT:
3106 case XD_LO_LINK:
3107 size_at_max = sizeof (Lisp_Object);
3108 break;
3109 case XD_OPAQUE_PTR:
3110 size_at_max = sizeof (void *);
3111 break;
3112 case XD_STRUCT_PTR:
3113 {
3114 EMACS_INT val = desc[pos].data1;
3115 if (XD_IS_INDIRECT (val))
3116 val = get_indirect_count (val, desc, obj);
3117 size_at_max = val * sizeof (void *);
3118 break;
3119 }
3120 break;
3121 case XD_STRUCT_ARRAY:
3122 {
3123 EMACS_INT val = desc[pos].data1;
3124
3125 if (XD_IS_INDIRECT (val))
3126 val = get_indirect_count (val, desc, obj);
3127
3128 size_at_max = val * structure_size (rdata, desc[pos].data2);
3129 break;
3130 }
3131 break;
3132 case XD_OPAQUE_DATA_PTR:
3133 size_at_max = sizeof (void *);
3134 break;
3135 case XD_UNION:
3136 abort ();
3137 break;
3138 case XD_C_STRING:
3139 size_at_max = sizeof (void *);
3140 break;
3141 case XD_DOC_STRING:
3142 size_at_max = sizeof (void *);
3143 break;
3144 case XD_INT_RESET:
3145 size_at_max = sizeof (int);
3146 break;
3147 case XD_BYTECOUNT:
3148 size_at_max = sizeof (Bytecount);
3149 break;
3150 case XD_ELEMCOUNT:
3151 size_at_max = sizeof (Elemcount);
3152 break;
3153 case XD_HASHCODE:
3154 size_at_max = sizeof (Hashcode);
3155 break;
3156 case XD_INT:
3157 size_at_max = sizeof (int);
3158 break;
3159 case XD_LONG:
3160 size_at_max = sizeof (long);
3161 break;
3162 case XD_SPECIFIER_END:
3163 case XD_CODING_SYSTEM_END:
3164 stderr_out
3165 ("Should not be seeing XD_SPECIFIER_END or\n"
3166 "XD_CODING_SYSTEM_END outside of struct Lisp_Specifier\n"
3167 "and struct Lisp_Coding_System.\n");
3168 abort ();
3169 default:
3170 stderr_out ("Unsupported dump type : %d\n", desc[pos].type);
3171 abort ();
3172 }
3173
3174 return ALIGN_SIZE (max_offset + size_at_max, ALIGNOF (max_align_t));
3175 }
3176
3177 3285
3178 /* This function loops all elements of a struct pointer and calls 3286 /* This function loops all elements of a struct pointer and calls
3179 mark_with_description with each element. */ 3287 mark_with_description with each element. */
3180 static void 3288 static void
3181 mark_struct_contents (const void *data, 3289 mark_struct_contents (const void *data,
3182 const struct struct_description *sdesc, 3290 const struct sized_memory_description *sdesc,
3183 int count) 3291 int count)
3184 { 3292 {
3185 int i; 3293 int i;
3186 Bytecount elsize; 3294 Bytecount elsize;
3187 elsize = structure_size (data, sdesc); 3295 elsize = lispdesc_structure_size (data, sdesc);
3188 3296
3189 for (i = 0; i < count; i++) 3297 for (i = 0; i < count; i++)
3190 { 3298 {
3191 mark_with_description (((char *) data) + elsize * i, 3299 mark_with_description (((char *) data) + elsize * i,
3192 sdesc->description); 3300 sdesc->description);
3209 /* if (PURIFIED (XPNTR (obj))) return; */ 3317 /* if (PURIFIED (XPNTR (obj))) return; */
3210 3318
3211 if (XTYPE (obj) == Lisp_Type_Record) 3319 if (XTYPE (obj) == Lisp_Type_Record)
3212 { 3320 {
3213 struct lrecord_header *lheader = XRECORD_LHEADER (obj); 3321 struct lrecord_header *lheader = XRECORD_LHEADER (obj);
3214 #ifdef USE_KKCC
3215 const struct lrecord_implementation *imp;
3216 const struct lrecord_description *desc;
3217 #endif /* USE_KKCC */
3218 3322
3219 GC_CHECK_LHEADER_INVARIANTS (lheader); 3323 GC_CHECK_LHEADER_INVARIANTS (lheader);
3220 3324
3325 #ifndef USE_KKCC
3326 /* We handle this separately, above, so we can mark free objects */
3221 gc_checking_assert (LHEADER_IMPLEMENTATION (lheader)->basic_p || 3327 gc_checking_assert (LHEADER_IMPLEMENTATION (lheader)->basic_p ||
3222 ! ((struct lcrecord_header *) lheader)->free); 3328 ! ((struct lcrecord_header *) lheader)->free);
3329 #endif /* not USE_KKCC */
3330
3223 3331
3224 /* All c_readonly objects have their mark bit set, 3332 /* All c_readonly objects have their mark bit set,
3225 so that we only need to check the mark bit here. */ 3333 so that we only need to check the mark bit here. */
3226 if (! MARKED_RECORD_HEADER_P (lheader)) 3334 if (! MARKED_RECORD_HEADER_P (lheader))
3227 { 3335 {
3228 MARK_RECORD_HEADER (lheader); 3336 MARK_RECORD_HEADER (lheader);
3229 3337
3338 {
3230 #ifdef USE_KKCC 3339 #ifdef USE_KKCC
3231 imp = LHEADER_IMPLEMENTATION (lheader); 3340 const struct lrecord_implementation *imp;
3232 desc = imp->description; 3341 const struct memory_description *desc;
3342
3343 imp = LHEADER_IMPLEMENTATION (lheader);
3344 desc = imp->description;
3233 3345
3234 if (desc) /* && !CONSP(obj))*/ /* KKCC cons special case */ 3346 if (desc) /* && !CONSP(obj))*/ /* KKCC cons special case */
3235 { 3347 {
3236 mark_with_description (lheader, desc); 3348 mark_with_description (lheader, desc);
3237 } 3349 }
3238 3350 else
3239 else
3240 {
3241
3242 #endif /* USE_KKCC */ 3351 #endif /* USE_KKCC */
3243 3352 {
3244 3353 if (RECORD_MARKER (lheader))
3245 if (RECORD_MARKER (lheader)) 3354 {
3246 { 3355 obj = RECORD_MARKER (lheader) (obj);
3247 obj = RECORD_MARKER (lheader) (obj); 3356 if (!NILP (obj)) goto tail_recurse;
3248 if (!NILP (obj)) goto tail_recurse; 3357 }
3249 } 3358 }
3250 3359 }
3251 #ifdef USE_KKCC
3252 }
3253 #endif /* USE_KKCC */
3254 } 3360 }
3255 } 3361 }
3256 }
3257
3258 /* mark all of the conses in a list and mark the final cdr; but
3259 DO NOT mark the cars.
3260
3261 Use only for internal lists! There should never be other pointers
3262 to the cons cells, because if so, the cars will remain unmarked
3263 even when they maybe should be marked. */
3264 void
3265 mark_conses_in_list (Lisp_Object obj)
3266 {
3267 Lisp_Object rest;
3268
3269 for (rest = obj; CONSP (rest); rest = XCDR (rest))
3270 {
3271 if (CONS_MARKED_P (XCONS (rest)))
3272 return;
3273 MARK_CONS (XCONS (rest));
3274 }
3275
3276 mark_object (rest);
3277 } 3362 }
3278 3363
3279 3364
3280 /* Find all structures not marked, and free them. */ 3365 /* Find all structures not marked, and free them. */
3281 3366
3282 static int gc_count_num_bit_vector_used, gc_count_bit_vector_total_size;
3283 static int gc_count_bit_vector_storage;
3284 static int gc_count_num_short_string_in_use; 3367 static int gc_count_num_short_string_in_use;
3285 static Bytecount gc_count_string_total_size; 3368 static Bytecount gc_count_string_total_size;
3286 static Bytecount gc_count_short_string_total_size; 3369 static Bytecount gc_count_short_string_total_size;
3287 3370
3288 /* static int gc_count_total_records_used, gc_count_records_total_size; */ 3371 /* static int gc_count_total_records_used, gc_count_records_total_size; */
3310 gc_checking_assert (!free_p); 3393 gc_checking_assert (!free_p);
3311 lcrecord_stats[type_index].instances_on_free_list++; 3394 lcrecord_stats[type_index].instances_on_free_list++;
3312 } 3395 }
3313 else 3396 else
3314 { 3397 {
3315 const struct lrecord_implementation *implementation = 3398 Bytecount sz = detagged_lisp_object_size (h);
3316 LHEADER_IMPLEMENTATION (h); 3399
3317
3318 Bytecount sz = (implementation->size_in_bytes_method ?
3319 implementation->size_in_bytes_method (h) :
3320 implementation->static_size);
3321 if (free_p) 3400 if (free_p)
3322 { 3401 {
3323 lcrecord_stats[type_index].instances_freed++; 3402 lcrecord_stats[type_index].instances_freed++;
3324 lcrecord_stats[type_index].bytes_freed += sz; 3403 lcrecord_stats[type_index].bytes_freed += sz;
3325 } 3404 }
3389 header = next; 3468 header = next;
3390 } 3469 }
3391 } 3470 }
3392 *used = num_used; 3471 *used = num_used;
3393 /* *total = total_size; */ 3472 /* *total = total_size; */
3394 }
3395
3396
3397 static void
3398 sweep_bit_vectors_1 (Lisp_Object *prev,
3399 int *used, int *total, int *storage)
3400 {
3401 Lisp_Object bit_vector;
3402 int num_used = 0;
3403 int total_size = 0;
3404 int total_storage = 0;
3405
3406 /* BIT_VECTORP fails because the objects are marked, which changes
3407 their implementation */
3408 for (bit_vector = *prev; !EQ (bit_vector, Qzero); )
3409 {
3410 Lisp_Bit_Vector *v = XBIT_VECTOR (bit_vector);
3411 int len = v->size;
3412 if (MARKED_RECORD_P (bit_vector))
3413 {
3414 if (! C_READONLY_RECORD_HEADER_P(&(v->lheader)))
3415 UNMARK_RECORD_HEADER (&(v->lheader));
3416 total_size += len;
3417 total_storage +=
3418 MALLOC_OVERHEAD +
3419 FLEXIBLE_ARRAY_STRUCT_SIZEOF (Lisp_Bit_Vector, unsigned long,
3420 bits, BIT_VECTOR_LONG_STORAGE (len));
3421 num_used++;
3422 /* #### May modify next on a C_READONLY bitvector */
3423 prev = &(bit_vector_next (v));
3424 bit_vector = *prev;
3425 }
3426 else
3427 {
3428 Lisp_Object next = bit_vector_next (v);
3429 *prev = next;
3430 xfree (v);
3431 bit_vector = next;
3432 }
3433 }
3434 *used = num_used;
3435 *total = total_size;
3436 *storage = total_storage;
3437 } 3473 }
3438 3474
3439 /* And the Lord said: Thou shalt use the `c-backslash-region' command 3475 /* And the Lord said: Thou shalt use the `c-backslash-region' command
3440 to make macros prettier. */ 3476 to make macros prettier. */
3441 3477
3592 /* If the CAR is not an int, then it will be a pointer, which will 3628 /* If the CAR is not an int, then it will be a pointer, which will
3593 always be four-byte aligned. If this cons cell has already been 3629 always be four-byte aligned. If this cons cell has already been
3594 placed on the free list, however, its car will probably contain 3630 placed on the free list, however, its car will probably contain
3595 a chain pointer to the next cons on the list, which has cleverly 3631 a chain pointer to the next cons on the list, which has cleverly
3596 had all its 0's and 1's inverted. This allows for a quick 3632 had all its 0's and 1's inverted. This allows for a quick
3597 check to make sure we're not freeing something already freed. */ 3633 check to make sure we're not freeing something already freed.
3634
3635 NOTE: This check may not be necessary. Freeing an object sets its
3636 type to lrecord_type_free, which will trip up the XCONS() above -- as
3637 well as a check in FREE_FIXED_TYPE(). */
3598 if (POINTER_TYPE_P (XTYPE (cons_car (ptr)))) 3638 if (POINTER_TYPE_P (XTYPE (cons_car (ptr))))
3599 ASSERT_VALID_POINTER (XPNTR (cons_car (ptr))); 3639 ASSERT_VALID_POINTER (XPNTR (cons_car (ptr)));
3600 #endif /* ERROR_CHECK_GC */ 3640 #endif /* ERROR_CHECK_GC */
3601 3641
3602 #ifndef ALLOC_NO_POOLS
3603 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (cons, Lisp_Cons, ptr); 3642 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (cons, Lisp_Cons, ptr);
3604 #endif /* ALLOC_NO_POOLS */
3605 } 3643 }
3606 3644
3607 /* explicitly free a list. You **must make sure** that you have 3645 /* explicitly free a list. You **must make sure** that you have
3608 created all the cons cells that make up this list and that there 3646 created all the cons cells that make up this list and that there
3609 are no pointers to any of these cons cells anywhere else. If there 3647 are no pointers to any of these cons cells anywhere else. If there
3683 #define ADDITIONAL_FREE_event(ptr) 3721 #define ADDITIONAL_FREE_event(ptr)
3684 3722
3685 SWEEP_FIXED_TYPE_BLOCK (event, Lisp_Event); 3723 SWEEP_FIXED_TYPE_BLOCK (event, Lisp_Event);
3686 } 3724 }
3687 3725
3688 #ifdef USE_KKCC 3726 #ifdef EVENT_DATA_AS_OBJECTS
3689 3727
3690 static void 3728 static void
3691 sweep_key_data (void) 3729 sweep_key_data (void)
3692 { 3730 {
3693 #define UNMARK_key_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3731 #define UNMARK_key_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3694 #define ADDITIONAL_FREE_key_data(ptr) 3732 #define ADDITIONAL_FREE_key_data(ptr)
3695 3733
3696 SWEEP_FIXED_TYPE_BLOCK (key_data, Lisp_Key_Data); 3734 SWEEP_FIXED_TYPE_BLOCK (key_data, Lisp_Key_Data);
3697 } 3735 }
3698 3736
3737 void
3738 free_key_data (Lisp_Object ptr)
3739 {
3740 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (key_data, Lisp_Key_Data, XKEY_DATA (ptr));
3741 }
3742
3699 static void 3743 static void
3700 sweep_button_data (void) 3744 sweep_button_data (void)
3701 { 3745 {
3702 #define UNMARK_button_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3746 #define UNMARK_button_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3703 #define ADDITIONAL_FREE_button_data(ptr) 3747 #define ADDITIONAL_FREE_button_data(ptr)
3704 3748
3705 SWEEP_FIXED_TYPE_BLOCK (button_data, Lisp_Button_Data); 3749 SWEEP_FIXED_TYPE_BLOCK (button_data, Lisp_Button_Data);
3706 } 3750 }
3707 3751
3752 void
3753 free_button_data (Lisp_Object ptr)
3754 {
3755 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (button_data, Lisp_Button_Data, XBUTTON_DATA (ptr));
3756 }
3757
3708 static void 3758 static void
3709 sweep_motion_data (void) 3759 sweep_motion_data (void)
3710 { 3760 {
3711 #define UNMARK_motion_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3761 #define UNMARK_motion_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3712 #define ADDITIONAL_FREE_motion_data(ptr) 3762 #define ADDITIONAL_FREE_motion_data(ptr)
3713 3763
3714 SWEEP_FIXED_TYPE_BLOCK (motion_data, Lisp_Motion_Data); 3764 SWEEP_FIXED_TYPE_BLOCK (motion_data, Lisp_Motion_Data);
3715 } 3765 }
3716 3766
3767 void
3768 free_motion_data (Lisp_Object ptr)
3769 {
3770 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (motion_data, Lisp_Motion_Data, XMOTION_DATA (ptr));
3771 }
3772
3717 static void 3773 static void
3718 sweep_process_data (void) 3774 sweep_process_data (void)
3719 { 3775 {
3720 #define UNMARK_process_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3776 #define UNMARK_process_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3721 #define ADDITIONAL_FREE_process_data(ptr) 3777 #define ADDITIONAL_FREE_process_data(ptr)
3722 3778
3723 SWEEP_FIXED_TYPE_BLOCK (process_data, Lisp_Process_Data); 3779 SWEEP_FIXED_TYPE_BLOCK (process_data, Lisp_Process_Data);
3724 } 3780 }
3725 3781
3782 void
3783 free_process_data (Lisp_Object ptr)
3784 {
3785 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (process_data, Lisp_Process_Data, XPROCESS_DATA (ptr));
3786 }
3787
3726 static void 3788 static void
3727 sweep_timeout_data (void) 3789 sweep_timeout_data (void)
3728 { 3790 {
3729 #define UNMARK_timeout_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3791 #define UNMARK_timeout_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3730 #define ADDITIONAL_FREE_timeout_data(ptr) 3792 #define ADDITIONAL_FREE_timeout_data(ptr)
3731 3793
3732 SWEEP_FIXED_TYPE_BLOCK (timeout_data, Lisp_Timeout_Data); 3794 SWEEP_FIXED_TYPE_BLOCK (timeout_data, Lisp_Timeout_Data);
3733 } 3795 }
3734 3796
3797 void
3798 free_timeout_data (Lisp_Object ptr)
3799 {
3800 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (timeout_data, Lisp_Timeout_Data, XTIMEOUT_DATA (ptr));
3801 }
3802
3735 static void 3803 static void
3736 sweep_magic_data (void) 3804 sweep_magic_data (void)
3737 { 3805 {
3738 #define UNMARK_magic_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3806 #define UNMARK_magic_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3739 #define ADDITIONAL_FREE_magic_data(ptr) 3807 #define ADDITIONAL_FREE_magic_data(ptr)
3740 3808
3741 SWEEP_FIXED_TYPE_BLOCK (magic_data, Lisp_Magic_Data); 3809 SWEEP_FIXED_TYPE_BLOCK (magic_data, Lisp_Magic_Data);
3742 } 3810 }
3743 3811
3812 void
3813 free_magic_data (Lisp_Object ptr)
3814 {
3815 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (magic_data, Lisp_Magic_Data, XMAGIC_DATA (ptr));
3816 }
3817
3744 static void 3818 static void
3745 sweep_magic_eval_data (void) 3819 sweep_magic_eval_data (void)
3746 { 3820 {
3747 #define UNMARK_magic_eval_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3821 #define UNMARK_magic_eval_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3748 #define ADDITIONAL_FREE_magic_eval_data(ptr) 3822 #define ADDITIONAL_FREE_magic_eval_data(ptr)
3749 3823
3750 SWEEP_FIXED_TYPE_BLOCK (magic_eval_data, Lisp_Magic_Eval_Data); 3824 SWEEP_FIXED_TYPE_BLOCK (magic_eval_data, Lisp_Magic_Eval_Data);
3751 } 3825 }
3752 3826
3827 void
3828 free_magic_eval_data (Lisp_Object ptr)
3829 {
3830 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (magic_eval_data, Lisp_Magic_Eval_Data, XMAGIC_EVAL_DATA (ptr));
3831 }
3832
3753 static void 3833 static void
3754 sweep_eval_data (void) 3834 sweep_eval_data (void)
3755 { 3835 {
3756 #define UNMARK_eval_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3836 #define UNMARK_eval_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3757 #define ADDITIONAL_FREE_eval_data(ptr) 3837 #define ADDITIONAL_FREE_eval_data(ptr)
3758 3838
3759 SWEEP_FIXED_TYPE_BLOCK (eval_data, Lisp_Eval_Data); 3839 SWEEP_FIXED_TYPE_BLOCK (eval_data, Lisp_Eval_Data);
3760 } 3840 }
3761 3841
3842 void
3843 free_eval_data (Lisp_Object ptr)
3844 {
3845 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (eval_data, Lisp_Eval_Data, XEVAL_DATA (ptr));
3846 }
3847
3762 static void 3848 static void
3763 sweep_misc_user_data (void) 3849 sweep_misc_user_data (void)
3764 { 3850 {
3765 #define UNMARK_misc_user_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3851 #define UNMARK_misc_user_data(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3766 #define ADDITIONAL_FREE_misc_user_data(ptr) 3852 #define ADDITIONAL_FREE_misc_user_data(ptr)
3767 3853
3768 SWEEP_FIXED_TYPE_BLOCK (misc_user_data, Lisp_Misc_User_Data); 3854 SWEEP_FIXED_TYPE_BLOCK (misc_user_data, Lisp_Misc_User_Data);
3769 } 3855 }
3770 3856
3771 #endif /* USE_KKCC */ 3857 void
3858 free_misc_user_data (Lisp_Object ptr)
3859 {
3860 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (misc_user_data, Lisp_Misc_User_Data, XMISC_USER_DATA (ptr));
3861 }
3862
3863 #endif /* EVENT_DATA_AS_OBJECTS */
3772 3864
3773 static void 3865 static void
3774 sweep_markers (void) 3866 sweep_markers (void)
3775 { 3867 {
3776 #define UNMARK_marker(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader)) 3868 #define UNMARK_marker(ptr) UNMARK_RECORD_HEADER (&((ptr)->lheader))
3783 SWEEP_FIXED_TYPE_BLOCK (marker, Lisp_Marker); 3875 SWEEP_FIXED_TYPE_BLOCK (marker, Lisp_Marker);
3784 } 3876 }
3785 3877
3786 /* Explicitly free a marker. */ 3878 /* Explicitly free a marker. */
3787 void 3879 void
3788 free_marker (Lisp_Marker *ptr) 3880 free_marker (Lisp_Object ptr)
3789 { 3881 {
3790 /* Perhaps this will catch freeing an already-freed marker. */ 3882 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (marker, Lisp_Marker, XMARKER (ptr));
3791 gc_checking_assert (ptr->lheader.type == lrecord_type_marker);
3792
3793 #ifndef ALLOC_NO_POOLS
3794 FREE_FIXED_TYPE_WHEN_NOT_IN_GC (marker, Lisp_Marker, ptr);
3795 #endif /* ALLOC_NO_POOLS */
3796 } 3883 }
3797 3884
3798 3885
3799 #if defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY) 3886 #if defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY)
3800 3887
3840 } 3927 }
3841 assert (pos == sb->pos); 3928 assert (pos == sb->pos);
3842 } 3929 }
3843 } 3930 }
3844 3931
3845 #endif /* MULE && ERROR_CHECK_GC */ 3932 #endif /* defined (MULE) && defined (VERIFY_STRING_CHARS_INTEGRITY) */
3846 3933
3847 /* Compactify string chars, relocating the reference to each -- 3934 /* Compactify string chars, relocating the reference to each --
3848 free any empty string_chars_block we see. */ 3935 free any empty string_chars_block we see. */
3849 static void 3936 static void
3850 compact_string_chars (void) 3937 compact_string_chars (void)
3882 from_pos += fullsize; 3969 from_pos += fullsize;
3883 continue; 3970 continue;
3884 } 3971 }
3885 3972
3886 string = from_s_chars->string; 3973 string = from_s_chars->string;
3887 assert (!(LRECORD_FREE_P (string))); 3974 gc_checking_assert (!(LRECORD_FREE_P (string)));
3888 3975
3889 size = string->size_; 3976 size = string->size_;
3890 fullsize = STRING_FULLSIZE (size); 3977 fullsize = STRING_FULLSIZE (size);
3891 3978
3892 gc_checking_assert (! BIG_STRING_FULLSIZE_P (fullsize)); 3979 gc_checking_assert (! BIG_STRING_FULLSIZE_P (fullsize));
4052 sweep_strings (); 4139 sweep_strings ();
4053 4140
4054 /* Put all unmarked conses on free list */ 4141 /* Put all unmarked conses on free list */
4055 sweep_conses (); 4142 sweep_conses ();
4056 4143
4057 /* Free all unmarked bit vectors */
4058 sweep_bit_vectors_1 (&all_bit_vectors,
4059 &gc_count_num_bit_vector_used,
4060 &gc_count_bit_vector_total_size,
4061 &gc_count_bit_vector_storage);
4062
4063 /* Free all unmarked compiled-function objects */ 4144 /* Free all unmarked compiled-function objects */
4064 sweep_compiled_functions (); 4145 sweep_compiled_functions ();
4065 4146
4066 /* Put all unmarked floats on free list */ 4147 /* Put all unmarked floats on free list */
4067 sweep_floats (); 4148 sweep_floats ();
4076 Dechain each one first from the buffer into which it points. */ 4157 Dechain each one first from the buffer into which it points. */
4077 sweep_markers (); 4158 sweep_markers ();
4078 4159
4079 sweep_events (); 4160 sweep_events ();
4080 4161
4081 #ifdef USE_KKCC 4162 #ifdef EVENT_DATA_AS_OBJECTS
4082 sweep_key_data (); 4163 sweep_key_data ();
4083 sweep_button_data (); 4164 sweep_button_data ();
4084 sweep_motion_data (); 4165 sweep_motion_data ();
4085 sweep_process_data (); 4166 sweep_process_data ();
4086 sweep_timeout_data (); 4167 sweep_timeout_data ();
4087 sweep_magic_data (); 4168 sweep_magic_data ();
4088 sweep_magic_eval_data (); 4169 sweep_magic_eval_data ();
4089 sweep_eval_data (); 4170 sweep_eval_data ();
4090 sweep_misc_user_data (); 4171 sweep_misc_user_data ();
4091 #endif /* USE_KKCC */ 4172 #endif /* EVENT_DATA_AS_OBJECTS */
4092 4173
4093 #ifdef PDUMP 4174 #ifdef PDUMP
4094 pdump_objects_unmark (); 4175 pdump_objects_unmark ();
4095 #endif 4176 #endif
4096 } 4177 }
4354 4435
4355 /* Do some totally ad-hoc resource clearing. */ 4436 /* Do some totally ad-hoc resource clearing. */
4356 /* #### generalize this? */ 4437 /* #### generalize this? */
4357 clear_event_resource (); 4438 clear_event_resource ();
4358 cleanup_specifiers (); 4439 cleanup_specifiers ();
4440 cleanup_buffer_undo_lists ();
4359 4441
4360 /* Mark all the special slots that serve as the roots of accessibility. */ 4442 /* Mark all the special slots that serve as the roots of accessibility. */
4361 4443
4362 { /* staticpro() */ 4444 { /* staticpro() */
4363 Lisp_Object **p = Dynarr_begin (staticpros); 4445 Lisp_Object **p = Dynarr_begin (staticpros);
4605 pl = gc_plist_hack ("compiled-functions-free", 4687 pl = gc_plist_hack ("compiled-functions-free",
4606 gc_count_num_compiled_function_freelist, pl); 4688 gc_count_num_compiled_function_freelist, pl);
4607 pl = gc_plist_hack ("compiled-functions-used", 4689 pl = gc_plist_hack ("compiled-functions-used",
4608 gc_count_num_compiled_function_in_use, pl); 4690 gc_count_num_compiled_function_in_use, pl);
4609 4691
4610 pl = gc_plist_hack ("bit-vector-storage", gc_count_bit_vector_storage, pl);
4611 pl = gc_plist_hack ("bit-vectors-total-length",
4612 gc_count_bit_vector_total_size, pl);
4613 pl = gc_plist_hack ("bit-vectors-used", gc_count_num_bit_vector_used, pl);
4614
4615 HACK_O_MATIC (symbol, "symbol-storage", pl); 4692 HACK_O_MATIC (symbol, "symbol-storage", pl);
4616 pl = gc_plist_hack ("symbols-free", gc_count_num_symbol_freelist, pl); 4693 pl = gc_plist_hack ("symbols-free", gc_count_num_symbol_freelist, pl);
4617 pl = gc_plist_hack ("symbols-used", gc_count_num_symbol_in_use, pl); 4694 pl = gc_plist_hack ("symbols-used", gc_count_num_symbol_in_use, pl);
4618 4695
4619 HACK_O_MATIC (cons, "cons-storage", pl); 4696 HACK_O_MATIC (cons, "cons-storage", pl);
4843 #endif /* MEMORY_USAGE_STATS */ 4920 #endif /* MEMORY_USAGE_STATS */
4844 4921
4845 4922
4846 /* Initialization */ 4923 /* Initialization */
4847 static void 4924 static void
4848 common_init_alloc_once_early (void) 4925 common_init_alloc_early (void)
4849 { 4926 {
4850 #ifndef Qzero 4927 #ifndef Qzero
4851 Qzero = make_int (0); /* Only used if Lisp_Object is a union type */ 4928 Qzero = make_int (0); /* Only used if Lisp_Object is a union type */
4852 #endif 4929 #endif
4853 4930
4857 Qnull_pointer = wrap_pointer_1 (0); 4934 Qnull_pointer = wrap_pointer_1 (0);
4858 #endif 4935 #endif
4859 4936
4860 gc_generation_number[0] = 0; 4937 gc_generation_number[0] = 0;
4861 breathing_space = 0; 4938 breathing_space = 0;
4862 all_bit_vectors = Qzero;
4863 Vgc_message = Qzero; 4939 Vgc_message = Qzero;
4864 all_lcrecords = 0; 4940 all_lcrecords = 0;
4865 ignore_malloc_warnings = 1; 4941 ignore_malloc_warnings = 1;
4866 #ifdef DOUG_LEA_MALLOC 4942 #ifdef DOUG_LEA_MALLOC
4867 mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */ 4943 mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */
4877 init_compiled_function_alloc (); 4953 init_compiled_function_alloc ();
4878 init_float_alloc (); 4954 init_float_alloc ();
4879 init_marker_alloc (); 4955 init_marker_alloc ();
4880 init_extent_alloc (); 4956 init_extent_alloc ();
4881 init_event_alloc (); 4957 init_event_alloc ();
4882 #ifdef USE_KKCC 4958 #ifdef EVENT_DATA_AS_OBJECTS
4883 init_key_data_alloc (); 4959 init_key_data_alloc ();
4884 init_button_data_alloc (); 4960 init_button_data_alloc ();
4885 init_motion_data_alloc (); 4961 init_motion_data_alloc ();
4886 init_process_data_alloc (); 4962 init_process_data_alloc ();
4887 init_timeout_data_alloc (); 4963 init_timeout_data_alloc ();
4888 init_magic_data_alloc (); 4964 init_magic_data_alloc ();
4889 init_magic_eval_data_alloc (); 4965 init_magic_eval_data_alloc ();
4890 init_eval_data_alloc (); 4966 init_eval_data_alloc ();
4891 init_misc_user_data_alloc (); 4967 init_misc_user_data_alloc ();
4892 #endif /* USE_KKCC */ 4968 #endif /* EVENT_DATA_AS_OBJECTS */
4893 4969
4894 ignore_malloc_warnings = 0; 4970 ignore_malloc_warnings = 0;
4895 4971
4896 if (staticpros_nodump) 4972 if (staticpros_nodump)
4897 Dynarr_free (staticpros_nodump); 4973 Dynarr_free (staticpros_nodump);
4918 gc_cons_percentage = 0; /* #### 20; Don't have an accurate measure of 4994 gc_cons_percentage = 0; /* #### 20; Don't have an accurate measure of
4919 memory usage on Windows; not verified on other 4995 memory usage on Windows; not verified on other
4920 systems */ 4996 systems */
4921 lrecord_uid_counter = 259; 4997 lrecord_uid_counter = 259;
4922 debug_string_purity = 0; 4998 debug_string_purity = 0;
4923 gcprolist = 0;
4924 4999
4925 gc_currently_forbidden = 0; 5000 gc_currently_forbidden = 0;
4926 gc_hooks_inhibited = 0; 5001 gc_hooks_inhibited = 0;
4927 5002
4928 #ifdef ERROR_CHECK_TYPES 5003 #ifdef ERROR_CHECK_TYPES
4950 staticpro_nodump (&all_lcrecord_lists[i]); 5025 staticpro_nodump (&all_lcrecord_lists[i]);
4951 } 5026 }
4952 } 5027 }
4953 5028
4954 void 5029 void
4955 reinit_alloc_once_early (void) 5030 init_alloc_early (void)
4956 { 5031 {
4957 common_init_alloc_once_early (); 5032 #if defined (__cplusplus) && defined (ERROR_CHECK_GC)
5033 static struct gcpro initial_gcpro;
5034
5035 initial_gcpro.next = 0;
5036 initial_gcpro.var = &Qnil;
5037 initial_gcpro.nvars = 1;
5038 gcprolist = &initial_gcpro;
5039 #else
5040 gcprolist = 0;
5041 #endif /* defined (__cplusplus) && defined (ERROR_CHECK_GC) */
5042 }
5043
5044 void
5045 reinit_alloc_early (void)
5046 {
5047 common_init_alloc_early ();
4958 init_lcrecord_lists (); 5048 init_lcrecord_lists ();
4959 } 5049 }
4960 5050
4961 void 5051 void
4962 init_alloc_once_early (void) 5052 init_alloc_once_early (void)
4963 { 5053 {
4964 common_init_alloc_once_early (); 5054 common_init_alloc_early ();
4965 5055
4966 { 5056 {
4967 int i; 5057 int i;
4968 for (i = 0; i < countof (lrecord_implementations_table); i++) 5058 for (i = 0; i < countof (lrecord_implementations_table); i++)
4969 lrecord_implementations_table[i] = 0; 5059 lrecord_implementations_table[i] = 0;
4971 5061
4972 INIT_LRECORD_IMPLEMENTATION (cons); 5062 INIT_LRECORD_IMPLEMENTATION (cons);
4973 INIT_LRECORD_IMPLEMENTATION (vector); 5063 INIT_LRECORD_IMPLEMENTATION (vector);
4974 INIT_LRECORD_IMPLEMENTATION (string); 5064 INIT_LRECORD_IMPLEMENTATION (string);
4975 INIT_LRECORD_IMPLEMENTATION (lcrecord_list); 5065 INIT_LRECORD_IMPLEMENTATION (lcrecord_list);
5066 INIT_LRECORD_IMPLEMENTATION (free);
4976 5067
4977 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *); 5068 staticpros = Dynarr_new2 (Lisp_Object_ptr_dynarr, Lisp_Object *);
4978 Dynarr_resize (staticpros, 1410); /* merely a small optimization */ 5069 Dynarr_resize (staticpros, 1410); /* merely a small optimization */
4979 dump_add_root_struct_ptr (&staticpros, &staticpros_description); 5070 dump_add_root_struct_ptr (&staticpros, &staticpros_description);
4980 #ifdef DEBUG_XEMACS 5071 #ifdef DEBUG_XEMACS
4982 Dynarr_resize (staticpro_names, 1410); /* merely a small optimization */ 5073 Dynarr_resize (staticpro_names, 1410); /* merely a small optimization */
4983 dump_add_root_struct_ptr (&staticpro_names, &staticpro_names_description); 5074 dump_add_root_struct_ptr (&staticpro_names, &staticpro_names_description);
4984 #endif 5075 #endif
4985 5076
4986 init_lcrecord_lists (); 5077 init_lcrecord_lists ();
4987 }
4988
4989 void
4990 init_alloc_early (void)
4991 {
4992 gcprolist = 0;
4993 } 5078 }
4994 5079
4995 void 5080 void
4996 syms_of_alloc (void) 5081 syms_of_alloc (void)
4997 { 5082 {