* src/gtkutil.c (free_gc_handle_callback): New.
(xg_finish_scroll_bar_creation): Use it instead of free_glib_gc_handle.
* src/pgtkterm.c (xg_scroll_callback, xg_end_scroll_callback): Adapt to
gc_handles.
Determining the best size for a static array seems difficult; so
allocate it dynamically.
* src/charset.c (CHARSET_TABLE_INIT_SIZE): New constant.
(syms_of_charset): Malloc charset_table here.
(charset_table_init): Removed.
(shrink_charset_table): New function.
(Fclear_charset_maps): Call it.
* src/charset.h (charset_table_init): Removed.
(charset_attributes_getter): Add an assertion.
* src/pdumper (dump_charset_table, dump_do_dump_relocation): Assert that
charset_table_size == charset_table_used.
The charset_table_init array can't be used because it may be too small.
* src/pdumper.c (RELOC_CHARSET_TABLE): New reloc type.
(dump_charset_table): Emit RELOC_CHARSET_TABLE.
(dump_do_dump_relocation): Implement the RELOC_CHARSET_TABLE case.
A weak hash table is now once again a pointer to a structure that
looks like a strong hash table.
* src/fns.c (weak_hash_from_key, set_weak_hash_next_slot):
(set_weak_hash_hash_slot, set_weak_hash_index_slot):
(WEAK_HASH_NEXT, WEAK_HASH_INDEX): Use Lisp_Objects or integers, not
the old 'struct Lisp_Weak_Hash_Table_Entry' type.
(allocate_weak_hash_table): Rewrite to use ...
(allocate_weak_hash_table_parts): ... this new function.
(make_weak_hash_table, weak_hash_index_index): Adjust entry types.
(maybe_resize_weak_hash_table): Reuse
'allocate_weak_hash_table_parts'.
(weak_hash_lookup_with_hash, weak_hash_put):
(weak_hash_remove_from_table, weak_hash_clear):
(Fhash_table_size, Fputhash): Adjust entry types.
* src/igc.c (fix_weak, IGC_FIX12_WEAK): Function and macro removed.
(fix_weak_hash_table_strong_part):
(fix_weak_hash_table_weak_part): Rewritten to use interior pointers
rather than making assumptions about the memory layout.
(weak_hash_table_entry, make_weak_hash_table_entry): Functions
removed.
(igc_alloc_weak_hash_table_strong_part):
(igc_alloc_weak_hash_table_weak_part): Rewritten to use 'alloc_multi'.
* src/igc.h:
* src/lisp.h (struct Lisp_Weak_Hash_Table_Entry): Type removed.
(struct Lisp_Weak_Hash_Table_Strong_Part)
(struct Lisp_Weak_Hash_Table_Weak_Part): Remove flexible 'entries' array.
(WEAK_HASH_KEY, WEAK_HASH_VALUE, WEAK_HASH_HASH)
(WEAK_HASH_TABLE_SIZE, weak_hash_table_index_size):
(DOHASH_WEAK, set_weak_hash_key_slot):
(set_weak_hash_value_slot): Adjust types of hash table entries.
Hash table weak and strong parts cannot be described as C structures,
since they consist of a sequence of variably-sized objects.
* src/igc.c (alloc_multi): New function.
These objects are no longer used.
* src/igc.c (pinned_objects_in_dump): Deleted
(igc_on_pdump_loaded): Skip creating pins.
(fix_charset_table): This should no longer be needed.
This is a preparation step to remove the pinned charset objects from the
GC heap.
* src/pdumper.c (dump_charset_table): Copy the charset_table back to
charset_table_init.
(dump_fixup_type.DUMP_FIXUP_CHARSET_CODE_SPACE_MASK): New fixup type.
(dump_reloc_type.RELOC_CHARSET_CODE_SPACE_MASK): New reloc type.
(dump_cold_charset): Emit fixup to relocate the code space mask.
(dump_do_fixup): Implemented DUMP_FIXUP_CHARSET_CODE_SPACE_MASK.
(dump_do_dump_relocation): Implemented RELOC_CHARSET_CODE_SPACE_MASK.
* src/charset.c (charset_table): Initialize charset_table here, not ...
(syms_of_charset): ... here.
* src/igc.c (igc_on_pdump_loaded): Remove assertion. charset_table no
longer points to the beginning of the dump.
When compiled with igc_debug, fix_weak_hash_table_strong_part can
trigger assertion failures because it calls fix_raw with unaligned
addresses. I assume that the AWL pool will filter out unaligned
addresses and the assertion is not needed.
* src/igc.c (fix_weak, IGC_FIX12_WEAK): New.
(fix_weak_hash_table_strong_part, fix_weak_hash_table_weak_part): Use
it.
* test/src/fns-tests.el (ft-weak-fixnums): New test.
(ft--test-weak-fixnums): New helper.
* src/igc.h (w32_aligned_stack_pos): New union.
* src/w32proc.c (timer_loop):
* src/w32fns.c (w32_msg_worker): Use it to ensure proper alignment
of stack bottom. Evidently, MPS requires it to be aligned as the
'Word' type used by MPS, see
https://lists.gnu.org/archive/html/emacs-devel/2025-10/msg00767.html
for the details.
This simplifies the GC code, as this was the only field in the charset
struct that referenced the GC heap. Without it, we no longer need to
trace the charset_table.
* src/charset.h (struct charset.attributes): Removed.
(charset_attributes_getter): New helper.
(CHARSET_ATTRIBUTES): Use it.
* src/charset.c (charset_attributes_table): New.
(Fdefine_charset_internal): Place attrs in charset_attributes_table.
(syms_of_charset): Initialize charset_attributes_table.
(mark_charset): Deleted.
* src/pdumper.c (dump_charset): Skip attributes field.
* src/lisp.h (mark_charset): Deleted.
* src/igc.c (fix_charset_table): Nothing to do anymore.
* src/alloc.c (garbage_collect): mark_charset no longer needed.
* src/pgtkmenu.c (menu_highlight_callback, menubar_selection_callback)
(popup_selection_callback):
* src/pgtkterm.c (size_allocate, pgtk_set_event_handler): Use
'gc_handle' or raw pointer, not 'glib_user_data'.
* src/gtkutil.c (struct xg_frame_tb_info): Use 'gc_handle', not
'Lisp_Object'.
(free_glib_gc_handle): New function.
(hierarchy_ch_cb, qttip_cb): Use 'gc_handle', not 'glib_user_data'.
(style_changed_cb): Use pointer directly, not through
'glib_user_data'.
(xg_create_frame_widgets,xg_create_frame_outer_widgets): Use
'gc_handle' or pointer.
(xg_free_frame_widgets) [MPS]: Use 'xfree'
(create_dialog, xg_dialog_response_cb, xg_dialog_run):
(xg_toggle_notify_cb, xg_get_file_with_chooser): Use pointers
directly.
(make_cl_data, update_cl_data, unref_cl_data): Use 'gc_handle' values.
(xg_mark_data): Simplify, since 'gc_handle' values are marked elsewhere.
(menuitem_destroy_callback, menu_destroy_callback): Use pointers
directly.
(xg_create_one_menuitem): Use 'gc_handle' values for callback data.
(menu_bar_button_pressed_cb, create_menus):
(xg_update_menu_item): Use 'gc_handle' values.
(menubar_map_cb): Use pointer to stack variable.
(xg_update_frame_menubar, find_scrollbar_cb): Use 'gc_handle' value.
(xg_get_widget_from_map): Use pointer to stack variable.
(xg_gtk_scroll_free_scroll_bar_cell): Funtion removed.
(xg_finish_scroll_bar_creation): Use 'gc_handle' value. The object we
create a handle for is unprintable and must not be leaked to Lisp.
(draw_page):
(xg_print_frames_dialog): Use 'gc_handle' values.
(xg_tool_bar_callback, xg_tool_bar_help_callback): Use integers cast
to pointers.
(tb_size_cb): Use 'gc_handle' value.
(xg_create_tool_bar) [MPS]: Use 'xmalloc'.
(xg_make_tool_item): Use integers cast to pointers.
(update_frame_tool_bar): Use 'gc_handle' values.
(free_frame_tool_bar) [MPS]: Use 'xfree'.
(xg_im_context_commit, xg_widget_style_updated):
* src/gtkutil.h (xg_menu_cb_data, xg_menu_item_cb_data):
* src/xmenu.c (menu_highlight_callback, menubar_selection_callback):
Use 'gc_handle' values, not Lisp_Object values.
* src/igc.c (w32_add_non_lisp_thread)
(w32_remove_non_lisp_thread) [HAVE_NTGUI]: New functions to
register w32 threads with MPS.
* src/igc.h: Define their prototypes.
* src/w32proc.c (timer_loop):
* src/w32fns.c (w32_msg_worker) [HAVE_MPS]: Call
'w32_add_non_lisp_thread' when the thread starts and
'w32_remove_non_lisp_thread' when it is about to exit.
Must use GC handles there too.
* src/xterm.c (xaw_jump_callback, xaw_scroll_callback)
(x_create_toolkit_scroll_bar): Some reformatting.
(xaw_free_gc_handle): Renamed from xaw_destroy_scrollbar_callback.
(x_create_horizontal_toolkit_scroll_bar): Create a GC handle.
Create a type alias Lisp_KV_Vector that is a struct Lisp_Vector* for
igc and a naked Lisp_Object* for the old GC.
* src/lisp.h (Lisp_KV_Vector): New typedef.
(kv_vector_data): New helper.
(struct Lisp_Obarray): Make buckets a Lisp_KV_Vector.
(struct Lisp_Hash_Table): Make key and value Lisp_KV_Vectors.
(hash_table_alloc_kv, hash_table_free_kv): Use Lisp_KV_Vector.
(obarray_iter_at_end, HASH_KEY, HASH_KEY, DOHASH, set_hash_key_slot)
(set_hash_value_slot): Adapt to Lisp_KV_Vector.
* src/alloc.c (hash_table_alloc_kv, hash_table_free_kv): Adapt to
Lisp_KV_Vector.
* src/fns.c (make_hash_table, copy_hash_table, maybe_resize_hash_table)
(hash_table_rehash): Adapt to Lisp_KV_Vector.
* src/igc.h (igc_make_hash_table_vec): Return a Lisp_Vector.
* src/igc.c (igc_make_hash_table_vec): Return a Lisp_Vector.
(fix_hash_table, fix_obarray): Use IGC_FIX12_PVEC for
Lisp_KV_Vectors.
* src/lread.c (intern_sym, Funintern, oblookup, make_obarray)
(grow_obarray, Fobarray_clear): Adapt to Lisp_KV_Vector.
* src/pdumper.c (hash_table_contents, hash_table_freeze, dump_hash_vec):
Adapt to Lisp_KV_Vector.
* test/src/emacs-module-tests.el (module--gc): New function.
(mod-test-globref-make-test,module--test-assertions--globref-invalid-free)
(module--test-assertion): Use it.
(module--test-assertions--call-emacs-from-gc): Expect this to fail.
(module/function-finalizer): Expect this to pass.
* src/fns.c (weak_hash_clear): Slow case for key-or-value weakness.
(Fputhash): Use the key in the table, not the (potentially different)
key we looked it up with.
(Fremhash): Destroy extra dependencies.
* src/igc.c (igc_xpointer):
(is_builtin_obj): New functions.
(scan_lispsym): Call 'dflt_scan_obj', which scans the extended header,
not 'fix_symbol' directly.
(igc_external_header): New 'is_builtin' argument. Use it to avoid
crashes.
(find_dependency_replacement):
(remove_dependency_replacement):
(Figc__extra_dependency): New functions.
(Figc__add_extra_dependency): Simplify. Use
'find_dependency_replacement'.
(Figc__remove_extra_dependency): Use 'find_dependency_replacement'.
Clean up when last dependency is removed.
(Vigc__dependency_replacements): New Lisp variable.
Some changes suggested by Stefan Monnier in
https://lists.gnu.org/archive/html/emacs-devel/2025-10/msg00490.html
* src/fns.c (strong_copy_hash_table): Renamed from
'strengthen_hash_table'.
(strengthen_hash_table_for_dump): Return type changed to 'void'.
(make_weak_hash_table): Error for user-defined hash table tests.
(maybe_resize_weak_hash_table): Use local variable and add comment.
(Fcopy_hash_table): Avoid redundant copy.
(Fhash_table_count): Continue copying, so the count is always
accurate.
(Fhash_table_rehash_size):
(Fhash_table_rehash_threshold):
(Fhash_table_size):
(Fhash_table_test): Avoid creating copy.
(Fmaphash): Adjust API.
(Finternal__hash_table_histogram):
(Finternal__hash_table_buckets): Return nil.
(Finternal__hash_table_index_size):
* src/print.c (print_object): Adjust API.
Provide the 'frame-height' call with the frame of the window where
the *Completions* buffer is displayed for the case when the minibuffer
window uses a dedicated frame (bug#79635).