From 7f7704b6fc58e42d2755d6b21325e5d8c430f4d4 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Wed, 26 Jun 2019 17:08:27 +0100 Subject: [PATCH] Made a size to sizeclass table. --- CMakeLists.txt | 1 + src/mem/sizeclass.h | 17 ++++------------- src/mem/sizeclasstable.h | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 79e9bd4..69193b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ if(NOT DEFINED SNMALLOC_ONLY_HEADER_LIBRARY) warnings_high() if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /constexpr:steps 10000000") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi") set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG") else() diff --git a/src/mem/sizeclass.h b/src/mem/sizeclass.h index 0f2d28a..cb5d3b8 100644 --- a/src/mem/sizeclass.h +++ b/src/mem/sizeclass.h @@ -11,20 +11,11 @@ namespace snmalloc constexpr static uint16_t get_initial_bumpptr(sizeclass_t sc, bool is_short); constexpr static uint16_t get_initial_link(sizeclass_t sc, bool is_short); constexpr static size_t sizeclass_to_size(sizeclass_t sizeclass); - constexpr static size_t - sizeclass_to_cache_friendly_mask(sizeclass_t sizeclass); - constexpr static size_t - sizeclass_to_inverse_cache_friendly_mask(sizeclass_t sc); + constexpr static size_t sizeclass_to_cache_friendly_mask(sizeclass_t sizeclass); + constexpr static size_t sizeclass_to_inverse_cache_friendly_mask(sizeclass_t sc); constexpr static uint16_t medium_slab_free(sizeclass_t sizeclass); + static sizeclass_t size_to_sizeclass(size_t size); - static inline sizeclass_t size_to_sizeclass(size_t size) - { - // Don't use sizeclasses that are not a multiple of the alignment. - // For example, 24 byte allocations can be - // problematic for some data due to alignment issues. - return static_cast( - bits::to_exp_mant(size)); - } constexpr static inline sizeclass_t size_to_sizeclass_const(size_t size) { @@ -38,7 +29,7 @@ namespace snmalloc constexpr static inline size_t large_sizeclass_to_size(uint8_t large_class) { return bits::one_at_bit(large_class + SUPERSLAB_BITS); - } + } // Small classes range from [MIN, SLAB], i.e. inclusive. static constexpr size_t NUM_SMALL_CLASSES = diff --git a/src/mem/sizeclasstable.h b/src/mem/sizeclasstable.h index 4f4958d..cab6595 100644 --- a/src/mem/sizeclasstable.h +++ b/src/mem/sizeclasstable.h @@ -5,8 +5,21 @@ namespace snmalloc { + constexpr size_t PTR_BITS = bits::next_pow2_bits_const(sizeof(void*)); + + constexpr static size_t sizeclass_lookup_index(size_t s) + { + // We shift by PTR_BITS as makes code-gen for the table lookup nicer. + // We could shift by MIN_ALLOC_BITS, but then there is a slightly more + // complex sequence. + return (s - 1) >> PTR_BITS; + } + + constexpr static size_t sizeclass_lookup_size = sizeclass_lookup_index(SLAB_SIZE + 1); + struct SizeClassTable { + sizeclass_t sizeclass_lookup[sizeclass_lookup_size]; ModArray size; ModArray cache_friendly_mask; ModArray inverse_cache_friendly_mask; @@ -16,8 +29,10 @@ namespace snmalloc ModArray short_initial_link_ptr; ModArray medium_slab_slots; + constexpr SizeClassTable() - : size(), + : sizeclass_lookup(), + size(), cache_friendly_mask(), inverse_cache_friendly_mask(), bump_ptr_start(), @@ -26,10 +41,18 @@ namespace snmalloc short_initial_link_ptr(), medium_slab_slots() { + size_t curr = 1; for (sizeclass_t sizeclass = 0; sizeclass < NUM_SIZECLASSES; sizeclass++) { size[sizeclass] = bits::from_exp_mant(sizeclass); + if (sizeclass < NUM_SMALL_CLASSES) + { + for ( ; curr <= size[sizeclass]; curr+= 1 << PTR_BITS) + { + sizeclass_lookup[sizeclass_lookup_index(curr)] = sizeclass; + } + } size_t alignment = bits::min( bits::one_at_bit(bits::ctz_const(size[sizeclass])), OS_PAGE_SIZE); @@ -108,6 +131,21 @@ namespace snmalloc return sizeclass_metadata.inverse_cache_friendly_mask[sizeclass]; } + static inline sizeclass_t size_to_sizeclass(size_t size) + { + if ((size-1) <= (SLAB_SIZE-1)) + { + return sizeclass_metadata.sizeclass_lookup[sizeclass_lookup_index(size)]; + } + + // Don't use sizeclasses that are not a multiple of the alignment. + // For example, 24 byte allocations can be + // problematic for some data due to alignment issues. + return static_cast( + bits::to_exp_mant(size)); + } + + constexpr static inline uint16_t medium_slab_free(sizeclass_t sizeclass) { return sizeclass_metadata