comparison src/elhash.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 37bdd24225ef
children f3437b56874d
comparison
equal deleted inserted replaced
1203:5f2f8dcbfb3e 1204:e22b0213b713
71 71
72 /* obsolete as of 19990901 in xemacs-21.2 */ 72 /* obsolete as of 19990901 in xemacs-21.2 */
73 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak; 73 static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qkey_or_value_weak;
74 static Lisp_Object Qnon_weak, Q_type; 74 static Lisp_Object Qnon_weak, Q_type;
75 75
76 typedef struct hentry 76 typedef struct htentry
77 { 77 {
78 Lisp_Object key; 78 Lisp_Object key;
79 Lisp_Object value; 79 Lisp_Object value;
80 } hentry; 80 } htentry;
81 81
82 struct Lisp_Hash_Table 82 struct Lisp_Hash_Table
83 { 83 {
84 struct lcrecord_header header; 84 struct lcrecord_header header;
85 Elemcount size; 85 Elemcount size;
88 double rehash_size; 88 double rehash_size;
89 double rehash_threshold; 89 double rehash_threshold;
90 Elemcount golden_ratio; 90 Elemcount golden_ratio;
91 hash_table_hash_function_t hash_function; 91 hash_table_hash_function_t hash_function;
92 hash_table_test_function_t test_function; 92 hash_table_test_function_t test_function;
93 hentry *hentries; 93 htentry *hentries;
94 enum hash_table_weakness weakness; 94 enum hash_table_weakness weakness;
95 Lisp_Object next_weak; /* Used to chain together all of the weak 95 Lisp_Object next_weak; /* Used to chain together all of the weak
96 hash tables. Don't mark through this. */ 96 hash tables. Don't mark through this. */
97 }; 97 };
98 98
99 #define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0) 99 #define HTENTRY_CLEAR_P(htentry) ((*(EMACS_UINT*)(&((htentry)->key))) == 0)
100 #define CLEAR_HENTRY(hentry) \ 100 #define CLEAR_HTENTRY(htentry) \
101 ((*(EMACS_UINT*)(&((hentry)->key))) = 0, \ 101 ((*(EMACS_UINT*)(&((htentry)->key))) = 0, \
102 (*(EMACS_UINT*)(&((hentry)->value))) = 0) 102 (*(EMACS_UINT*)(&((htentry)->value))) = 0)
103 103
104 #define HASH_TABLE_DEFAULT_SIZE 16 104 #define HASH_TABLE_DEFAULT_SIZE 16
105 #define HASH_TABLE_DEFAULT_REHASH_SIZE 1.3 105 #define HASH_TABLE_DEFAULT_REHASH_SIZE 1.3
106 #define HASH_TABLE_MIN_SIZE 10 106 #define HASH_TABLE_MIN_SIZE 10
107 107
113 #define KEYS_EQUAL_P(key1, key2, testfun) \ 113 #define KEYS_EQUAL_P(key1, key2, testfun) \
114 (EQ (key1, key2) || ((testfun) && (testfun) (key1, key2))) 114 (EQ (key1, key2) || ((testfun) && (testfun) (key1, key2)))
115 115
116 #define LINEAR_PROBING_LOOP(probe, entries, size) \ 116 #define LINEAR_PROBING_LOOP(probe, entries, size) \
117 for (; \ 117 for (; \
118 !HENTRY_CLEAR_P (probe) || \ 118 !HTENTRY_CLEAR_P (probe) || \
119 (probe == entries + size ? \ 119 (probe == entries + size ? \
120 (probe = entries, !HENTRY_CLEAR_P (probe)) : 0); \ 120 (probe = entries, !HTENTRY_CLEAR_P (probe)) : 0); \
121 probe++) 121 probe++)
122 122
123 #ifdef ERROR_CHECK_STRUCTURES 123 #ifdef ERROR_CHECK_STRUCTURES
124 static void 124 static void
125 check_hash_table_invariants (Lisp_Hash_Table *ht) 125 check_hash_table_invariants (Lisp_Hash_Table *ht)
126 { 126 {
127 assert (ht->count < ht->size); 127 assert (ht->count < ht->size);
128 assert (ht->count <= ht->rehash_count); 128 assert (ht->count <= ht->rehash_count);
129 assert (ht->rehash_count < ht->size); 129 assert (ht->rehash_count < ht->size);
130 assert ((double) ht->count * ht->rehash_threshold - 1 <= (double) ht->rehash_count); 130 assert ((double) ht->count * ht->rehash_threshold - 1 <= (double) ht->rehash_count);
131 assert (HENTRY_CLEAR_P (ht->hentries + ht->size)); 131 assert (HTENTRY_CLEAR_P (ht->hentries + ht->size));
132 } 132 }
133 #else 133 #else
134 #define check_hash_table_invariants(ht) 134 #define check_hash_table_invariants(ht)
135 #endif 135 #endif
136 136
221 /* If the hash table is weak, we don't want to mark the keys and 221 /* If the hash table is weak, we don't want to mark the keys and
222 values (we scan over them after everything else has been marked, 222 values (we scan over them after everything else has been marked,
223 and mark or remove them as necessary). */ 223 and mark or remove them as necessary). */
224 if (ht->weakness == HASH_TABLE_NON_WEAK) 224 if (ht->weakness == HASH_TABLE_NON_WEAK)
225 { 225 {
226 hentry *e, *sentinel; 226 htentry *e, *sentinel;
227 227
228 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 228 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
229 if (!HENTRY_CLEAR_P (e)) 229 if (!HTENTRY_CLEAR_P (e))
230 { 230 {
231 mark_object (e->key); 231 mark_object (e->key);
232 mark_object (e->value); 232 mark_object (e->value);
233 } 233 }
234 } 234 }
248 static int 248 static int
249 hash_table_equal (Lisp_Object hash_table1, Lisp_Object hash_table2, int depth) 249 hash_table_equal (Lisp_Object hash_table1, Lisp_Object hash_table2, int depth)
250 { 250 {
251 Lisp_Hash_Table *ht1 = XHASH_TABLE (hash_table1); 251 Lisp_Hash_Table *ht1 = XHASH_TABLE (hash_table1);
252 Lisp_Hash_Table *ht2 = XHASH_TABLE (hash_table2); 252 Lisp_Hash_Table *ht2 = XHASH_TABLE (hash_table2);
253 hentry *e, *sentinel; 253 htentry *e, *sentinel;
254 254
255 if ((ht1->test_function != ht2->test_function) || 255 if ((ht1->test_function != ht2->test_function) ||
256 (ht1->weakness != ht2->weakness) || 256 (ht1->weakness != ht2->weakness) ||
257 (ht1->count != ht2->count)) 257 (ht1->count != ht2->count))
258 return 0; 258 return 0;
259 259
260 depth++; 260 depth++;
261 261
262 for (e = ht1->hentries, sentinel = e + ht1->size; e < sentinel; e++) 262 for (e = ht1->hentries, sentinel = e + ht1->size; e < sentinel; e++)
263 if (!HENTRY_CLEAR_P (e)) 263 if (!HTENTRY_CLEAR_P (e))
264 /* Look up the key in the other hash table, and compare the values. */ 264 /* Look up the key in the other hash table, and compare the values. */
265 { 265 {
266 Lisp_Object value_in_other = Fgethash (e->key, hash_table2, Qunbound); 266 Lisp_Object value_in_other = Fgethash (e->key, hash_table2, Qunbound);
267 if (UNBOUNDP (value_in_other) || 267 if (UNBOUNDP (value_in_other) ||
268 !internal_equal (e->value, value_in_other, depth)) 268 !internal_equal (e->value, value_in_other, depth))
310 hash table and prints key/value pairs using PRINTCHARFUN. */ 310 hash table and prints key/value pairs using PRINTCHARFUN. */
311 static void 311 static void
312 print_hash_table_data (Lisp_Hash_Table *ht, Lisp_Object printcharfun) 312 print_hash_table_data (Lisp_Hash_Table *ht, Lisp_Object printcharfun)
313 { 313 {
314 int count = 0; 314 int count = 0;
315 hentry *e, *sentinel; 315 htentry *e, *sentinel;
316 316
317 write_c_string (printcharfun, " data ("); 317 write_c_string (printcharfun, " data (");
318 318
319 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 319 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
320 if (!HENTRY_CLEAR_P (e)) 320 if (!HTENTRY_CLEAR_P (e))
321 { 321 {
322 if (count > 0) 322 if (count > 0)
323 write_c_string (printcharfun, " "); 323 write_c_string (printcharfun, " ");
324 if (!print_readably && count > 3) 324 if (!print_readably && count > 3)
325 { 325 {
384 write_fmt_string (printcharfun, " 0x%x>", ht->header.uid); 384 write_fmt_string (printcharfun, " 0x%x>", ht->header.uid);
385 } 385 }
386 } 386 }
387 387
388 static void 388 static void
389 free_hentries (hentry *hentries, size_t size) 389 free_hentries (htentry *hentries, size_t size)
390 { 390 {
391 #ifdef ERROR_CHECK_STRUCTURES 391 #ifdef ERROR_CHECK_STRUCTURES
392 /* Ensure a crash if other code uses the discarded entries afterwards. */ 392 /* Ensure a crash if other code uses the discarded entries afterwards. */
393 hentry *e, *sentinel; 393 htentry *e, *sentinel;
394 394
395 for (e = hentries, sentinel = e + size; e < sentinel; e++) 395 for (e = hentries, sentinel = e + size; e < sentinel; e++)
396 * (unsigned long *) e = 0xdeadbeef; 396 * (unsigned long *) e = 0xdeadbeef; /* -559038737 base 10 */
397 #endif 397 #endif
398 398
399 if (!DUMPEDP (hentries)) 399 if (!DUMPEDP (hentries))
400 xfree (hentries); 400 xfree (hentries);
401 } 401 }
409 free_hentries (ht->hentries, ht->size); 409 free_hentries (ht->hentries, ht->size);
410 ht->hentries = 0; 410 ht->hentries = 0;
411 } 411 }
412 } 412 }
413 413
414 static const struct lrecord_description hentry_description_1[] = { 414 static const struct memory_description htentry_description_1[] = {
415 { XD_LISP_OBJECT, offsetof (hentry, key) }, 415 { XD_LISP_OBJECT, offsetof (htentry, key) },
416 { XD_LISP_OBJECT, offsetof (hentry, value) }, 416 { XD_LISP_OBJECT, offsetof (htentry, value) },
417 { XD_END } 417 { XD_END }
418 }; 418 };
419 419
420 static const struct struct_description hentry_description = { 420 static const struct sized_memory_description htentry_description = {
421 sizeof (hentry), 421 sizeof (htentry),
422 hentry_description_1 422 htentry_description_1
423 }; 423 };
424 424
425 const struct lrecord_description hash_table_description[] = { 425 static const struct memory_description htentry_union_description_1[] = {
426 { XD_ELEMCOUNT, offsetof (Lisp_Hash_Table, size) }, 426 /* Note: XD_INDIRECT in this table refers to the surrounding table,
427 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description }, 427 and so this will work. */
428 { XD_STRUCT_PTR, HASH_TABLE_NON_WEAK, XD_INDIRECT (0, 1),
429 &htentry_description },
430 { XD_STRUCT_PTR, 0, XD_INDIRECT (0, 1), &htentry_description,
431 XD_FLAG_UNION_DEFAULT_ENTRY | XD_FLAG_NO_KKCC },
432 { XD_END }
433 };
434
435 static const struct sized_memory_description htentry_union_description = {
436 sizeof (htentry *),
437 htentry_union_description_1
438 };
439
440 const struct memory_description hash_table_description[] = {
441 { XD_ELEMCOUNT, offsetof (Lisp_Hash_Table, size) },
442 { XD_INT, offsetof (Lisp_Hash_Table, weakness) },
443 { XD_UNION, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT (1, 0),
444 &htentry_union_description },
428 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) }, 445 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) },
429 { XD_END } 446 { XD_END }
430 }; 447 };
431 448
432 #ifdef USE_KKCC
433 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table, 449 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
434 1, /*dumpable-flag*/ 450 1, /*dumpable-flag*/
435 mark_hash_table, print_hash_table, 451 mark_hash_table, print_hash_table,
436 finalize_hash_table, 452 finalize_hash_table,
437 hash_table_equal, hash_table_hash, 453 hash_table_equal, hash_table_hash,
438 hash_table_description, 454 hash_table_description,
439 Lisp_Hash_Table); 455 Lisp_Hash_Table);
440 #else /* not USE_KKCC */
441 DEFINE_LRECORD_IMPLEMENTATION ("hash-table", hash_table,
442 mark_hash_table, print_hash_table,
443 finalize_hash_table,
444 hash_table_equal, hash_table_hash,
445 hash_table_description,
446 Lisp_Hash_Table);
447 #endif /* not USE_KKCC */
448 456
449 static Lisp_Hash_Table * 457 static Lisp_Hash_Table *
450 xhash_table (Lisp_Object hash_table) 458 xhash_table (Lisp_Object hash_table)
451 { 459 {
452 /* #### What's going on here? Why the gc_in_progress check? */ 460 /* #### What's going on here? Why the gc_in_progress check? */
535 + 1.0)); 543 + 1.0));
536 ht->count = 0; 544 ht->count = 0;
537 545
538 compute_hash_table_derived_values (ht); 546 compute_hash_table_derived_values (ht);
539 547
540 /* We leave room for one never-occupied sentinel hentry at the end. */ 548 /* We leave room for one never-occupied sentinel htentry at the end. */
541 ht->hentries = xnew_array_and_zero (hentry, ht->size + 1); 549 ht->hentries = xnew_array_and_zero (htentry, ht->size + 1);
542 550
543 hash_table = wrap_hash_table (ht); 551 hash_table = wrap_hash_table (ht);
544 552
545 if (weakness == HASH_TABLE_NON_WEAK) 553 if (weakness == HASH_TABLE_NON_WEAK)
546 ht->next_weak = Qunbound; 554 ht->next_weak = Qunbound;
626 if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK; 634 if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK;
627 if (EQ (obj, Qkey_or_value_weak)) return HASH_TABLE_KEY_VALUE_WEAK; 635 if (EQ (obj, Qkey_or_value_weak)) return HASH_TABLE_KEY_VALUE_WEAK;
628 if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK; 636 if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK;
629 637
630 invalid_constant ("Invalid hash table weakness", obj); 638 invalid_constant ("Invalid hash table weakness", obj);
631 RETURN_NOT_REACHED (HASH_TABLE_NON_WEAK) 639 RETURN_NOT_REACHED (HASH_TABLE_NON_WEAK);
632 } 640 }
633 641
634 static int 642 static int
635 hash_table_test_validate (Lisp_Object keyword, Lisp_Object value, 643 hash_table_test_validate (Lisp_Object keyword, Lisp_Object value,
636 Error_Behavior errb) 644 Error_Behavior errb)
652 if (EQ (obj, Qeq)) return HASH_TABLE_EQ; 660 if (EQ (obj, Qeq)) return HASH_TABLE_EQ;
653 if (EQ (obj, Qequal)) return HASH_TABLE_EQUAL; 661 if (EQ (obj, Qequal)) return HASH_TABLE_EQUAL;
654 if (EQ (obj, Qeql)) return HASH_TABLE_EQL; 662 if (EQ (obj, Qeql)) return HASH_TABLE_EQL;
655 663
656 invalid_constant ("Invalid hash table test", obj); 664 invalid_constant ("Invalid hash table test", obj);
657 RETURN_NOT_REACHED (HASH_TABLE_EQ) 665 RETURN_NOT_REACHED (HASH_TABLE_EQ);
658 } 666 }
659 667
660 static int 668 static int
661 hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value, 669 hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value,
662 Error_Behavior errb) 670 Error_Behavior errb)
939 const Lisp_Hash_Table *ht_old = xhash_table (hash_table); 947 const Lisp_Hash_Table *ht_old = xhash_table (hash_table);
940 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table); 948 Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
941 949
942 copy_lcrecord (ht, ht_old); 950 copy_lcrecord (ht, ht_old);
943 951
944 ht->hentries = xnew_array (hentry, ht_old->size + 1); 952 ht->hentries = xnew_array (htentry, ht_old->size + 1);
945 memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (hentry)); 953 memcpy (ht->hentries, ht_old->hentries, (ht_old->size + 1) * sizeof (htentry));
946 954
947 hash_table = wrap_hash_table (ht); 955 hash_table = wrap_hash_table (ht);
948 956
949 if (! EQ (ht->next_weak, Qunbound)) 957 if (! EQ (ht->next_weak, Qunbound))
950 { 958 {
956 } 964 }
957 965
958 static void 966 static void
959 resize_hash_table (Lisp_Hash_Table *ht, Elemcount new_size) 967 resize_hash_table (Lisp_Hash_Table *ht, Elemcount new_size)
960 { 968 {
961 hentry *old_entries, *new_entries, *sentinel, *e; 969 htentry *old_entries, *new_entries, *sentinel, *e;
962 Elemcount old_size; 970 Elemcount old_size;
963 971
964 old_size = ht->size; 972 old_size = ht->size;
965 ht->size = new_size; 973 ht->size = new_size;
966 974
967 old_entries = ht->hentries; 975 old_entries = ht->hentries;
968 976
969 ht->hentries = xnew_array_and_zero (hentry, new_size + 1); 977 ht->hentries = xnew_array_and_zero (htentry, new_size + 1);
970 new_entries = ht->hentries; 978 new_entries = ht->hentries;
971 979
972 compute_hash_table_derived_values (ht); 980 compute_hash_table_derived_values (ht);
973 981
974 for (e = old_entries, sentinel = e + old_size; e < sentinel; e++) 982 for (e = old_entries, sentinel = e + old_size; e < sentinel; e++)
975 if (!HENTRY_CLEAR_P (e)) 983 if (!HTENTRY_CLEAR_P (e))
976 { 984 {
977 hentry *probe = new_entries + HASHCODE (e->key, ht); 985 htentry *probe = new_entries + HASHCODE (e->key, ht);
978 LINEAR_PROBING_LOOP (probe, new_entries, new_size) 986 LINEAR_PROBING_LOOP (probe, new_entries, new_size)
979 ; 987 ;
980 *probe = *e; 988 *probe = *e;
981 } 989 }
982 990
988 and thus their HASHCODEs have changed. */ 996 and thus their HASHCODEs have changed. */
989 void 997 void
990 pdump_reorganize_hash_table (Lisp_Object hash_table) 998 pdump_reorganize_hash_table (Lisp_Object hash_table)
991 { 999 {
992 const Lisp_Hash_Table *ht = xhash_table (hash_table); 1000 const Lisp_Hash_Table *ht = xhash_table (hash_table);
993 hentry *new_entries = xnew_array_and_zero (hentry, ht->size + 1); 1001 htentry *new_entries = xnew_array_and_zero (htentry, ht->size + 1);
994 hentry *e, *sentinel; 1002 htentry *e, *sentinel;
995 1003
996 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 1004 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
997 if (!HENTRY_CLEAR_P (e)) 1005 if (!HTENTRY_CLEAR_P (e))
998 { 1006 {
999 hentry *probe = new_entries + HASHCODE (e->key, ht); 1007 htentry *probe = new_entries + HASHCODE (e->key, ht);
1000 LINEAR_PROBING_LOOP (probe, new_entries, ht->size) 1008 LINEAR_PROBING_LOOP (probe, new_entries, ht->size)
1001 ; 1009 ;
1002 *probe = *e; 1010 *probe = *e;
1003 } 1011 }
1004 1012
1005 memcpy (ht->hentries, new_entries, ht->size * sizeof (hentry)); 1013 memcpy (ht->hentries, new_entries, ht->size * sizeof (htentry));
1006 1014
1007 xfree (new_entries); 1015 xfree (new_entries);
1008 } 1016 }
1009 1017
1010 static void 1018 static void
1013 Elemcount new_size = 1021 Elemcount new_size =
1014 hash_table_size ((Elemcount) ((double) ht->size * ht->rehash_size)); 1022 hash_table_size ((Elemcount) ((double) ht->size * ht->rehash_size));
1015 resize_hash_table (ht, new_size); 1023 resize_hash_table (ht, new_size);
1016 } 1024 }
1017 1025
1018 static hentry * 1026 static htentry *
1019 find_hentry (Lisp_Object key, const Lisp_Hash_Table *ht) 1027 find_htentry (Lisp_Object key, const Lisp_Hash_Table *ht)
1020 { 1028 {
1021 hash_table_test_function_t test_function = ht->test_function; 1029 hash_table_test_function_t test_function = ht->test_function;
1022 hentry *entries = ht->hentries; 1030 htentry *entries = ht->hentries;
1023 hentry *probe = entries + HASHCODE (key, ht); 1031 htentry *probe = entries + HASHCODE (key, ht);
1024 1032
1025 LINEAR_PROBING_LOOP (probe, entries, ht->size) 1033 LINEAR_PROBING_LOOP (probe, entries, ht->size)
1026 if (KEYS_EQUAL_P (probe->key, key, test_function)) 1034 if (KEYS_EQUAL_P (probe->key, key, test_function))
1027 break; 1035 break;
1028 1036
1034 If there is no corresponding value, return DEFAULT (which defaults to nil). 1042 If there is no corresponding value, return DEFAULT (which defaults to nil).
1035 */ 1043 */
1036 (key, hash_table, default_)) 1044 (key, hash_table, default_))
1037 { 1045 {
1038 const Lisp_Hash_Table *ht = xhash_table (hash_table); 1046 const Lisp_Hash_Table *ht = xhash_table (hash_table);
1039 hentry *e = find_hentry (key, ht); 1047 htentry *e = find_htentry (key, ht);
1040 1048
1041 return HENTRY_CLEAR_P (e) ? default_ : e->value; 1049 return HTENTRY_CLEAR_P (e) ? default_ : e->value;
1042 } 1050 }
1043 1051
1044 DEFUN ("puthash", Fputhash, 3, 3, 0, /* 1052 DEFUN ("puthash", Fputhash, 3, 3, 0, /*
1045 Hash KEY to VALUE in HASH-TABLE. 1053 Hash KEY to VALUE in HASH-TABLE.
1046 */ 1054 */
1047 (key, value, hash_table)) 1055 (key, value, hash_table))
1048 { 1056 {
1049 Lisp_Hash_Table *ht = xhash_table (hash_table); 1057 Lisp_Hash_Table *ht = xhash_table (hash_table);
1050 hentry *e = find_hentry (key, ht); 1058 htentry *e = find_htentry (key, ht);
1051 1059
1052 if (!HENTRY_CLEAR_P (e)) 1060 if (!HTENTRY_CLEAR_P (e))
1053 return e->value = value; 1061 return e->value = value;
1054 1062
1055 e->key = key; 1063 e->key = key;
1056 e->value = value; 1064 e->value = value;
1057 1065
1059 enlarge_hash_table (ht); 1067 enlarge_hash_table (ht);
1060 1068
1061 return value; 1069 return value;
1062 } 1070 }
1063 1071
1064 /* Remove hentry pointed at by PROBE. 1072 /* Remove htentry pointed at by PROBE.
1065 Subsequent entries are removed and reinserted. 1073 Subsequent entries are removed and reinserted.
1066 We don't use tombstones - too wasteful. */ 1074 We don't use tombstones - too wasteful. */
1067 static void 1075 static void
1068 remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe) 1076 remhash_1 (Lisp_Hash_Table *ht, htentry *entries, htentry *probe)
1069 { 1077 {
1070 Elemcount size = ht->size; 1078 Elemcount size = ht->size;
1071 CLEAR_HENTRY (probe); 1079 CLEAR_HTENTRY (probe);
1072 probe++; 1080 probe++;
1073 ht->count--; 1081 ht->count--;
1074 1082
1075 LINEAR_PROBING_LOOP (probe, entries, size) 1083 LINEAR_PROBING_LOOP (probe, entries, size)
1076 { 1084 {
1077 Lisp_Object key = probe->key; 1085 Lisp_Object key = probe->key;
1078 hentry *probe2 = entries + HASHCODE (key, ht); 1086 htentry *probe2 = entries + HASHCODE (key, ht);
1079 LINEAR_PROBING_LOOP (probe2, entries, size) 1087 LINEAR_PROBING_LOOP (probe2, entries, size)
1080 if (EQ (probe2->key, key)) 1088 if (EQ (probe2->key, key))
1081 /* hentry at probe doesn't need to move. */ 1089 /* htentry at probe doesn't need to move. */
1082 goto continue_outer_loop; 1090 goto continue_outer_loop;
1083 /* Move hentry from probe to new home at probe2. */ 1091 /* Move htentry from probe to new home at probe2. */
1084 *probe2 = *probe; 1092 *probe2 = *probe;
1085 CLEAR_HENTRY (probe); 1093 CLEAR_HTENTRY (probe);
1086 continue_outer_loop: continue; 1094 continue_outer_loop: continue;
1087 } 1095 }
1088 } 1096 }
1089 1097
1090 DEFUN ("remhash", Fremhash, 2, 2, 0, /* 1098 DEFUN ("remhash", Fremhash, 2, 2, 0, /*
1093 Return non-nil if an entry was removed. 1101 Return non-nil if an entry was removed.
1094 */ 1102 */
1095 (key, hash_table)) 1103 (key, hash_table))
1096 { 1104 {
1097 Lisp_Hash_Table *ht = xhash_table (hash_table); 1105 Lisp_Hash_Table *ht = xhash_table (hash_table);
1098 hentry *e = find_hentry (key, ht); 1106 htentry *e = find_htentry (key, ht);
1099 1107
1100 if (HENTRY_CLEAR_P (e)) 1108 if (HTENTRY_CLEAR_P (e))
1101 return Qnil; 1109 return Qnil;
1102 1110
1103 remhash_1 (ht, ht->hentries, e); 1111 remhash_1 (ht, ht->hentries, e);
1104 return Qt; 1112 return Qt;
1105 } 1113 }
1108 Remove all entries from HASH-TABLE, leaving it empty. 1116 Remove all entries from HASH-TABLE, leaving it empty.
1109 */ 1117 */
1110 (hash_table)) 1118 (hash_table))
1111 { 1119 {
1112 Lisp_Hash_Table *ht = xhash_table (hash_table); 1120 Lisp_Hash_Table *ht = xhash_table (hash_table);
1113 hentry *e, *sentinel; 1121 htentry *e, *sentinel;
1114 1122
1115 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 1123 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1116 CLEAR_HENTRY (e); 1124 CLEAR_HTENTRY (e);
1117 ht->count = 0; 1125 ht->count = 0;
1118 1126
1119 return hash_table; 1127 return hash_table;
1120 } 1128 }
1121 1129
1278 copy_compress_hentries (const Lisp_Hash_Table *ht) 1286 copy_compress_hentries (const Lisp_Hash_Table *ht)
1279 { 1287 {
1280 Lisp_Object * const objs = 1288 Lisp_Object * const objs =
1281 /* If the hash table is empty, ht->count could be 0. */ 1289 /* If the hash table is empty, ht->count could be 0. */
1282 xnew_array (Lisp_Object, 2 * (ht->count > 0 ? ht->count : 1)); 1290 xnew_array (Lisp_Object, 2 * (ht->count > 0 ? ht->count : 1));
1283 const hentry *e, *sentinel; 1291 const htentry *e, *sentinel;
1284 Lisp_Object *pobj; 1292 Lisp_Object *pobj;
1285 1293
1286 for (e = ht->hentries, sentinel = e + ht->size, pobj = objs; e < sentinel; e++) 1294 for (e = ht->hentries, sentinel = e + ht->size, pobj = objs; e < sentinel; e++)
1287 if (!HENTRY_CLEAR_P (e)) 1295 if (!HTENTRY_CLEAR_P (e))
1288 { 1296 {
1289 *(pobj++) = e->key; 1297 *(pobj++) = e->key;
1290 *(pobj++) = e->value; 1298 *(pobj++) = e->value;
1291 } 1299 }
1292 1300
1337 void 1345 void
1338 elisp_maphash_unsafe (maphash_function_t function, 1346 elisp_maphash_unsafe (maphash_function_t function,
1339 Lisp_Object hash_table, void *extra_arg) 1347 Lisp_Object hash_table, void *extra_arg)
1340 { 1348 {
1341 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table); 1349 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1342 const hentry *e, *sentinel; 1350 const htentry *e, *sentinel;
1343 1351
1344 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++) 1352 for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
1345 if (!HENTRY_CLEAR_P (e)) 1353 if (!HTENTRY_CLEAR_P (e))
1346 if (function (e->key, e->value, extra_arg)) 1354 if (function (e->key, e->value, extra_arg))
1347 return; 1355 return;
1348 } 1356 }
1349 1357
1350 /* Map *C* function FUNCTION over the elements of a lisp hash table. 1358 /* Map *C* function FUNCTION over the elements of a lisp hash table.
1420 for (hash_table = Vall_weak_hash_tables; 1428 for (hash_table = Vall_weak_hash_tables;
1421 !NILP (hash_table); 1429 !NILP (hash_table);
1422 hash_table = XHASH_TABLE (hash_table)->next_weak) 1430 hash_table = XHASH_TABLE (hash_table)->next_weak)
1423 { 1431 {
1424 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table); 1432 const Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1425 const hentry *e = ht->hentries; 1433 const htentry *e = ht->hentries;
1426 const hentry *sentinel = e + ht->size; 1434 const htentry *sentinel = e + ht->size;
1427 1435
1428 if (! marked_p (hash_table)) 1436 if (! marked_p (hash_table))
1429 /* The hash table is probably garbage. Ignore it. */ 1437 /* The hash table is probably garbage. Ignore it. */
1430 continue; 1438 continue;
1431 1439
1434 keeping this pair. */ 1442 keeping this pair. */
1435 switch (ht->weakness) 1443 switch (ht->weakness)
1436 { 1444 {
1437 case HASH_TABLE_KEY_WEAK: 1445 case HASH_TABLE_KEY_WEAK:
1438 for (; e < sentinel; e++) 1446 for (; e < sentinel; e++)
1439 if (!HENTRY_CLEAR_P (e)) 1447 if (!HTENTRY_CLEAR_P (e))
1440 if (marked_p (e->key)) 1448 if (marked_p (e->key))
1441 MARK_OBJ (e->value); 1449 MARK_OBJ (e->value);
1442 break; 1450 break;
1443 1451
1444 case HASH_TABLE_VALUE_WEAK: 1452 case HASH_TABLE_VALUE_WEAK:
1445 for (; e < sentinel; e++) 1453 for (; e < sentinel; e++)
1446 if (!HENTRY_CLEAR_P (e)) 1454 if (!HTENTRY_CLEAR_P (e))
1447 if (marked_p (e->value)) 1455 if (marked_p (e->value))
1448 MARK_OBJ (e->key); 1456 MARK_OBJ (e->key);
1449 break; 1457 break;
1450 1458
1451 case HASH_TABLE_KEY_VALUE_WEAK: 1459 case HASH_TABLE_KEY_VALUE_WEAK:
1452 for (; e < sentinel; e++) 1460 for (; e < sentinel; e++)
1453 if (!HENTRY_CLEAR_P (e)) 1461 if (!HTENTRY_CLEAR_P (e))
1454 { 1462 {
1455 if (marked_p (e->value)) 1463 if (marked_p (e->value))
1456 MARK_OBJ (e->key); 1464 MARK_OBJ (e->key);
1457 else if (marked_p (e->key)) 1465 else if (marked_p (e->key))
1458 MARK_OBJ (e->value); 1466 MARK_OBJ (e->value);
1459 } 1467 }
1460 break; 1468 break;
1461 1469
1462 case HASH_TABLE_KEY_CAR_WEAK: 1470 case HASH_TABLE_KEY_CAR_WEAK:
1463 for (; e < sentinel; e++) 1471 for (; e < sentinel; e++)
1464 if (!HENTRY_CLEAR_P (e)) 1472 if (!HTENTRY_CLEAR_P (e))
1465 if (!CONSP (e->key) || marked_p (XCAR (e->key))) 1473 if (!CONSP (e->key) || marked_p (XCAR (e->key)))
1466 { 1474 {
1467 MARK_OBJ (e->key); 1475 MARK_OBJ (e->key);
1468 MARK_OBJ (e->value); 1476 MARK_OBJ (e->value);
1469 } 1477 }
1473 rate. At least this is not externally visible - and in 1481 rate. At least this is not externally visible - and in
1474 fact all of these KEY_CAR_* types are only used by the 1482 fact all of these KEY_CAR_* types are only used by the
1475 glyph code. */ 1483 glyph code. */
1476 case HASH_TABLE_KEY_CAR_VALUE_WEAK: 1484 case HASH_TABLE_KEY_CAR_VALUE_WEAK:
1477 for (; e < sentinel; e++) 1485 for (; e < sentinel; e++)
1478 if (!HENTRY_CLEAR_P (e)) 1486 if (!HTENTRY_CLEAR_P (e))
1479 { 1487 {
1480 if (!CONSP (e->key) || marked_p (XCAR (e->key))) 1488 if (!CONSP (e->key) || marked_p (XCAR (e->key)))
1481 { 1489 {
1482 MARK_OBJ (e->key); 1490 MARK_OBJ (e->key);
1483 MARK_OBJ (e->value); 1491 MARK_OBJ (e->value);
1487 } 1495 }
1488 break; 1496 break;
1489 1497
1490 case HASH_TABLE_VALUE_CAR_WEAK: 1498 case HASH_TABLE_VALUE_CAR_WEAK:
1491 for (; e < sentinel; e++) 1499 for (; e < sentinel; e++)
1492 if (!HENTRY_CLEAR_P (e)) 1500 if (!HTENTRY_CLEAR_P (e))
1493 if (!CONSP (e->value) || marked_p (XCAR (e->value))) 1501 if (!CONSP (e->value) || marked_p (XCAR (e->value)))
1494 { 1502 {
1495 MARK_OBJ (e->key); 1503 MARK_OBJ (e->key);
1496 MARK_OBJ (e->value); 1504 MARK_OBJ (e->value);
1497 } 1505 }
1525 { 1533 {
1526 /* Now, scan over all the pairs. Remove all of the pairs 1534 /* Now, scan over all the pairs. Remove all of the pairs
1527 in which the key or value, or both, is unmarked 1535 in which the key or value, or both, is unmarked
1528 (depending on the weakness of the hash table). */ 1536 (depending on the weakness of the hash table). */
1529 Lisp_Hash_Table *ht = XHASH_TABLE (hash_table); 1537 Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
1530 hentry *entries = ht->hentries; 1538 htentry *entries = ht->hentries;
1531 hentry *sentinel = entries + ht->size; 1539 htentry *sentinel = entries + ht->size;
1532 hentry *e; 1540 htentry *e;
1533 1541
1534 for (e = entries; e < sentinel; e++) 1542 for (e = entries; e < sentinel; e++)
1535 if (!HENTRY_CLEAR_P (e)) 1543 if (!HTENTRY_CLEAR_P (e))
1536 { 1544 {
1537 again: 1545 again:
1538 if (!marked_p (e->key) || !marked_p (e->value)) 1546 if (!marked_p (e->key) || !marked_p (e->value))
1539 { 1547 {
1540 remhash_1 (ht, entries, e); 1548 remhash_1 (ht, entries, e);
1541 if (!HENTRY_CLEAR_P (e)) 1549 if (!HTENTRY_CLEAR_P (e))
1542 goto again; 1550 goto again;
1543 } 1551 }
1544 } 1552 }
1545 1553
1546 prev = hash_table; 1554 prev = hash_table;