aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/memory
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-03-31 09:28:53 +0200
committerLars Knoll <lars.knoll@qt.io>2017-04-07 06:06:08 +0000
commit8aa36b6cff134fba3b226cbd596ee256d2c490d2 (patch)
treef2c2387fe97bcffefcd41aa86fb91fb474b30c29 /src/qml/memory
parentfd0ee94d961458760243db8ec7306206905ef4f9 (diff)
Avoid stack overflows during GC runs
When marking very large objects, the old code could overflow the GC stack, as it would push all it's children onto the GC stack. Be more careful about this and drain the mark stack from time to time if required. Change-Id: If11ca521f405ce63b894d4e43a83b68d33a844af Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/memory')
-rw-r--r--src/qml/memory/qv4mm.cpp18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index c025dd09a4..f117bbc10f 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -885,9 +885,21 @@ void MemoryManager::drainMarkStack(Value *markBase)
ValueArray<0> *a = reinterpret_cast<ValueArray<0> *>(mem);
Value *v = a->values;
const Value *end = v + a->alloc;
- while (v < end) {
- v->mark(engine);
- ++v;
+ 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;
}