From 012138e29f8802157ee430b68a1c64f0ef3fbe0b Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Tue, 1 Jul 2025 12:02:10 +0100 Subject: [PATCH] Small sizeclass lookup improvement, (#777) * Fix off by one in deciding where to switch from small to large. * Improve codegen on Windows by making it simpler for compiler to remove a redundant branch --- src/snmalloc/mem/sizeclasstable.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/snmalloc/mem/sizeclasstable.h b/src/snmalloc/mem/sizeclasstable.h index 18c849a..d31a1f6 100644 --- a/src/snmalloc/mem/sizeclasstable.h +++ b/src/snmalloc/mem/sizeclasstable.h @@ -32,7 +32,7 @@ namespace snmalloc } constexpr size_t NUM_SMALL_SIZECLASSES = - size_to_sizeclass_const(MAX_SMALL_SIZECLASS_SIZE); + size_to_sizeclass_const(MAX_SMALL_SIZECLASS_SIZE) + 1; // Large classes range from [MAX_SMALL_SIZECLASS_SIZE, ADDRESS_SPACE). constexpr size_t NUM_LARGE_CLASSES = @@ -41,7 +41,7 @@ namespace snmalloc // How many bits are required to represent either a large or a small // sizeclass. constexpr size_t TAG_SIZECLASS_BITS = bits::max( - bits::next_pow2_bits_const(NUM_SMALL_SIZECLASSES + 1), + bits::next_pow2_bits_const(NUM_SMALL_SIZECLASSES), bits::next_pow2_bits_const(NUM_LARGE_CLASSES + 1)); // Number of bits required to represent a tagged sizeclass that can be @@ -410,7 +410,7 @@ namespace snmalloc } constexpr size_t sizeclass_lookup_size = - sizeclass_lookup_index(MAX_SMALL_SIZECLASS_SIZE); + sizeclass_lookup_index(MAX_SMALL_SIZECLASS_SIZE) + 1; /** * This struct is used to statically initialise a table for looking up @@ -470,9 +470,10 @@ namespace snmalloc constexpr smallsizeclass_t size_to_sizeclass(size_t size) { - auto index = sizeclass_lookup_index(size); - if (index < sizeclass_lookup_size) + if (SNMALLOC_LIKELY(is_small_sizeclass(size))) { + auto index = sizeclass_lookup_index(size); + SNMALLOC_ASSERT(index < sizeclass_lookup_size); return sizeclass_lookup.table[index]; }