aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-12-18 15:03:26 +0100
committerLars Knoll <lars.knoll@digia.com>2012-12-18 15:21:16 +0100
commitf2e52c5bf26cfcedd0901040dfe1a6c86c5aa146 (patch)
treed486af12c135e6b8e56947beac08ce85b25f5fcb
parenteb5471f4fbdc2bbd1b811f935fa34664671d8c67 (diff)
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 <lars.knoll@digia.com>
-rw-r--r--qv4mm.cpp29
1 files 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 <QTime>
#include <QVector>
@@ -43,6 +45,7 @@
#include <alloca.h>
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<size_t, MMObject *> largeItems;
- QLinkedList<QPair<char *, std::size_t> > heapChunks;
+ QLinkedList<PageAllocation> heapChunks;
// statistics:
#ifdef DETAILED_MM_STATS
@@ -80,8 +83,8 @@ struct MemoryManager::Data
~Data()
{
- for (QLinkedList<QPair<char *, std::size_t> >::iterator i = heapChunks.begin(), ei = heapChunks.end(); i != ei; ++i)
- free(i->first);
+ for (QLinkedList<PageAllocation>::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<void**>(&ptr), 16, allocSize);
- m_d->heapChunks.append(qMakePair(ptr, allocSize));
- m_d->fallbackObject = reinterpret_cast<MMObject *>(ptr);
+ allocSize = roundUpToMultipleOf(WTF::pageSize(), allocSize);
+ PageAllocation allocation = PageAllocation::allocate(allocSize, OSAllocator::JSGCHeapPages);
+ m_d->heapChunks.append(allocation);
+ m_d->fallbackObject = reinterpret_cast<MMObject *>(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<QPair<char *, std::size_t> >::iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i)
- freedCount += sweep(i->first, i->second, largestFreedBlock);
+ for (QLinkedList<PageAllocation>::iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i)
+ freedCount += sweep(reinterpret_cast<char*>(i->base()), i->size(), largestFreedBlock);
return freedCount;
}
@@ -431,10 +434,10 @@ void MemoryManagerWithNativeStack::collectRootsOnStack(QVector<VM::Object *> &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<QPair<char *, std::size_t> >::Iterator it = m_d->heapChunks.begin(), end =
+ for (QLinkedList<PageAllocation>::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<char*>(it->base());
+ heapChunkBoundaries[i++] = reinterpret_cast<char*>(it->base()) + it->size();
}
qSort(heapChunkBoundaries, heapChunkBoundariesEnd);