From 2b12c13055d2f2eaeb2e9641f227bccbf7a77aec Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 5 Oct 2014 20:24:00 +0300 Subject: [PATCH] memory: support sized deallocation With N3778, the compiler can provide us with the size of the object, so we can avoid looking it up in the page array. Unfortunately only implemented in clang at the moment. --- core/memory.cc | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/core/memory.cc b/core/memory.cc index ecc5775d00..24da67705c 100644 --- a/core/memory.cc +++ b/core/memory.cc @@ -206,6 +206,7 @@ struct cpu_pages { void free_span_no_merge(pageidx start, uint32_t nr_pages); void* allocate_small(unsigned size); void free(void* ptr); + void free(void* ptr, size_t size); size_t object_size(void* ptr); page* to_page(void* p) { return &pages[(reinterpret_cast(p) - mem()) / page_size]; @@ -353,6 +354,16 @@ void cpu_pages::free(void* ptr) { } } +void cpu_pages::free(void* ptr, size_t size) { + assert(((reinterpret_cast(ptr) >> cpu_id_shift) & 0xff) == cpu_id); + if (size <= max_small_allocation) { + auto pool = &small_pools[small_pool::size_to_idx(size)]; + pool->deallocate(ptr); + } else { + free_large(ptr); + } +} + bool cpu_pages::initialize() { if (nr_pages) { return false; @@ -526,6 +537,10 @@ void free(void* obj) { cpu_mem.free(obj); } +void free(void* obj, size_t size) { + cpu_mem.free(obj, size); +} + } using namespace memory; @@ -661,6 +676,18 @@ void operator delete[](void* ptr) throw () { } } +void operator delete(void* ptr, size_t size) { + if (ptr) { + memory::free(ptr, size); + } +} + +void operator delete[](void* ptr, size_t size) { + if (ptr) { + memory::free(ptr, size); + } +} + void* operator new(size_t size, std::nothrow_t) throw () { if (size == 0) { size = 1; @@ -695,4 +722,16 @@ void operator delete[](void* ptr, std::nothrow_t) throw () { } } +void operator delete(void* ptr, size_t size, std::nothrow_t) throw () { + if (ptr) { + memory::free(ptr, size); + } +} + +void operator delete[](void* ptr, size_t size, std::nothrow_t) throw () { + if (ptr) { + memory::free(ptr, size); + } +} + #endif