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