From aa61b59a8ff62785ccd33be3487d806bf0183a02 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Mon, 6 Jun 2022 23:39:46 +0100 Subject: [PATCH] NFC: Generalize smallbuddyrange bounds annotations Make these generic, with the SmallBuddyRange taking its cue from the parent Range, since we're about to change them anyway and might want to vary them again in the future. --- .../backend_helpers/smallbuddyrange.h | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/snmalloc/backend_helpers/smallbuddyrange.h b/src/snmalloc/backend_helpers/smallbuddyrange.h index 53e82ba..c35abea 100644 --- a/src/snmalloc/backend_helpers/smallbuddyrange.h +++ b/src/snmalloc/backend_helpers/smallbuddyrange.h @@ -10,20 +10,22 @@ namespace snmalloc * struct for representing the redblack nodes * directly inside the meta data. */ + template struct FreeChunk { - capptr::Chunk left; - capptr::Chunk right; + CapPtr left; + CapPtr right; }; /** * Class for using the allocations own space to store in the RBTree. */ + template class BuddyInplaceRep { public: - using Handle = capptr::Chunk*; - using Contents = capptr::Chunk; + using Handle = CapPtr, bounds>*; + using Contents = CapPtr, bounds>; static constexpr Contents null = nullptr; static constexpr Contents root = nullptr; @@ -33,17 +35,17 @@ namespace snmalloc { SNMALLOC_ASSERT((address_cast(r) & MASK) == 0); if (r == nullptr) - *ptr = capptr::Chunk::unsafe_from( - reinterpret_cast((*ptr).unsafe_uintptr() & MASK)); + *ptr = CapPtr, bounds>::unsafe_from( + reinterpret_cast*>((*ptr).unsafe_uintptr() & MASK)); else // Preserve lower bit. *ptr = pointer_offset(r, (address_cast(*ptr) & MASK)) - .template as_static(); + .template as_static>(); } static Contents get(Handle ptr) { - return pointer_align_down<2, FreeChunk>((*ptr).as_void()); + return pointer_align_down<2, FreeChunk>((*ptr).as_void()); } static Handle ref(bool direction, Contents r) @@ -66,15 +68,16 @@ namespace snmalloc if (new_is_red != is_red(k)) { auto r = ref(false, k); - auto old_addr = pointer_align_down<2, FreeChunk>(r->as_void()); + auto old_addr = pointer_align_down<2, FreeChunk>(r->as_void()); if (new_is_red) { if (old_addr == nullptr) - *r = capptr::Chunk::unsafe_from( - reinterpret_cast(MASK)); + *r = CapPtr, bounds>::unsafe_from( + reinterpret_cast*>(MASK)); else - *r = pointer_offset(old_addr, MASK).template as_static(); + *r = pointer_offset(old_addr, MASK) + .template as_static>(); } else { @@ -86,21 +89,22 @@ namespace snmalloc static Contents offset(Contents k, size_t size) { - return pointer_offset(k, size).template as_static(); + return pointer_offset(k, size).template as_static>(); } static Contents buddy(Contents k, size_t size) { // This is just doing xor size, but with what API // exists on capptr. - auto base = pointer_align_down(k.as_void(), size * 2); + auto base = pointer_align_down>(k.as_void(), size * 2); auto offset = (address_cast(k) & size) ^ size; - return pointer_offset(base, offset).template as_static(); + return pointer_offset(base, offset) + .template as_static>(); } static Contents align_down(Contents k, size_t size) { - return pointer_align_down(k.as_void(), size); + return pointer_align_down>(k.as_void(), size); } static bool compare(Contents k1, Contents k2) @@ -149,30 +153,38 @@ namespace snmalloc template> class Type : public ContainsParent { + public: + using ChunkBounds = typename ParentRange::ChunkBounds; + + private: using ContainsParent::parent; static constexpr size_t MIN_BITS = - bits::next_pow2_bits_const(sizeof(FreeChunk)); + bits::next_pow2_bits_const(sizeof(FreeChunk)); - Buddy buddy_small; + Buddy, MIN_BITS, MIN_CHUNK_BITS> buddy_small; /** * Add a range of memory to the address space. * Divides blocks into power of two sizes with natural alignment */ - void add_range(capptr::Chunk base, size_t length) + void add_range(CapPtr base, size_t length) { range_to_pow_2_blocks( - base, length, [this](capptr::Chunk base, size_t align, bool) { - capptr::Chunk overflow = - buddy_small.add_block(base.as_reinterpret(), align) + base, + length, + [this](CapPtr base, size_t align, bool) { + CapPtr overflow = + buddy_small + .add_block( + base.template as_reinterpret>(), align) .template as_reinterpret(); if (overflow != nullptr) parent.dealloc_range(overflow, bits::one_at_bit(MIN_CHUNK_BITS)); }); } - capptr::Chunk refill(size_t size) + CapPtr refill(size_t size) { auto refill = parent.alloc_range(MIN_CHUNK_SIZE); @@ -188,11 +200,9 @@ namespace snmalloc static constexpr bool ConcurrencySafe = false; - using ChunkBounds = capptr::bounds::Chunk; - constexpr Type() = default; - capptr::Chunk alloc_range(size_t size) + CapPtr alloc_range(size_t size) { if (size >= MIN_CHUNK_SIZE) { @@ -209,7 +219,7 @@ namespace snmalloc return refill(size); } - capptr::Chunk alloc_range_with_leftover(size_t size) + CapPtr alloc_range_with_leftover(size_t size) { SNMALLOC_ASSERT(size <= MIN_CHUNK_SIZE); @@ -227,7 +237,7 @@ namespace snmalloc return result.template as_reinterpret(); } - void dealloc_range(capptr::Chunk base, size_t size) + void dealloc_range(CapPtr base, size_t size) { if (size >= MIN_CHUNK_SIZE) {