diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-04-04 10:05:58 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-04-07 06:06:14 +0000 |
commit | 1e63f7c4833c19f760f4af0b7650311819d0f2b2 (patch) | |
tree | 355eec0c3e72969a7ff2719800697f19cfaba0c2 /src | |
parent | a410cb69012603a38a07f7670e2ad1c1876f675a (diff) |
Cleanups
* Only call ExecutionEngine::markObjects() on a full GC, it doesn't do
anything in the incrementall case anyway.
* Move the marking of child objects into it's own method for clarity
* Move collection of gray items down to happen directly before we drain
the mark stack
Change-Id: I41067e17d483067bd1c4d60da22c5628482dae78
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 30 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 2 | ||||
-rw-r--r-- | src/qml/memory/qv4heap_p.h | 2 | ||||
-rw-r--r-- | src/qml/memory/qv4mm.cpp | 123 |
4 files changed, 81 insertions, 76 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 99efa1cc13..b9408be218 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -148,8 +148,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) , m_profiler(0) #endif { - writeBarrierActive = true; - memoryManager = new QV4::MemoryManager(this); if (maxCallDepth == -1) { @@ -932,25 +930,23 @@ void ExecutionEngine::requireArgumentsAccessors(int n) } } -void ExecutionEngine::markObjects(bool incremental) +void ExecutionEngine::markObjects() { - if (!incremental) { - identifierTable->mark(this); + identifierTable->mark(this); - for (int i = 0; i < nArgumentsAccessors; ++i) { - const Property &pd = argumentsAccessors[i]; - if (Heap::FunctionObject *getter = pd.getter()) - getter->mark(this); - if (Heap::FunctionObject *setter = pd.setter()) - setter->mark(this); - } + for (int i = 0; i < nArgumentsAccessors; ++i) { + const Property &pd = argumentsAccessors[i]; + if (Heap::FunctionObject *getter = pd.getter()) + getter->mark(this); + if (Heap::FunctionObject *setter = pd.setter()) + setter->mark(this); + } - classPool->markObjects(this); + classPool->markObjects(this); - for (QSet<CompiledData::CompilationUnit*>::ConstIterator it = compilationUnits.constBegin(), end = compilationUnits.constEnd(); - it != end; ++it) - (*it)->markObjects(this); - } + for (QSet<CompiledData::CompilationUnit*>::ConstIterator it = compilationUnits.constBegin(), end = compilationUnits.constEnd(); + it != end; ++it) + (*it)->markObjects(this); } ReturnedValue ExecutionEngine::throwError(const Value &value) diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index cf2ebe268d..fdfdeada9a 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -446,7 +446,7 @@ public: void requireArgumentsAccessors(int n); - void markObjects(bool incremental); + void markObjects(); void initRootContext(); diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h index 1347a9bd6e..6c7da91ba0 100644 --- a/src/qml/memory/qv4heap_p.h +++ b/src/qml/memory/qv4heap_p.h @@ -127,6 +127,8 @@ struct Q_QML_EXPORT Base { return Chunk::testBit(c->objectBitmap, h - c->realBase()); } + inline void markChildren(ExecutionEngine *engine); + void *operator new(size_t, Managed *m) { return m; } void *operator new(size_t, Heap::Base *m) { return m; } void operator delete(void *, Heap::Base *) {} diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index f117bbc10f..28330a93c9 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -260,6 +260,62 @@ void ChunkAllocator::free(Chunk *chunk, size_t size) } +void Heap::Base::markChildren(ExecutionEngine *engine) +{ + if (vtable()->markObjects) + vtable()->markObjects(this, engine); + if (quint64 m = vtable()->markTable) { +// qDebug() << "using mark table:" << hex << m << "for" << h; + void **mem = reinterpret_cast<void **>(this); + while (m) { + MarkFlags mark = static_cast<MarkFlags>(m & 3); + switch (mark) { + case Mark_NoMark: + break; + case Mark_Value: +// qDebug() << "marking value at " << mem; + reinterpret_cast<Value *>(mem)->mark(engine); + break; + case Mark_Pointer: { +// qDebug() << "marking pointer at " << mem; + Heap::Base *p = *reinterpret_cast<Heap::Base **>(mem); + if (p) + p->mark(engine); + break; + } + case Mark_ValueArray: { + Q_ASSERT(m == Mark_ValueArray); +// qDebug() << "marking Value Array at offset" << hex << (mem - reinterpret_cast<void **>(h)); + ValueArray<0> *a = reinterpret_cast<ValueArray<0> *>(mem); + Value *v = a->values; + const Value *end = v + a->alloc; + if (a->alloc > 32*1024) { + // drain from time to time to avoid overflows in the js stack + Value *currentBase = engine->jsStackTop; + while (v < end) { + v->mark(engine); + ++v; + if (engine->jsStackTop >= currentBase + 32*1024) + engine->memoryManager->drainMarkStack(currentBase); + } + + } else { + while (v < end) { + v->mark(engine); + ++v; + } + } + break; + } + } + + m >>= 2; + ++mem; + } + } +} + + void Chunk::sweep() { // DEBUG << "sweeping chunk" << this << (*freeList); @@ -858,57 +914,7 @@ void MemoryManager::drainMarkStack(Value *markBase) Heap::Base *h = engine->popForGC(); ++markStackSize; Q_ASSERT(h); // at this point we should only have Heap::Base objects in this area on the stack. If not, weird things might happen. - if (h->vtable()->markObjects) - h->vtable()->markObjects(h, engine); - if (quint64 m = h->vtable()->markTable) { -// qDebug() << "using mark table:" << hex << m << "for" << h; - void **mem = reinterpret_cast<void **>(h); - while (m) { - MarkFlags mark = static_cast<MarkFlags>(m & 3); - switch (mark) { - case Mark_NoMark: - break; - case Mark_Value: -// qDebug() << "marking value at " << mem; - reinterpret_cast<Value *>(mem)->mark(engine); - break; - case Mark_Pointer: { -// qDebug() << "marking pointer at " << mem; - Heap::Base *p = *reinterpret_cast<Heap::Base **>(mem); - if (p) - p->mark(engine); - break; - } - case Mark_ValueArray: { - Q_ASSERT(m == Mark_ValueArray); -// qDebug() << "marking Value Array at offset" << hex << (mem - reinterpret_cast<void **>(h)); - ValueArray<0> *a = reinterpret_cast<ValueArray<0> *>(mem); - Value *v = a->values; - const Value *end = v + a->alloc; - if (a->alloc > 32*1024) { - // drain from time to time to avoid overflows in the js stack - Value *currentBase = engine->jsStackTop; - while (v < end) { - v->mark(engine); - ++v; - if (engine->jsStackTop >= currentBase + 32*1024) - drainMarkStack(currentBase); - } - - } else { - while (v < end) { - v->mark(engine); - ++v; - } - } - break; - } - } - - m >>= 2; - ++mem; - } - } + h->markChildren(engine); } } @@ -918,16 +924,11 @@ void MemoryManager::mark() markStackSize = 0; - if (nextGCIsIncremental) { - // need to collect all gray items and push them onto the mark stack - blockAllocator.collectGrayItems(engine); - hugeItemAllocator.collectGrayItems(engine); - } - // qDebug() << ">>>> Mark phase:"; // qDebug() << " mark stack after gray items" << (engine->jsStackTop - markBase); - engine->markObjects(nextGCIsIncremental); + if (!nextGCIsIncremental) + engine->markObjects(); // qDebug() << " mark stack after engine->mark" << (engine->jsStackTop - markBase); @@ -969,6 +970,12 @@ void MemoryManager::mark() drainMarkStack(markBase); } + if (nextGCIsIncremental) { + // need to collect all gray items and push them onto the mark stack + blockAllocator.collectGrayItems(engine); + hugeItemAllocator.collectGrayItems(engine); + } + drainMarkStack(markBase); } |