Tidy TODOs from Free List
* Add extra key to freelist. This follows the encoding Cedric suggested for a signature of two things. Free list key now has a pair of keys for encoding previous pointer. This makes it harder to extract the underlying keys out of the multiplication. * Apply SFINAE to the extract_segment.
This commit is contained in:
committed by
Matthew Parkinson
parent
15e3052087
commit
0af1ee3bef
@@ -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<address_t>(key)),
|
||||
constexpr FreeListKey(uint64_t key1, uint64_t key2, uint64_t key_next)
|
||||
: key1(static_cast<address_t>(key1)),
|
||||
key2(static_cast<address_t>(key2)),
|
||||
key_next(static_cast<address_t>(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<PAL>();
|
||||
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();
|
||||
|
||||
@@ -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<FreeObject, CBAlloc>, CapPtr<FreeObject, CBAlloc>>
|
||||
template<bool RANDOM_ = RANDOM>
|
||||
std::enable_if_t<
|
||||
!RANDOM_,
|
||||
std::pair<CapPtr<FreeObject, CBAlloc>, CapPtr<FreeObject, CBAlloc>>>
|
||||
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,
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user