diff options
author | Andy Wingo <wingo@pobox.com> | 2025-04-23 15:23:42 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2025-04-23 15:23:42 +0200 |
commit | af567f0575adc079b634830c35eaefc46001d156 (patch) | |
tree | b13d826e6c282dfb5ee34d6e4f8a098587c1e80e | |
parent | 68839e078947f2418a417dec476da6e9c972f1e3 (diff) | |
download | guile-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.c | 29 |
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); } |