diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-09-08 15:20:02 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-09-10 19:45:49 +0000 |
commit | 38ef59b386e5eb5063b9572d2dfc1a7d59624ef3 (patch) | |
tree | 84fd50f68e46f6341eae3d1a27910298fb7b0a20 /src | |
parent | 0b73daa4f6858aa8d52e6b958d8f0b3209858b80 (diff) |
Drain the mark stack while collecting roots
This avoids overflows in the markStack for test cases where
we have a huge amount of compilation units with many runtime
strings that all want to get marked.
Task-number: QTBUG-63063
Change-Id: I150c1f1a4065350cec59dd80c5c628920f70e3d0
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index a090ac7c47..d571337ecf 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -927,8 +927,18 @@ void ExecutionEngine::requireArgumentsAccessors(int n) } } +static void drainMarkStack(ExecutionEngine *engine, Value *markBase) +{ + while (engine->jsStackTop > markBase) { + Heap::Base *h = engine->popForGC(); + Q_ASSERT (h->vtable()->markObjects); + h->vtable()->markObjects(h, engine); + } +} + void ExecutionEngine::markObjects() { + Value *markBase = jsStackTop; identifierTable->mark(this); for (int i = 0; i < nArgumentsAccessors; ++i) { @@ -941,9 +951,13 @@ void ExecutionEngine::markObjects() classPool->markObjects(this); + drainMarkStack(this, markBase); + for (QSet<CompiledData::CompilationUnit*>::ConstIterator it = compilationUnits.constBegin(), end = compilationUnits.constEnd(); - it != end; ++it) + it != end; ++it) { (*it)->markObjects(this); + drainMarkStack(this, markBase); + } } ReturnedValue ExecutionEngine::throwError(const Value &value) |