From 1e9a1307b2164e8e36198e58da9f4a9709e41761 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Wed, 5 Aug 2026 15:48:37 +0200 Subject: [PATCH] Compute aligned size class arithmetically get_size_info_align previously scanned the size class table linearly from the class matching the requested size until it found one whose size was a multiple of the alignment, costing up to ~28 iterations (e.g. a small allocation with page-sized alignment). Rounding the size up to a multiple of the (power of 2) alignment and then to a size class always lands on the smallest class whose size is a multiple of the alignment, since get_size_info rounds up to a power-of-2 spacing which preserves divisibility by the alignment. This makes the lookup constant time, which should improve memory-aligned (de)llocations. Verified equivalent to the previous scan for every size and alignment in both the default and extended size class configurations. --- h_malloc.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/h_malloc.c b/h_malloc.c index 46a6d481..0961892a 100644 --- a/h_malloc.c +++ b/h_malloc.c @@ -249,17 +249,15 @@ static inline struct size_info get_size_info(size_t size) { // alignment must be a power of 2 <= PAGE_SIZE since slabs are only page aligned static inline struct size_info get_size_info_align(size_t size, size_t alignment) { - unsigned start = get_size_info(size).class; - if (unlikely(!start)) { - start = 1; - } - for (unsigned class = start; class < N_SIZE_CLASSES; class++) { - size_t real_size = size_classes[class]; - if (size <= real_size && !(real_size & (alignment - 1))) { - return (struct size_info){real_size, class}; - } - } - fatal_error("invalid size for slabs"); + // Rounding up to a multiple of the (power of 2) alignment and then to a size class always + // lands on a class whose size is a multiple of the alignment: get_size_info rounds up to a + // power-of-2 spacing, which preserves divisibility by the alignment. This is the smallest + // such class, matching a linear scan over the size classes without the O(N) cost. + size_t aligned_size = align(size, alignment); + if (unlikely(aligned_size == 0)) { + aligned_size = alignment; + } + return get_size_info(aligned_size); } static size_t get_slab_size(size_t slots, size_t size) {