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:
@@ -168,7 +168,7 @@ template<bool committed>
|
||||
void* reserve(const size_t* size) noexcept;
|
||||
```
|
||||
Only one of these needs to be implemented, depending on whether the underlying
|
||||
system can provide strongly (e.g. 16MiB) aligned memory regions.
|
||||
system can provide strongly aligned memory regions.
|
||||
If the system guarantees only page alignment, implement the second and snmalloc
|
||||
will over-allocate and then trim the requested region.
|
||||
If the system provides strong alignment, implement the first to return memory
|
||||
|
||||
@@ -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