summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2025-04-23 15:23:42 +0200
committerAndy Wingo <wingo@pobox.com>2025-04-23 15:23:42 +0200
commitaf567f0575adc079b634830c35eaefc46001d156 (patch)
treeb13d826e6c282dfb5ee34d6e4f8a098587c1e80e
parent68839e078947f2418a417dec476da6e9c972f1e3 (diff)
downloadguile-af567f0575adc079b634830c35eaefc46001d156.tar.gz
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.
-rw-r--r--libguile/struct.c29
1 files 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);
}