1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-29 19:30:36 +02:00

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.
This commit is contained in:
Andy Wingo 2025-04-23 15:23:42 +02:00
parent 68839e0789
commit af567f0575

View file

@ -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);
}