wingo pushed a commit to branch wip-whippet
in repository guile.

commit af567f0575adc079b634830c35eaefc46001d156
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Wed Apr 23 15:23:42 2025 +0200

    Vtables avoid zero-sized bitmap allocation
    
    * libguile/struct.c (set_vtable_access_fields): If there are no fields,
    we don't need to allocate an unboxed fields array.
---
 libguile/struct.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/libguile/struct.c b/libguile/struct.c
index 68dcc0070..8721c5469 100644
--- a/libguile/struct.c
+++ b/libguile/struct.c
@@ -1,4 +1,4 @@
-/* Copyright 1996-2001,2003-2004,2006-2013,2015,2017-2018,2020
+/* Copyright 1996-2001,2003-2004,2006-2013,2015,2017-2018,2020,2025
      Free Software Foundation, Inc.
 
    This file is part of Guile.
@@ -126,7 +126,7 @@ SCM_DEFINE (scm_make_struct_layout, "make-struct-layout", 
1, 0, 0,
 static void
 set_vtable_access_fields (SCM vtable)
 {
-  size_t len, nfields, bitmask_size, field;
+  size_t len, nfields;
   SCM layout;
   const char *c_layout;
   uint32_t *unboxed_fields;
@@ -138,20 +138,23 @@ set_vtable_access_fields (SCM vtable)
   assert (len % 2 == 0);
   nfields = len / 2;
 
-  bitmask_size = (nfields + 31U) / 32U;
-  unboxed_fields =
-    scm_gc_malloc_pointerless (bitmask_size * sizeof (*unboxed_fields),
-                               "unboxed fields");
-  memset (unboxed_fields, 0, bitmask_size * sizeof (*unboxed_fields));
-
-  /* Update FLAGS according to LAYOUT.  */
-  for (field = 0; field < nfields; field++)
-    if (c_layout[field*2] == 'u')
-      unboxed_fields[field/32U] |= 1U << (field%32U);
+  if (nfields)
+    {
+      size_t bitmask_size = (nfields + 31U) / 32U;
+      unboxed_fields =
+        scm_gc_malloc_pointerless (bitmask_size * sizeof (*unboxed_fields),
+                                   "unboxed fields");
+      memset (unboxed_fields, 0, bitmask_size * sizeof (*unboxed_fields));
+      for (size_t field = 0; field < nfields; field++)
+        if (c_layout[field*2] == 'u')
+          unboxed_fields[field/32U] |= 1U << (field%32U);
+    }
+  else
+    unboxed_fields = NULL;
 
   /* Record computed size of vtable's instances.  */
   SCM_SET_VTABLE_FLAGS (vtable, 0);
-  SCM_STRUCT_DATA_SET (vtable, scm_vtable_index_size, len / 2);
+  SCM_STRUCT_DATA_SET (vtable, scm_vtable_index_size, nfields);
   SCM_STRUCT_DATA_SET (vtable, scm_vtable_index_unboxed_fields,
                        (uintptr_t) unboxed_fields);
 }

Reply via email to