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).
On GNU/Linux, glibc expects condvars and mutexes to be in memory which
is always accessible.
* src/thread.c (main_thread_condvar): New variable.
(main_thread): Add reference to it.
(run_thread): Adjust.
(finalize_one_thread) [MPS]: Free 'thread_condvar'.
(Fmake_thread) [MPS]: Allocate 'thread_condvar'.
(thread_join_callback):
(init_threads): Adjust.
* src/thread.h (struct thread_state): Turn 'thread_condvar' into a
pointer or single-element array.
* test/src/igc-tests.el (igc-test--list-length): New variable.
(igc-test--trigger-incremental-gc): New function.
(igc-test-thread-incremental-gc): New test.
This prevents a very subtle bug: The MPS AWL pool doesn't handle
ambiguous interior pointers. The way DOHASH_WEAK is written, no base
pointer to the weak or strong parts of the weak hash table is on the
stack, so it's possible for the AWL segment not to update forwarding
references before allowing access to the segment.
* src/fns.c (hash_table_being_accessed): New variable.
(strengthen_hash_table): Ensure the strong and weak parts are pinned
by an ambiguous non-interior reference while we access the hash table.
When clicking on a string displayed by a display property, also
look at the text properties of the underlying buffer text for
keymaps, not just the displayed string. The displayed string
takes precedence over the buffer text, but it doesn't replace
it.
Also, we should use the buffer's local map even for clicks on
the mode line. (Otherwise, what's the point of the <mode-line>
event?)
* src/keymap.c (Fcurrent_active_maps): Consider displayed
string, then buffer text, then fall back to local
map. (Bug#79505)
* test/src/keymap-tests.el
(keymap-test-keymaps-for-non-buffer-positions): Add more tests.
* lisp/progmodes/lua-mode.el (lua-process-buffer-name)
(lua-process-history-file, lua-process-startfile): New options.
(lua-start-process): Use new options.
(lua-send-file): New command.
(lua--repl-buffer-p): Remove unused internal variable. (Bug#79573)
* doc/emacs/sending.texi (Sending Mail):
* doc/emacs/dired.texi (Dired Enter, Dired Visiting):
* doc/emacs/maintaining.texi (Old Revisions)
(Change Log Commands, Looking Up Identifiers):
* doc/emacs/windows.texi (Displaying Buffers):
* doc/emacs/files.texi (Visiting): Add cross-references to where
user options are described which control how windows are split.
* lisp/mail/sendmail.el (mail-other-window):
* lisp/gnus/message.el (message-mail-other-window)
(message-news-other-window):
* lisp/replace.el (occur-mode-goto-occurrence-other-window):
* lisp/vc/vc.el (vc-revision-other-window):
* lisp/vc/vc-dir.el (vc-dir-find-file-other-window):
* lisp/progmodes/xref.el (xref-find-definitions-other-window):
* lisp/simple.el (compose-mail-other-window)
(clone-indirect-buffer-other-window):
* lisp/vc/add-log.el (add-change-log-entry-other-window):
* lisp/view.el (view-file-other-window)
(view-buffer-other-window):
* lisp/window.el (switch-to-buffer-other-window):
* lisp/files.el (find-file-other-window)
(find-file-read-only-other-window)
(find-alternate-file-other-window):
* lisp/dired.el (dired-other-window)
(dired-mouse-find-file-other-window)
(dired-find-file-other-window, dired-jump-other-window): Mention
in the doc strings how to control the way the current window is
split.