Subject: feature/igc [PATCH] Trace struct hash_table_test exactly

From: Helmut Eller <[email-masked]>
Date: Wed, 02 Jul 2025 14:27:21 +0200

>From b08eb9fe786cab0ae92fe7fb63585c198c210e5b Mon Sep 17 00:00:00 2001
From: Helmut Eller <[email-masked]>
Date: Wed, 2 Jul 2025 13:46:20 +0200
Subject: [PATCH] Trace struct hash_table_test exactly

* src/lisp.h (struct hash_table_user_test): Moved here from fns.c.
* src/fns.c (get_hash_table_user_test): Use igc_alloc_hash_table_user_test.
* src/igc.h (igc_alloc_hash_table_user_test): New.
* src/igc.c (igc_alloc_hash_table_user_test): Implement it.
(scan_hash_table_user_test): Actual tracing coding code.
---
 src/fns.c  | 13 +------------
 src/igc.c  | 23 +++++++++++++++++++++++
 src/igc.h  |  1 +
 src/lisp.h | 10 ++++++++++
 4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/fns.c b/src/fns.c
index 6ac61469292..cdc2cc52ff4 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -6166,17 +6166,6 @@ If (sxhash-equal-including-properties A B), then
   return reduce_emacs_uint_to_fixnum (hash);
 }
 
-
-/* This is a cache of hash_table_test structures so that they can be
-   shared between hash tables using the same test.
-   FIXME: This way of storing and looking up hash_table_test structs
-   isn't wonderful.  Find a better solution.  */
-struct hash_table_user_test
-{
-  struct hash_table_test test;
-  struct hash_table_user_test *next;
-};
-
 static struct hash_table_user_test *hash_table_user_tests = NULL;
 
 #ifndef HAVE_MPS
@@ -6212,7 +6201,7 @@ get_hash_table_user_test (Lisp_Object test)
   if (!ut)
     {
 #ifdef HAVE_MPS
-      ut = igc_xzalloc_ambig (sizeof *ut);
+      ut = igc_alloc_hash_table_user_test ();
 #else
       ut = xmalloc (sizeof *ut);
 #endif
diff --git a/src/igc.c b/src/igc.c
index d0bd9eb63e8..6100b9ce918 100644
--- a/src/igc.c
+++ b/src/igc.c
@@ -1781,6 +1781,20 @@ scan_kboard (mps_ss_t ss, void *start, void *end, void *closure)
   return MPS_RES_OK;
 }
 
+static mps_res_t
+scan_hash_table_user_test (mps_ss_t ss, void *start, void *end, void *closure)
+{
+  struct hash_table_user_test *ut = start;
+  MPS_SCAN_BEGIN (ss)
+  {
+    IGC_FIX12_OBJ (ss, &ut->test.user_hash_function);
+    IGC_FIX12_OBJ (ss, &ut->test.user_cmp_function);
+    IGC_FIX12_OBJ (ss, &ut->test.name);
+  }
+  MPS_SCAN_END (ss);
+  return MPS_RES_OK;
+}
+
 /***********************************************************************
 			 Default pad, fwd, ...
  ***********************************************************************/
@@ -3575,6 +3589,15 @@ igc_alloc_kboard (void)
   return kb;
 }
 
+struct hash_table_user_test *
+igc_alloc_hash_table_user_test (void)
+{
+  struct hash_table_user_test *ut = xzalloc (sizeof *ut);
+  root_create_exact (global_igc, ut, ut + 1, scan_hash_table_user_test,
+		     "hash-table-user-test");
+  return ut;
+}
+
 static void
 finalize_bignum (struct Lisp_Bignum *n)
 {
diff --git a/src/igc.h b/src/igc.h
index 308da60ed9f..1de17c62240 100644
--- a/src/igc.h
+++ b/src/igc.h
@@ -118,6 +118,7 @@ #define EMACS_IGC_H
 
 void *igc_xnrealloc_ambig (void *pa, ptrdiff_t nitems, ptrdiff_t item_size);
 struct kboard *igc_alloc_kboard (void);
+struct hash_table_user_test *igc_alloc_hash_table_user_test (void);
 
 struct Lisp_Vector *igc_alloc_pseudovector (size_t nwords_mem,
 					    size_t nwords_lisp,
diff --git a/src/lisp.h b/src/lisp.h
index 167f2cb3a8f..4fd591e0ba8 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2629,6 +2629,16 @@ #define DOOBARRAY(oa, it)					\
   Lisp_Object name;
 };
 
+/* This is a cache of hash_table_test structures so that they can be
+   shared between hash tables using the same test.
+   FIXME: This way of storing and looking up hash_table_test structs
+   isn't wonderful.  Find a better solution.  */
+struct hash_table_user_test
+{
+  struct hash_table_test test;
+  struct hash_table_user_test *next;
+};
+
 typedef enum hash_table_weakness_t {
   Weak_None,		 /* No weak references.  */
   Weak_Key,		 /* Reference to key is weak.  */
-- 
2.39.5