Make all large allocations naturally aligned
This makes any large allocation naturally aligned to its size. This means all alignment requests can be handled without checks.
This commit is contained in:
@@ -281,9 +281,6 @@ namespace snmalloc
|
||||
template<class MemoryProvider>
|
||||
class LargeAlloc
|
||||
{
|
||||
void* reserved_start = nullptr;
|
||||
void* reserved_end = nullptr;
|
||||
|
||||
public:
|
||||
// This will be a zero-size structure if stats are not enabled.
|
||||
Stats stats;
|
||||
@@ -292,38 +289,6 @@ namespace snmalloc
|
||||
|
||||
LargeAlloc(MemoryProvider& mp) : memory_provider(mp) {}
|
||||
|
||||
template<AllowReserve allow_reserve>
|
||||
bool reserve_memory(size_t need, size_t add)
|
||||
{
|
||||
assert(reserved_start <= reserved_end);
|
||||
|
||||
/*
|
||||
* Spell this comparison in terms of pointer subtraction like this,
|
||||
* rather than "reserved_start + need < reserved_end" because the
|
||||
* sum might not be representable on CHERI.
|
||||
*/
|
||||
if (pointer_diff(reserved_start, reserved_end) < need)
|
||||
{
|
||||
if constexpr (allow_reserve == YesReserve)
|
||||
{
|
||||
stats.segment_create();
|
||||
reserved_start =
|
||||
memory_provider.template reserve<false>(&add, SUPERSLAB_SIZE);
|
||||
reserved_end = pointer_offset(reserved_start, add);
|
||||
reserved_start = pointer_align_up<SUPERSLAB_SIZE>(reserved_start);
|
||||
|
||||
if (add < need)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<ZeroMem zero_mem = NoZero, AllowReserve allow_reserve = YesReserve>
|
||||
void* alloc(size_t large_class, size_t size)
|
||||
{
|
||||
@@ -337,23 +302,9 @@ namespace snmalloc
|
||||
|
||||
if (p == nullptr)
|
||||
{
|
||||
assert(reserved_start <= reserved_end);
|
||||
size_t add;
|
||||
|
||||
if ((rsize + SUPERSLAB_SIZE) < RESERVE_SIZE)
|
||||
add = RESERVE_SIZE;
|
||||
else
|
||||
add = rsize + SUPERSLAB_SIZE;
|
||||
|
||||
if (!reserve_memory<allow_reserve>(rsize, add))
|
||||
return nullptr;
|
||||
|
||||
p = reserved_start;
|
||||
reserved_start = pointer_offset(p, rsize);
|
||||
|
||||
stats.superslab_fresh();
|
||||
// All memory is zeroed since it comes from reserved space.
|
||||
memory_provider.template notify_using<NoZero>(p, size);
|
||||
size_t add = rsize;
|
||||
p = memory_provider.template reserve<false>(&add, rsize);
|
||||
memory_provider.template notify_using<zero_mem>(p, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -179,8 +179,6 @@ namespace snmalloc
|
||||
{
|
||||
// Client responsible for checking alignment is not zero
|
||||
assert(alignment != 0);
|
||||
// Client responsible for checking alignment is not above SUPERSLAB_SIZE
|
||||
assert(alignment <= SUPERSLAB_SIZE);
|
||||
// Client responsible for checking alignment is a power of two
|
||||
assert(bits::next_pow2(alignment) == alignment);
|
||||
|
||||
|
||||
@@ -108,8 +108,7 @@ extern "C"
|
||||
SNMALLOC_NAME_MANGLE(memalign)(size_t alignment, size_t size)
|
||||
{
|
||||
if (
|
||||
(alignment == 0) || (alignment == size_t(-1)) ||
|
||||
(alignment > SUPERSLAB_SIZE))
|
||||
(alignment == 0) || (alignment == size_t(-1)))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return nullptr;
|
||||
|
||||
@@ -108,7 +108,7 @@ int main(int argc, char** argv)
|
||||
test_posix_memalign((size_t)-1, 0, EINVAL, true);
|
||||
test_posix_memalign(OS_PAGE_SIZE, sizeof(uintptr_t) / 2, EINVAL, true);
|
||||
|
||||
for (size_t align = sizeof(uintptr_t); align <= SUPERSLAB_SIZE; align <<= 1)
|
||||
for (size_t align = sizeof(uintptr_t); align <= SUPERSLAB_SIZE * 8; align <<= 1)
|
||||
{
|
||||
for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user