From f2e52c5bf26cfcedd0901040dfe1a6c86c5aa146 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 18 Dec 2012 15:03:26 +0100 Subject: Changed GC heap chunks to be allocated from separate page allocations Use page allocations instead of the regular libc heap for the chunks of the memory manager. This will allow for easier return of the memory to the operation system in the future. Change-Id: Ie370e54042251b17335e94b497933f06ab62ecc3 Reviewed-by: Lars Knoll --- qv4mm.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/qv4mm.cpp b/qv4mm.cpp index 4cdb211a92..25dfaa4cd2 100644 --- a/qv4mm.cpp +++ b/qv4mm.cpp @@ -32,6 +32,8 @@ #include "qv4ecmaobjects_p.h" #include "qv4mm.h" #include "StackBounds.h" +#include "PageAllocation.h" +#include "StdLibExtras.h" #include #include @@ -43,6 +45,7 @@ #include using namespace QQmlJS::VM; +using namespace WTF; static const std::size_t CHUNK_SIZE = 65536; @@ -59,7 +62,7 @@ struct MemoryManager::Data MMObject *fallbackObject; MMObject *smallItems[16]; // 16 - 256 bytes QMap largeItems; - QLinkedList > heapChunks; + QLinkedList heapChunks; // statistics: #ifdef DETAILED_MM_STATS @@ -80,8 +83,8 @@ struct MemoryManager::Data ~Data() { - for (QLinkedList >::iterator i = heapChunks.begin(), ei = heapChunks.end(); i != ei; ++i) - free(i->first); + for (QLinkedList::iterator i = heapChunks.begin(), ei = heapChunks.end(); i != ei; ++i) + i->deallocate(); } }; @@ -133,14 +136,14 @@ MemoryManager::MMObject *MemoryManager::alloc(std::size_t size) // try to free up space, otherwise allocate if (!m_d->aggressiveGC || runGC() < size) { std::size_t allocSize = std::max(size, CHUNK_SIZE); - char *ptr = 0; - posix_memalign(reinterpret_cast(&ptr), 16, allocSize); - m_d->heapChunks.append(qMakePair(ptr, allocSize)); - m_d->fallbackObject = reinterpret_cast(ptr); + allocSize = roundUpToMultipleOf(WTF::pageSize(), allocSize); + PageAllocation allocation = PageAllocation::allocate(allocSize, OSAllocator::JSGCHeapPages); + m_d->heapChunks.append(allocation); + m_d->fallbackObject = reinterpret_cast(allocation.base()); m_d->fallbackObject->info.inUse = 0; m_d->fallbackObject->info.next = 0; m_d->fallbackObject->info.markBit = 0; - m_d->fallbackObject->info.size = allocSize; + m_d->fallbackObject->info.size = allocation.size(); } return alloc(size - alignedSizeOfMMInfo); } @@ -247,8 +250,8 @@ std::size_t MemoryManager::sweep(std::size_t &largestFreedBlock) { std::size_t freedCount = 0; - for (QLinkedList >::iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i) - freedCount += sweep(i->first, i->second, largestFreedBlock); + for (QLinkedList::iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i) + freedCount += sweep(reinterpret_cast(i->base()), i->size(), largestFreedBlock); return freedCount; } @@ -431,10 +434,10 @@ void MemoryManagerWithNativeStack::collectRootsOnStack(QVector &ro char** heapChunkBoundaries = (char**)alloca(m_d->heapChunks.count() * 2 * sizeof(char*)); char** heapChunkBoundariesEnd = heapChunkBoundaries + 2 * m_d->heapChunks.count(); int i = 0; - for (QLinkedList >::Iterator it = m_d->heapChunks.begin(), end = + for (QLinkedList::Iterator it = m_d->heapChunks.begin(), end = m_d->heapChunks.end(); it != end; ++it) { - heapChunkBoundaries[i++] = it->first; - heapChunkBoundaries[i++] = it->first + it->second; + heapChunkBoundaries[i++] = reinterpret_cast(it->base()); + heapChunkBoundaries[i++] = reinterpret_cast(it->base()) + it->size(); } qSort(heapChunkBoundaries, heapChunkBoundariesEnd); -- cgit v1.2.3