From 52fcb218c379bb2008e24a2b5b00b613219ba7f6 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 16 Apr 2014 09:36:38 +0200 Subject: Fix marking of prototype objects in internal class pool As per reported bug, we have to protect ourselves against potential loops and can mark the internal classes much simpler by just walking through the memory pool they were allocated in. Task-number: QTBUG-38299 Change-Id: I3ae96e8082e76d06f4321c5aa6d2e9645d2830a0 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4internalclass.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'src/qml/jsruntime/qv4internalclass.cpp') diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index aacc5bf517..3dc20b8e76 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -129,7 +129,7 @@ uint PropertyHash::lookup(const Identifier *identifier) const InternalClass::InternalClass(ExecutionEngine *engine) : engine(engine) , prototype(0) - , vtable(&Managed::static_vtbl) + , vtable(&QV4::Managed::static_vtbl) , m_sealed(0) , m_frozen(0) , size(0) @@ -138,7 +138,8 @@ InternalClass::InternalClass(ExecutionEngine *engine) InternalClass::InternalClass(const QV4::InternalClass &other) - : engine(other.engine) + : QQmlJS::Managed() + , engine(other.engine) , prototype(other.prototype) , vtable(other.vtable) , propertyTable(other.propertyTable) @@ -455,17 +456,24 @@ void InternalClass::destroy() transitions.clear(); } -void InternalClass::markObjects() +struct InternalClassPoolVisitor { - // all prototype changes are done on the empty class - Q_ASSERT(!prototype || this != engine->emptyClass); - - if (prototype) - prototype->mark(engine); + ExecutionEngine *engine; + void operator()(InternalClass *klass) + { + // all prototype changes are done on the empty class + Q_ASSERT(!klass->prototype || klass != engine->emptyClass); + + if (klass->prototype) + klass->prototype->mark(engine); + } +}; - for (QHash::ConstIterator it = transitions.begin(), end = transitions.end(); - it != end; ++it) - it.value()->markObjects(); +void InternalClassPool::markObjects(ExecutionEngine *engine) +{ + InternalClassPoolVisitor v; + v.engine = engine; + visitManagedPool(v); } QT_END_NAMESPACE -- cgit v1.2.3