From 06eef5c4c56b29981353589dc857f1701804c1d7 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Thu, 2 Apr 2020 07:04:03 +0100 Subject: [PATCH] Small changes (#159) * Use NoZero for fresh pages * MADV_DONTNEED only use for greater than a whole slab * Simplify free list threading code --- src/mem/largealloc.h | 7 ++++--- src/mem/slab.h | 45 +++++++++++++------------------------------- src/pal/pal_linux.h | 10 +++++++--- 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/mem/largealloc.h b/src/mem/largealloc.h index 916eaed..50120ee 100644 --- a/src/mem/largealloc.h +++ b/src/mem/largealloc.h @@ -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(start); if (large_class > 0) - PAL::template notify_using(p, OS_PAGE_SIZE); + PAL::template notify_using(p, OS_PAGE_SIZE); else { if (decommit_strategy == DecommitSuperLazy) { - PAL::template notify_using(p, OS_PAGE_SIZE); + PAL::template notify_using(p, OS_PAGE_SIZE); p = new (p) Decommittedslab(); } else - PAL::template notify_using(p, SUPERSLAB_SIZE); + PAL::template notify_using(p, SUPERSLAB_SIZE); } large_stack[large_class].push(reinterpret_cast(p)); } diff --git a/src/mem/slab.h b/src/mem/slab.h index 548d9ff..8c14fe3 100644 --- a/src/mem/slab.h +++ b/src/mem/slab.h @@ -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(newbumpptr); + void* slab_end2 = + pointer_align_up(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) diff --git a/src/pal/pal_linux.h b/src/pal/pal_linux.h index 6b83831..d4c20a7 100644 --- a/src/pal/pal_linux.h +++ b/src/pal/pal_linux.h @@ -37,11 +37,15 @@ namespace snmalloc template 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(p, size)) + if ( + (page_aligned || is_aligned_block(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(p, size)); madvise(p, size, MADV_DONTNEED); }