diff --git a/src/mem/entropy.h b/src/mem/entropy.h index 9a56cb2..7f14919 100644 --- a/src/mem/entropy.h +++ b/src/mem/entropy.h @@ -31,11 +31,13 @@ namespace snmalloc struct FreeListKey { - address_t key; + address_t key1; + address_t key2; address_t key_next; - constexpr FreeListKey(uint64_t key, uint64_t key_next) - : key(static_cast(key)), + constexpr FreeListKey(uint64_t key1, uint64_t key2, uint64_t key_next) + : key1(static_cast(key1)), + key2(static_cast(key2)), key_next(static_cast(key_next)) {} }; @@ -47,7 +49,7 @@ namespace snmalloc uint64_t local_counter{0}; uint64_t fresh_bits{0}; uint64_t count{0}; - FreeListKey key{0, 0}; + FreeListKey key{0, 0, 0}; public: constexpr LocalEntropy() = default; @@ -59,12 +61,14 @@ namespace snmalloc local_counter = get_entropy64(); if constexpr (bits::BITS == 64) { - key.key = get_next(); + key.key1 = get_next(); + key.key2 = get_next(); key.key_next = get_next(); } else { - key.key = get_next() & 0xffff'ffff; + key.key1 = get_next() & 0xffff'ffff; + key.key2 = get_next() & 0xffff'ffff; key.key_next = get_next() & 0xffff'ffff; } bit_source = get_next(); diff --git a/src/mem/freelist.h b/src/mem/freelist.h index 31500bb..a8bc4df 100644 --- a/src/mem/freelist.h +++ b/src/mem/freelist.h @@ -43,20 +43,13 @@ namespace snmalloc { /** * This function is used to sign back pointers in the free list. - * - * TODO - Needs review. Should we shift low bits out as they help - * guess the key. - * - * TODO - We now have space in the FreeListBuilder for a fresh key for each - * list. */ inline static uintptr_t signed_prev(address_t curr, address_t next, const FreeListKey& key) { auto c = curr; auto n = next; - auto k = key.key; - return (c + k) * (n - k); + return (c + key.key1) * (n + key.key2); } /** @@ -65,7 +58,7 @@ namespace snmalloc * back pointer in a doubly linked list, however, it is encoded * to prevent corruption. * - * TODO: Consider put prev_encoded at the end of the object, would + * TODO: Consider putting prev_encoded at the end of the object, would * require size to be threaded through, but would provide more OOB * detection. */ @@ -443,11 +436,14 @@ namespace snmalloc } } - std::pair, CapPtr> + template + std::enable_if_t< + !RANDOM_, + std::pair, CapPtr>> extract_segment(const FreeListKey& key) { + static_assert(RANDOM_ == RANDOM, "Don't set SFINAE parameter!"); SNMALLOC_ASSERT(!empty()); - SNMALLOC_ASSERT(!RANDOM); // TODO: Turn this into a static failure. auto first = read_head(0, key); // end[0] is pointing to the first field in the object, diff --git a/src/mem/remoteallocator.h b/src/mem/remoteallocator.h index 6e8ea47..f467cfc 100644 --- a/src/mem/remoteallocator.h +++ b/src/mem/remoteallocator.h @@ -27,7 +27,7 @@ namespace snmalloc /** * Global key for all remote lists. */ - inline static FreeListKey key_global(0xdeadbeef, 0xdeadbeef); + inline static FreeListKey key_global(0xdeadbeef, 0xbeefdead, 0xdeadbeef); struct alignas(REMOTE_MIN_ALIGN) RemoteAllocator {