Small changes (#159)

* Use NoZero for fresh pages
* MADV_DONTNEED only use for greater than a whole slab
* Simplify free list threading code
This commit is contained in:
Matthew Parkinson
2020-04-02 07:04:03 +01:00
committed by GitHub
parent d900e29424
commit 06eef5c4c5
3 changed files with 24 additions and 38 deletions

View File

@@ -185,18 +185,19 @@ namespace snmalloc
void push_space(address_t start, size_t large_class)
{
// All fresh pages so can use "NoZero"
void* p = pointer_cast<void>(start);
if (large_class > 0)
PAL::template notify_using<YesZero>(p, OS_PAGE_SIZE);
PAL::template notify_using<NoZero>(p, OS_PAGE_SIZE);
else
{
if (decommit_strategy == DecommitSuperLazy)
{
PAL::template notify_using<YesZero>(p, OS_PAGE_SIZE);
PAL::template notify_using<NoZero>(p, OS_PAGE_SIZE);
p = new (p) Decommittedslab();
}
else
PAL::template notify_using<YesZero>(p, SUPERSLAB_SIZE);
PAL::template notify_using<NoZero>(p, SUPERSLAB_SIZE);
}
large_stack[large_class].push(reinterpret_cast<Largeslab*>(p));
}

View File

@@ -94,42 +94,23 @@ namespace snmalloc
static SNMALLOC_FAST_PATH void
alloc_new_list(void*& bumpptr, FreeListHead& fast_free_list, size_t rsize)
{
// Allocate the last object on the current page if there is one,
// and then thread the next free list worth of allocations.
bool crossed_page_boundary = false;
void* curr = nullptr;
while (true)
fast_free_list.value = bumpptr;
void* newbumpptr = pointer_offset(bumpptr, rsize);
void* slab_end = pointer_align_up<SLAB_SIZE>(newbumpptr);
void* slab_end2 =
pointer_align_up<OS_PAGE_SIZE>(pointer_offset(bumpptr, rsize * 32));
if (slab_end2 < slab_end)
slab_end = slab_end2;
while (newbumpptr < slab_end)
{
void* newbumpptr = pointer_offset(bumpptr, rsize);
auto alignedbumpptr =
bits::align_up(address_cast(bumpptr) - 1, OS_PAGE_SIZE);
auto alignednewbumpptr =
bits::align_up(address_cast(newbumpptr), OS_PAGE_SIZE);
if (alignedbumpptr != alignednewbumpptr)
{
// We have crossed a page boundary already, so
// lets stop building our free list.
if (crossed_page_boundary)
break;
crossed_page_boundary = true;
}
if (curr == nullptr)
{
fast_free_list.value = bumpptr;
}
else
{
Metaslab::store_next(curr, bumpptr);
}
curr = bumpptr;
Metaslab::store_next(bumpptr, newbumpptr);
bumpptr = newbumpptr;
newbumpptr = pointer_offset(bumpptr, rsize);
}
SNMALLOC_ASSERT(curr != nullptr);
Metaslab::store_next(curr, nullptr);
Metaslab::store_next(bumpptr, nullptr);
bumpptr = newbumpptr;
}
bool is_start_of_object(Superslab* super, void* p)

View File

@@ -37,11 +37,15 @@ namespace snmalloc
template<bool page_aligned = false>
void zero(void* p, size_t size) noexcept
{
// QEMU does not seem to be giving the desired behaviour for MADV_DONTNEED.
// switch back to memset only for QEMU.
// QEMU does not seem to be giving the desired behaviour for
// MADV_DONTNEED. switch back to memset only for QEMU.
# ifndef SNMALLOC_QEMU_WORKAROUND
if (page_aligned || is_aligned_block<OS_PAGE_SIZE>(p, size))
if (
(page_aligned || is_aligned_block<OS_PAGE_SIZE>(p, size)) &&
(size > SLAB_SIZE))
{
// Only use this on large allocations as memset faster, and doesn't
// introduce IPI so faster for small allocations.
SNMALLOC_ASSERT(is_aligned_block<OS_PAGE_SIZE>(p, size));
madvise(p, size, MADV_DONTNEED);
}