aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-09-08 15:20:02 +0200
committerLiang Qi <liang.qi@qt.io>2017-09-10 19:45:49 +0000
commit38ef59b386e5eb5063b9572d2dfc1a7d59624ef3 (patch)
tree84fd50f68e46f6341eae3d1a27910298fb7b0a20
parent0b73daa4f6858aa8d52e6b958d8f0b3209858b80 (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>
-rw-r--r--src/qml/jsruntime/qv4engine.cpp16
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)