From 855784e5a72cb1a1309bcc832f84e4d0989bfba6 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 14 Nov 2013 12:05:42 +0100 Subject: Add support for large items to the memory manager This is required, so we can track ExecutionContexts through the regular memory manager. Change-Id: I1bd2e2ef275e6e9e1f364a35affbb991f4377b05 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4mm.cpp | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp index 9eb3ae7ec9..d57ad69262 100644 --- a/src/qml/jsruntime/qv4mm.cpp +++ b/src/qml/jsruntime/qv4mm.cpp @@ -155,6 +155,19 @@ struct MemoryManager::Data QVector heapChunks; + + struct LargeItem { + LargeItem *next; + void *data; + + Managed *managed() { + return reinterpret_cast(&data); + } + }; + + LargeItem *largeItems; + + // statistics: #ifdef DETAILED_MM_STATS QVector allocSizeCounters; @@ -167,6 +180,7 @@ struct MemoryManager::Data , stackTop(0) , totalItems(0) , totalAlloc(0) + , largeItems(0) { memset(smallItems, 0, sizeof(smallItems)); memset(nChunks, 0, sizeof(nChunks)); @@ -258,8 +272,14 @@ Managed *MemoryManager::alloc(std::size_t size) size_t pos = size >> 4; - // fits into a small bucket - Q_ASSERT(size < MemoryManager::Data::MaxItemSize); + // doesn't fit into a small bucket + if (size >= MemoryManager::Data::MaxItemSize) { + // we use malloc for this + MemoryManager::Data::LargeItem *item = static_cast(malloc(size + sizeof(MemoryManager::Data::LargeItem))); + item->next = m_d->largeItems; + m_d->largeItems = item; + return item->managed(); + } Managed *m = m_d->smallItems[pos]; if (m) @@ -447,6 +467,23 @@ void MemoryManager::sweep(bool lastSweep) for (QVector::iterator i = m_d->heapChunks.begin(), ei = m_d->heapChunks.end(); i != ei; ++i) sweep(reinterpret_cast(i->memory.base()), i->memory.size(), i->chunkSize, &deletable); + Data::LargeItem *i = m_d->largeItems; + Data::LargeItem **last = &m_d->largeItems; + while (i) { + Managed *m = i->managed(); + Q_ASSERT(m->inUse); + if (m->markBit) { + m->markBit = 0; + last = &i->next; + i = i->next; + continue; + } + + *last = i->next; + free(i); + i = *last; + } + ExecutionContext *ctx = m_contextList; ExecutionContext **n = &m_contextList; while (ctx) { -- cgit v1.2.3