Subject: feature/igc: [PATCH] Make lface_id_to_name an exact root

From: Helmut Eller <[email-masked]>
Date: Tue, 17 Jun 2025 09:56:23 +0200

This is a proposal to make the variable lface_id_to_name an exact root.

>From c462bc2a21c6e35e903df177a6f1e79d3e60f8ab Mon Sep 17 00:00:00 2001
From: Helmut Eller <[email-masked]>
Date: Tue, 17 Jun 2025 09:29:07 +0200
Subject: [PATCH] Make lface_id_to_name an exact root

* src/igc.h (igc_xpalloc_lisp_objs_exact): New.
* src/igc.c (igc_xpalloc_lisp_objs_exact): Implementation.
* src/xface.c (init_xfaces): igc_xalloc_lisp_objs_exact instead of
igc_xzalloc_ambig.
(Finternal_make_lisp_face): Use igc_xpalloc_lisp_objs_exact instead of
igc_xpalloc_ambig.
---
 src/igc.c    | 18 ++++++++++++++++++
 src/igc.h    |  6 ++++++
 src/xfaces.c | 10 ++++++----
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/src/igc.c b/src/igc.c
index eb845ff7ae0..2b9339d0c99 100644
--- a/src/igc.c
+++ b/src/igc.c
@@ -3503,6 +3503,24 @@ igc_xnrealloc_ambig (void *old_pa, ptrdiff_t nitems, ptrdiff_t item_size)
   return new_pa;
 }
 
+Lisp_Object *
+igc_xpalloc_lisp_objs_exact (Lisp_Object *pa, ptrdiff_t *nitems,
+			     ptrdiff_t nitems_incr_min, ptrdiff_t nitems_max,
+			     ptrdiff_t item_size, const char *label)
+{
+  ptrdiff_t nitems_old = *nitems;
+  ptrdiff_t nitems_new = nitems_old;
+  ptrdiff_t nbytes
+    = xpalloc_nbytes (pa, &nitems_new, nitems_incr_min, nitems_max, item_size);
+  Lisp_Object *old = pa;
+  Lisp_Object *new = xzalloc (nbytes);
+  root_create_exact (global_igc, new, new + nitems_new, scan_exact, label);
+  memcpy (new, old, nitems_old * sizeof old[0]);
+  igc_destroy_root_with_start (old);
+  *nitems = nitems_new;
+  return new;
+}
+
 static void
 finalize_bignum (struct Lisp_Bignum *n)
 {
diff --git a/src/igc.h b/src/igc.h
index 5e24c7c338a..1f1341ca589 100644
--- a/src/igc.h
+++ b/src/igc.h
@@ -96,6 +96,12 @@ #define EMACS_IGC_H
 			 ptrdiff_t nitems_incr_min, ptrdiff_t nitems_max,
 			 ptrdiff_t item_size);
 
+Lisp_Object *igc_xpalloc_lisp_objs_exact (Lisp_Object *pa, ptrdiff_t *nitems,
+					  ptrdiff_t nitems_incr_min,
+					  ptrdiff_t nitems_max,
+					  ptrdiff_t item_size,
+					  const char *label);
+
 typedef int igc_scan_result_t; /* zero means success */
 struct igc_ss;
 typedef igc_scan_result_t (*igc_scan_area_t) (struct igc_ss *ss, void *start,
diff --git a/src/xfaces.c b/src/xfaces.c
index 2ca68193876..7ebbc53709c 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -2990,8 +2990,11 @@ DEFUN ("internal-make-lisp-face", Finternal_make_lisp_face,
 	{
 #ifdef HAVE_MPS
 	  lface_id_to_name
-	    = igc_xpalloc_ambig (lface_id_to_name, &lface_id_to_name_size,
-				 1, MAX_FACE_ID, sizeof *lface_id_to_name);
+	    = igc_xpalloc_lisp_objs_exact (lface_id_to_name,
+					   &lface_id_to_name_size,
+					   1, MAX_FACE_ID,
+					   sizeof *lface_id_to_name,
+					   "lface-id-to-name");
 #else
 	  lface_id_to_name = xpalloc (lface_id_to_name, &lface_id_to_name_size,
 				      1, MAX_FACE_ID, sizeof *lface_id_to_name);
@@ -7361,8 +7364,7 @@ init_xfaces (void)
 	  /* Allocate the lface_id_to_name[] array.  */
 	  lface_id_to_name_size = next_lface_id = nfaces;
 #ifdef HAVE_MPS
-	  lface_id_to_name
-	    = igc_xzalloc_ambig (next_lface_id * sizeof *lface_id_to_name);
+	  lface_id_to_name = igc_xalloc_lisp_objs_exact (next_lface_id);
 #else
 	  lface_id_to_name = xnmalloc (next_lface_id, sizeof *lface_id_to_name);
 #endif
-- 
2.39.5