aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-11-02 16:30:26 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-05 18:54:51 +0100
commit025365f1dc6dc9c3244a125882433e55b57fa672 (patch)
tree6cab46d0595e7c9a8b61c8f2eb620dba009f30f8
parentc9a90b3181723061e27e7545b70a66dda4f4306d (diff)
Refactor marking GC'ed objects
Don't use recursive function calls anymore. Instead, push marked objects onto the JS stack, and then pop them off when their children are being marked. Should reduce stack memory usage, and improves performance by ~5%. Change-Id: I2d37d97579144fcba87ec8e9fd545dd220c01fbb Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/compiler/qv4compileddata.cpp10
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4context.cpp18
-rw-r--r--src/qml/jsruntime/qv4engine.cpp94
-rw-r--r--src/qml/jsruntime/qv4engine_p.h22
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4function.cpp8
-rw-r--r--src/qml/jsruntime/qv4function_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp18
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h4
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp2
-rw-r--r--src/qml/jsruntime/qv4managed_p.h10
-rw-r--r--src/qml/jsruntime/qv4mm.cpp32
-rw-r--r--src/qml/jsruntime/qv4mm_p.h3
-rw-r--r--src/qml/jsruntime/qv4object.cpp18
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp8
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h2
-rw-r--r--src/qml/jsruntime/qv4qmlextensions.cpp4
-rw-r--r--src/qml/jsruntime/qv4qmlextensions_p.h3
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp14
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h2
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp3
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h2
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4script.cpp6
-rw-r--r--src/qml/jsruntime/qv4script_p.h2
-rw-r--r--src/qml/jsruntime/qv4string.cpp6
-rw-r--r--src/qml/jsruntime/qv4string_p.h2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4value.cpp4
-rw-r--r--src/qml/jsruntime/qv4value_def_p.h4
-rw-r--r--src/qml/jsruntime/qv4value_p.h11
-rw-r--r--src/qml/qml/qqmlcomponent.cpp12
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp8
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h2
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp4
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp6
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp5
45 files changed, 202 insertions, 191 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 51f39e7e6c..ce0c7abf9e 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -158,20 +158,20 @@ void CompilationUnit::unlink()
runtimeFunctions.clear();
}
-void CompilationUnit::markObjects()
+void CompilationUnit::markObjects(QV4::ExecutionEngine *e)
{
for (uint i = 0; i < data->stringTableSize; ++i)
- runtimeStrings[i].mark();
+ runtimeStrings[i].mark(e);
if (runtimeRegularExpressions) {
for (uint i = 0; i < data->regexpTableSize; ++i)
- runtimeRegularExpressions[i].mark();
+ runtimeRegularExpressions[i].mark(e);
}
for (int i = 0; i < runtimeFunctions.count(); ++i)
if (runtimeFunctions[i])
- runtimeFunctions[i]->mark();
+ runtimeFunctions[i]->mark(e);
if (runtimeLookups) {
for (uint i = 0; i < data->lookupTableSize; ++i)
- runtimeLookups[i].name->mark();
+ runtimeLookups[i].name->mark(e);
}
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 1c0d72e521..bfbb40445a 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -505,7 +505,7 @@ struct Q_QML_EXPORT CompilationUnit
// ### runtime data
// pointer to qml data for QML unit
- void markObjects();
+ void markObjects(QV4::ExecutionEngine *e);
protected:
virtual void linkBackendToEngine(QV4::ExecutionEngine *engine) = 0;
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 13075f05ed..ed010b1230 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -174,12 +174,12 @@ ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
return Encode::undefined();
}
-void ArgumentsObject::markObjects(Managed *that)
+void ArgumentsObject::markObjects(Managed *that, ExecutionEngine *e)
{
ArgumentsObject *o = static_cast<ArgumentsObject *>(that);
o->context->mark();
for (int i = 0; i < o->mappedArguments.size(); ++i)
- o->mappedArguments.at(i).mark();
+ o->mappedArguments.at(i).mark(e);
- Object::markObjects(that);
+ Object::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 33245ca2fd..7a5b0817a3 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -85,7 +85,7 @@ struct ArgumentsObject: Object {
};
bool defineOwnProperty(ExecutionContext *ctx, uint index, const Property &desc, PropertyAttributes attrs);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
protected:
static void destroy(Managed *);
};
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index a8628d6fa8..b401032293 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -327,27 +327,27 @@ void ExecutionContext::mark()
if (type != Type_SimpleCallContext && outer)
outer->mark();
- callData->thisObject.mark();
+ callData->thisObject.mark(engine);
for (int arg = 0; arg < callData->argc; ++arg)
- callData->args[arg].mark();
+ callData->args[arg].mark(engine);
if (type >= Type_CallContext) {
QV4::CallContext *c = static_cast<CallContext *>(this);
for (unsigned local = 0, lastLocal = c->variableCount(); local < lastLocal; ++local)
- c->locals[local].mark();
+ c->locals[local].mark(engine);
if (c->activation)
- c->activation->mark();
- c->function->mark();
+ c->activation->mark(engine);
+ c->function->mark(engine);
} else if (type == Type_WithContext) {
WithContext *w = static_cast<WithContext *>(this);
- w->withObject->mark();
+ w->withObject->mark(engine);
} else if (type == Type_CatchContext) {
CatchContext *c = static_cast<CatchContext *>(this);
- c->exceptionVarName->mark();
- c->exceptionValue.mark();
+ c->exceptionVarName->mark(engine);
+ c->exceptionValue.mark(engine);
} else if (type == Type_GlobalContext) {
GlobalContext *g = static_cast<GlobalContext *>(this);
- g->global->mark();
+ g->global->mark(engine);
}
}
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 6cb269d842..5d22dde98c 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -682,19 +682,19 @@ void ExecutionEngine::requireArgumentsAccessors(int n)
void ExecutionEngine::markObjects()
{
- identifierTable->mark();
+ identifierTable->mark(this);
- globalObject->mark();
+ globalObject->mark(this);
if (globalCode)
- globalCode->mark();
+ globalCode->mark(this);
for (int i = 0; i < argumentsAccessors.size(); ++i) {
const Property &pd = argumentsAccessors.at(i);
if (FunctionObject *getter = pd.getter())
- getter->mark();
+ getter->mark(this);
if (FunctionObject *setter = pd.setter())
- setter->mark();
+ setter->mark(this);
}
ExecutionContext *c = current;
@@ -703,55 +703,55 @@ void ExecutionEngine::markObjects()
c = c->parent;
}
- id_length->mark();
- id_prototype->mark();
- id_constructor->mark();
- id_arguments->mark();
- id_caller->mark();
- id_this->mark();
- id___proto__->mark();
- id_enumerable->mark();
- id_configurable->mark();
- id_writable->mark();
- id_value->mark();
- id_get->mark();
- id_set->mark();
- id_eval->mark();
- id_uintMax->mark();
- id_name->mark();
- id_index->mark();
- id_input->mark();
- id_toString->mark();
- id_valueOf->mark();
-
- objectCtor.mark();
- stringCtor.mark();
- numberCtor.mark();
- booleanCtor.mark();
- arrayCtor.mark();
- functionCtor.mark();
- dateCtor.mark();
- regExpCtor.mark();
- errorCtor.mark();
- evalErrorCtor.mark();
- rangeErrorCtor.mark();
- referenceErrorCtor.mark();
- syntaxErrorCtor.mark();
- typeErrorCtor.mark();
- uRIErrorCtor.mark();
-
- exceptionValue.mark();
-
- thrower->mark();
+ id_length->mark(this);
+ id_prototype->mark(this);
+ id_constructor->mark(this);
+ id_arguments->mark(this);
+ id_caller->mark(this);
+ id_this->mark(this);
+ id___proto__->mark(this);
+ id_enumerable->mark(this);
+ id_configurable->mark(this);
+ id_writable->mark(this);
+ id_value->mark(this);
+ id_get->mark(this);
+ id_set->mark(this);
+ id_eval->mark(this);
+ id_uintMax->mark(this);
+ id_name->mark(this);
+ id_index->mark(this);
+ id_input->mark(this);
+ id_toString->mark(this);
+ id_valueOf->mark(this);
+
+ objectCtor.mark(this);
+ stringCtor.mark(this);
+ numberCtor.mark(this);
+ booleanCtor.mark(this);
+ arrayCtor.mark(this);
+ functionCtor.mark(this);
+ dateCtor.mark(this);
+ regExpCtor.mark(this);
+ errorCtor.mark(this);
+ evalErrorCtor.mark(this);
+ rangeErrorCtor.mark(this);
+ referenceErrorCtor.mark(this);
+ syntaxErrorCtor.mark(this);
+ typeErrorCtor.mark(this);
+ uRIErrorCtor.mark(this);
+
+ exceptionValue.mark(this);
+
+ thrower->mark(this);
if (m_qmlExtensions)
- m_qmlExtensions->markObjects();
+ m_qmlExtensions->markObjects(this);
emptyClass->markObjects();
for (QSet<CompiledData::CompilationUnit*>::ConstIterator it = compilationUnits.constBegin(), end = compilationUnits.constEnd();
it != end; ++it)
- (*it)->markObjects();
+ (*it)->markObjects(this);
}
namespace {
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index b49964a669..c585714dd0 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -134,11 +134,20 @@ struct Q_QML_EXPORT ExecutionEngine
jsStackTop = ptr + nValues;
return ptr;
}
-
void stackPop(uint nValues) {
jsStackTop -= nValues;
}
+ void pushForGC(Managed *m) {
+ *jsStackTop = Value::fromManaged(m);
+ ++jsStackTop;
+ }
+ Managed *popForGC() {
+ --jsStackTop;
+ return jsStackTop->managed();
+ }
+
+
IdentifierTable *identifierTable;
QV4::Debugging::Debugger *debugger;
@@ -365,6 +374,17 @@ struct ExecutionContextSaver
}
};
+inline
+void Managed::mark(QV4::ExecutionEngine *engine)
+{
+ if (markBit)
+ return;
+ markBit = 1;
+ engine->pushForGC(this);
+}
+
+
+
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index f149bc556e..3f75bc0c79 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -192,12 +192,12 @@ ReturnedValue ErrorObject::method_get_stack(SimpleCallContext *ctx)
return This->stack->asReturnedValue();
}
-void ErrorObject::markObjects(Managed *that)
+void ErrorObject::markObjects(Managed *that, ExecutionEngine *e)
{
ErrorObject *This = that->asErrorObject();
if (This->stack)
- This->stack->mark();
- Object::markObjects(that);
+ This->stack->mark(e);
+ Object::markObjects(that, e);
}
DEFINE_MANAGED_VTABLE(ErrorObject);
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index ff43f54f3e..b46bea5231 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -74,7 +74,7 @@ struct ErrorObject: Object {
String *stack;
static ReturnedValue method_get_stack(SimpleCallContext *ctx);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
static void destroy(Managed *that) { static_cast<ErrorObject *>(that)->~ErrorObject(); }
};
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 99d5de4fe5..c3d2165fb4 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -81,13 +81,13 @@ Function::~Function()
}
-void Function::mark()
+void Function::mark(ExecutionEngine *e)
{
- name.mark();
+ name.mark(e);
for (int i = 0; i < formals.size(); ++i)
- formals.at(i)->mark();
+ formals.at(i)->mark(e);
for (int i = 0; i < locals.size(); ++i)
- locals.at(i)->mark();
+ locals.at(i)->mark(e);
}
namespace QV4 {
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 35c98897a0..f29891e3b3 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -126,7 +126,7 @@ struct Function {
inline bool needsActivation() const
{ return compiledFunction->nInnerFunctions > 0 || (compiledFunction->flags & (CompiledData::Function::HasDirectEval | CompiledData::Function::UsesArgumentsObject)); }
- void mark();
+ void mark(ExecutionEngine *e);
int lineNumberForProgramCounter(qptrdiff offset) const;
};
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index d8029548f4..81844582a3 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -203,11 +203,11 @@ ReturnedValue FunctionObject::call(Managed *, CallData *)
return Encode::undefined();
}
-void FunctionObject::markObjects(Managed *that)
+void FunctionObject::markObjects(Managed *that, ExecutionEngine *e)
{
FunctionObject *o = static_cast<FunctionObject *>(that);
if (o->name.managed())
- o->name->mark();
+ o->name->mark(e);
// these are marked in VM::Function:
// for (uint i = 0; i < formalParameterCount; ++i)
// formalParameterList[i]->mark();
@@ -215,9 +215,9 @@ void FunctionObject::markObjects(Managed *that)
// varList[i]->mark();
o->scope->mark();
if (o->function)
- o->function->mark();
+ o->function->mark(e);
- Object::markObjects(that);
+ Object::markObjects(that, e);
}
FunctionObject *FunctionObject::creatScriptFunction(ExecutionContext *scope, Function *function)
@@ -703,12 +703,12 @@ bool BoundFunction::hasInstance(Managed *that, const ValueRef value)
return FunctionObject::hasInstance(f->target, value);
}
-void BoundFunction::markObjects(Managed *that)
+void BoundFunction::markObjects(Managed *that, ExecutionEngine *e)
{
BoundFunction *o = static_cast<BoundFunction *>(that);
- o->target->mark();
- o->boundThis.mark();
+ o->target->mark(e);
+ o->boundThis.mark(e);
for (int i = 0; i < o->boundArgs.size(); ++i)
- o->boundArgs.at(i).mark();
- FunctionObject::markObjects(that);
+ o->boundArgs.at(i).mark(e);
+ FunctionObject::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index fe69625061..3f526947a0 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -139,7 +139,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
protected:
FunctionObject(InternalClass *ic);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
static bool hasInstance(Managed *that, const ValueRef value);
static void destroy(Managed *that)
{ static_cast<FunctionObject*>(that)->~FunctionObject(); }
@@ -234,7 +234,7 @@ struct BoundFunction: FunctionObject {
static ReturnedValue call(Managed *that, CallData *dd);
static void destroy(Managed *);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
static bool hasInstance(Managed *that, const ValueRef value);
};
diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h
index a02d90e7e2..02fc8b70c6 100644
--- a/src/qml/jsruntime/qv4identifiertable_p.h
+++ b/src/qml/jsruntime/qv4identifiertable_p.h
@@ -79,10 +79,10 @@ public:
Identifier *identifierImpl(const String *str);
- void mark() {
+ void mark(ExecutionEngine *e) {
for (int i = 0; i < alloc; ++i)
if (entries[i])
- entries[i]->mark();
+ entries[i]->mark(e);
}
};
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index c3dd3e0505..4f4309769a 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -348,7 +348,7 @@ void InternalClass::markObjects()
it != end; ++it) {
if (it.key().flags == Transition::ProtoChange) {
Q_ASSERT(it.value()->prototype);
- it.value()->prototype->mark();
+ it.value()->prototype->mark(engine);
}
}
}
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index b4469c8048..47ac5e05e4 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -81,7 +81,7 @@ struct ManagedVTable
{
ReturnedValue (*call)(Managed *, CallData *data);
ReturnedValue (*construct)(Managed *, CallData *data);
- void (*markObjects)(Managed *);
+ void (*markObjects)(Managed *, ExecutionEngine *e);
void (*destroy)(Managed *);
void (*collectDeletables)(Managed *, GCDeletable **deletable);
bool (*hasInstance)(Managed *, const ValueRef value);
@@ -166,13 +166,7 @@ public:
void operator delete(void *ptr);
void operator delete(void *ptr, MemoryManager *mm);
- inline void mark() {
- if (markBit)
- return;
- markBit = 1;
- if (vtbl->markObjects)
- vtbl->markObjects(this);
- }
+ inline void mark(QV4::ExecutionEngine *engine);
enum Type {
Type_Invalid,
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index a03f2865f1..057a583dc3 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -152,7 +152,6 @@ struct MemoryManager::Data
};
QVector<Chunk> heapChunks;
- QHash<Managed *, uint> protectedObject;
// statistics:
#ifdef DETAILED_MM_STATS
@@ -316,10 +315,9 @@ Managed *MemoryManager::alloc(std::size_t size)
void MemoryManager::mark()
{
- m_d->engine->markObjects();
+ SafeValue *markBase = m_d->engine->jsStackTop;
- for (QHash<Managed *, uint>::const_iterator it = m_d->protectedObject.begin(); it != m_d->protectedObject.constEnd(); ++it)
- it.key()->mark();
+ m_d->engine->markObjects();
PersistentValuePrivate *persistent = m_persistentValues;
while (persistent) {
@@ -330,7 +328,7 @@ void MemoryManager::mark()
persistent = n;
continue;
}
- persistent->value.mark();
+ persistent->value.mark(m_d->engine);
persistent = persistent->next;
}
@@ -394,7 +392,14 @@ void MemoryManager::mark()
}
if (keepAlive)
- qobjectWrapper->getPointer()->mark();
+ qobjectWrapper->getPointer()->mark(m_d->engine);
+ }
+
+ // now that we marked all roots, start marking recursively and popping from the mark stack
+ while (m_d->engine->jsStackTop > markBase) {
+ Managed *m = m_d->engine->popForGC();
+ Q_ASSERT (m->vtbl->markObjects);
+ m->vtbl->markObjects(m, m_d->engine);
}
}
@@ -558,17 +563,6 @@ MemoryManager::~MemoryManager()
#endif
}
-void MemoryManager::protect(Managed *m)
-{
- ++m_d->protectedObject[m];
-}
-
-void MemoryManager::unprotect(Managed *m)
-{
- if (!--m_d->protectedObject[m])
- m_d->protectedObject.remove(m);
-}
-
void MemoryManager::setExecutionEngine(ExecutionEngine *engine)
{
m_d->engine = engine;
@@ -651,7 +645,7 @@ void MemoryManager::collectFromStack() const
continue;
// qDebug() << " marking";
- m->mark();
+ m->mark(m_d->engine);
}
}
}
@@ -664,7 +658,7 @@ void MemoryManager::collectFromJSStack() const
Managed *m = v->asManaged();
if (m && m->inUse)
// Skip pointers to already freed objects, they are bogus as well
- m->mark();
+ m->mark(m_d->engine);
++v;
}
}
diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/jsruntime/qv4mm_p.h
index 95f49545b8..f3258519de 100644
--- a/src/qml/jsruntime/qv4mm_p.h
+++ b/src/qml/jsruntime/qv4mm_p.h
@@ -91,9 +91,6 @@ public:
MemoryManager();
~MemoryManager();
- void protect(Managed *m);
- void unprotect(Managed *m);
-
// TODO: this is only for 64bit (and x86 with SSE/AVX), so exend it for other architectures to be slightly more efficient (meaning, align on 8-byte boundaries).
// Note: all occurances of "16" in alloc/dealloc are also due to the alignment.
static inline std::size_t align(std::size_t size)
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 25443a59c2..66b1b58b67 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -239,40 +239,40 @@ void Object::defineReadonlyProperty(const StringRef name, ValueRef value)
pd->value = *value;
}
-void Object::markObjects(Managed *that)
+void Object::markObjects(Managed *that, ExecutionEngine *e)
{
Object *o = static_cast<Object *>(that);
if (!o->hasAccessorProperty) {
for (uint i = 0; i < o->internalClass->size; ++i)
- o->memberData[i].value.mark();
+ o->memberData[i].value.mark(e);
} else {
for (uint i = 0; i < o->internalClass->size; ++i) {
const Property &pd = o->memberData[i];
if (o->internalClass->propertyData[i].isAccessor()) {
if (pd.getter())
- pd.getter()->mark();
+ pd.getter()->mark(e);
if (pd.setter())
- pd.setter()->mark();
+ pd.setter()->mark(e);
} else {
- pd.value.mark();
+ pd.value.mark(e);
}
}
}
if (o->flags & SimpleArray) {
for (uint i = 0; i < o->arrayDataLen; ++i)
- o->arrayData[i].value.mark();
+ o->arrayData[i].value.mark(e);
return;
} else {
for (uint i = 0; i < o->arrayDataLen; ++i) {
const Property &pd = o->arrayData[i];
if (o->arrayAttributes && o->arrayAttributes[i].isAccessor()) {
if (pd.getter())
- pd.getter()->mark();
+ pd.getter()->mark(e);
if (pd.setter())
- pd.setter()->mark();
+ pd.setter()->mark(e);
} else {
- pd.value.mark();
+ pd.value.mark(e);
}
}
}
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 097d40db55..33f785ec90 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -300,7 +300,7 @@ public:
using Managed::advanceIterator;
protected:
static void destroy(Managed *that);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, const StringRef name, const ValueRef value);
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index cec0873527..62595b5176 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -174,10 +174,10 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
DEFINE_MANAGED_VTABLE(ForEachIteratorObject);
-void ForEachIteratorObject::markObjects(Managed *that)
+void ForEachIteratorObject::markObjects(Managed *that, ExecutionEngine *e)
{
ForEachIteratorObject *o = static_cast<ForEachIteratorObject *>(that);
- o->workArea[0].mark();
- o->workArea[1].mark();
- Object::markObjects(that);
+ o->workArea[0].mark(e);
+ o->workArea[1].mark(e);
+ Object::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index e38fa8d7b6..19aedf3766 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -96,7 +96,7 @@ struct ForEachIteratorObject: Object {
ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }
protected:
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
SafeObject workArea[2];
};
diff --git a/src/qml/jsruntime/qv4qmlextensions.cpp b/src/qml/jsruntime/qv4qmlextensions.cpp
index a55330ff67..547813bc66 100644
--- a/src/qml/jsruntime/qv4qmlextensions.cpp
+++ b/src/qml/jsruntime/qv4qmlextensions.cpp
@@ -44,8 +44,8 @@
using namespace QV4;
-void QmlExtensions::markObjects()
+void QmlExtensions::markObjects(ExecutionEngine *e)
{
if (valueTypeWrapperPrototype)
- valueTypeWrapperPrototype->mark();
+ valueTypeWrapperPrototype->mark(e);
}
diff --git a/src/qml/jsruntime/qv4qmlextensions_p.h b/src/qml/jsruntime/qv4qmlextensions_p.h
index cf9e287efe..b1e8052fc2 100644
--- a/src/qml/jsruntime/qv4qmlextensions_p.h
+++ b/src/qml/jsruntime/qv4qmlextensions_p.h
@@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct Object;
+struct ExecutionEngine;
struct Q_QML_EXPORT QmlExtensions
{
@@ -56,7 +57,7 @@ struct Q_QML_EXPORT QmlExtensions
Object *valueTypeWrapperPrototype;
- void markObjects();
+ void markObjects(ExecutionEngine *e);
};
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 5284f927d4..07a4ff7cd7 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -932,36 +932,36 @@ ReturnedValue QObjectWrapper::method_disconnect(SimpleCallContext *ctx)
return Encode::undefined();
}
-static void markChildQObjectsRecursively(QObject *parent)
+static void markChildQObjectsRecursively(QObject *parent, QV4::ExecutionEngine *e)
{
const QObjectList &children = parent->children();
for (int i = 0; i < children.count(); ++i) {
QObject *child = children.at(i);
QQmlData *ddata = QQmlData::get(child, /*create*/false);
if (ddata)
- ddata->jsWrapper.markOnce();
- markChildQObjectsRecursively(child);
+ ddata->jsWrapper.markOnce(e);
+ markChildQObjectsRecursively(child, e);
}
}
-void QObjectWrapper::markObjects(Managed *that)
+void QObjectWrapper::markObjects(Managed *that, QV4::ExecutionEngine *e)
{
QObjectWrapper *This = static_cast<QObjectWrapper*>(that);
if (QObject *o = This->m_object.data()) {
QQmlVMEMetaObject *vme = QQmlVMEMetaObject::get(o);
if (vme)
- vme->mark();
+ vme->mark(e);
// Children usually don't need to be marked, the gc keeps them alive.
// But in the rare case of a "floating" QObject without a parent that
// _gets_ marked (we've been called here!) then we also need to
// propagate the marking down to the children recursively.
if (!o->parent())
- markChildQObjectsRecursively(o);
+ markChildQObjectsRecursively(o, e);
}
- QV4::Object::markObjects(that);
+ QV4::Object::markObjects(that, e);
}
namespace {
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 4907d926fe..eb3cf15bff 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -114,7 +114,7 @@ private:
static void put(Managed *m, const StringRef name, const ValueRef value);
static PropertyAttributes query(const Managed *, StringRef name);
static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attributes);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, QV4::ExecutionEngine *e);
static void collectDeletables(Managed *m, GCDeletable **deletable);
static void destroy(Managed *that)
{
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index 8c184754ca..5ec63061dc 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -132,9 +132,10 @@ void RegExp::destroy(Managed *that)
static_cast<RegExp*>(that)->~RegExp();
}
-void RegExp::markObjects(Managed *that)
+void RegExp::markObjects(Managed *that, ExecutionEngine *e)
{
Q_UNUSED(that);
+ Q_UNUSED(e);
}
ReturnedValue RegExp::get(Managed *, const StringRef, bool *)
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index f674bea042..9041ff2ef4 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -110,7 +110,7 @@ public:
protected:
static void destroy(Managed *that);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, QV4::ExecutionEngine *e);
static ReturnedValue get(Managed *, const StringRef, bool *);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, const StringRef name, const ValueRef value);
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 02467c3045..7322a58412 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -175,12 +175,12 @@ void RegExpObject::destroy(Managed *that)
static_cast<RegExpObject *>(that)->~RegExpObject();
}
-void RegExpObject::markObjects(Managed *that)
+void RegExpObject::markObjects(Managed *that, ExecutionEngine *e)
{
RegExpObject *re = static_cast<RegExpObject*>(that);
if (re->value)
- re->value->mark();
- Object::markObjects(that);
+ re->value->mark(e);
+ Object::markObjects(that, e);
}
Property *RegExpObject::lastIndexProperty(ExecutionContext *ctx)
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index eb932a49ee..70bc9476e0 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -97,7 +97,7 @@ struct RegExpObject: Object {
protected:
RegExpObject(InternalClass *ic);
static void destroy(Managed *that);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
};
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 49fee99135..26cb0d940c 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -102,12 +102,12 @@ ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *)
return result.asReturnedValue();
}
-void QmlBindingWrapper::markObjects(Managed *m)
+void QmlBindingWrapper::markObjects(Managed *m, ExecutionEngine *e)
{
QmlBindingWrapper *wrapper = static_cast<QmlBindingWrapper*>(m);
if (wrapper->qml)
- wrapper->qml->mark();
- FunctionObject::markObjects(m);
+ wrapper->qml->mark(e);
+ FunctionObject::markObjects(m, e);
wrapper->qmlContext->mark();
}
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index 657923062b..8e11eddb8f 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -61,7 +61,7 @@ struct QmlBindingWrapper : FunctionObject {
QmlBindingWrapper(ExecutionContext *scope, ObjectRef qml);
static ReturnedValue call(Managed *that, CallData *);
- static void markObjects(Managed *m);
+ static void markObjects(Managed *m, ExecutionEngine *e);
CallContext *context() const { return qmlContext; }
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 30b08badcd..eef901d74a 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -129,12 +129,12 @@ void String::destroy(Managed *that)
static_cast<String*>(that)->~String();
}
-void String::markObjects(Managed *that)
+void String::markObjects(Managed *that, ExecutionEngine *e)
{
String *s = static_cast<String *>(that);
if (s->largestSubLength) {
- s->left->mark();
- s->right->mark();
+ s->left->mark(e);
+ s->right->mark(e);
}
}
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 5412371bc0..bb6f1d2279 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -155,7 +155,7 @@ struct Q_QML_EXPORT String : public Managed {
protected:
static void destroy(Managed *);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
static ReturnedValue get(Managed *m, const StringRef name, bool *hasProperty);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, const StringRef name, const ValueRef value);
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 0fc5dee5be..33dd403e9b 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -159,12 +159,12 @@ Property *StringObject::advanceIterator(Managed *m, ObjectIterator *it, StringRe
return Object::advanceIterator(m, it, name, index, attrs);
}
-void StringObject::markObjects(Managed *that)
+void StringObject::markObjects(Managed *that, ExecutionEngine *e)
{
StringObject *o = static_cast<StringObject *>(that);
- o->value.stringValue()->mark();
- o->tmpProperty.value.mark();
- Object::markObjects(that);
+ o->value.stringValue()->mark(e);
+ o->tmpProperty.value.mark(e);
+ Object::markObjects(that, e);
}
DEFINE_MANAGED_VTABLE(StringCtor);
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index e6777380a4..c67f933479 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -63,7 +63,7 @@ struct StringObject: Object {
protected:
StringObject(InternalClass *ic);
static Property *advanceIterator(Managed *m, ObjectIterator *it, StringRef name, uint *index, PropertyAttributes *attrs);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, ExecutionEngine *e);
};
struct StringCtor: FunctionObject
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index a7413e031c..4ae570c8dc 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -396,11 +396,11 @@ WeakValue::~WeakValue()
d->deref();
}
-void WeakValue::markOnce()
+void WeakValue::markOnce(ExecutionEngine *e)
{
if (!d)
return;
- d->value.mark();
+ d->value.mark(e);
}
PersistentValuePrivate::PersistentValuePrivate(ReturnedValue v, ExecutionEngine *e, bool weak)
diff --git a/src/qml/jsruntime/qv4value_def_p.h b/src/qml/jsruntime/qv4value_def_p.h
index 163aed9abc..615f6218e4 100644
--- a/src/qml/jsruntime/qv4value_def_p.h
+++ b/src/qml/jsruntime/qv4value_def_p.h
@@ -335,7 +335,7 @@ struct Q_QML_EXPORT Value
// Section 9.12
bool sameValue(Value other) const;
- inline void mark() const;
+ inline void mark(ExecutionEngine *e) const;
};
inline Managed *Value::asManaged() const
@@ -445,7 +445,7 @@ struct Safe : public SafeValue
T *getPointer() const { return static_cast<T *>(managed()); }
Returned<T> *ret() const;
- void mark() { if (managed()) managed()->mark(); }
+ void mark(ExecutionEngine *e) { if (managed()) managed()->mark(e); }
};
typedef Safe<String> SafeString;
typedef Safe<Object> SafeObject;
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index a2137ee849..ad9ca708c1 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -49,6 +49,7 @@
#include "qv4string_p.h"
#include <QtCore/QDebug>
#include "qv4managed_p.h"
+#include "qv4engine_p.h"
#include <private/qtqmlglobal_p.h>
//#include <wtf/MathExtras.h>
@@ -77,17 +78,19 @@ inline bool Value::isPrimitive() const
return !isObject();
}
-inline ExecutionEngine *Value::engine() const {
+inline ExecutionEngine *Value::engine() const
+{
Managed *m = asManaged();
return m ? m->engine() : 0;
}
-inline void Value::mark() const {
+inline void Value::mark(ExecutionEngine *e) const
+{
if (!val)
return;
Managed *m = asManaged();
if (m)
- m->mark();
+ m->mark(e);
}
inline Primitive Primitive::nullValue()
@@ -389,7 +392,7 @@ public:
*this = WeakValue();
}
- void markOnce();
+ void markOnce(ExecutionEngine *e);
private:
friend struct ValueRef;
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index cb05a2bef8..ea88acd85f 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1120,7 +1120,7 @@ public:
static QV4::ReturnedValue method_forceCompletion(QV4::SimpleCallContext *ctx);
static void destroy(Managed *that);
- static void markObjects(Managed *that);
+ static void markObjects(Managed *that, QV4::ExecutionEngine *e);
QScopedPointer<QQmlComponentIncubator> incubator;
QV8Engine *v8;
@@ -1538,14 +1538,14 @@ void QmlIncubatorObject::destroy(Managed *that)
o->~QmlIncubatorObject();
}
-void QmlIncubatorObject::markObjects(QV4::Managed *that)
+void QmlIncubatorObject::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e)
{
QmlIncubatorObject *o = that->as<QmlIncubatorObject>();
Q_ASSERT(o);
- o->valuemap.mark();
- o->qmlGlobal.mark();
- o->m_statusChanged.mark();
- Object::markObjects(that);
+ o->valuemap.mark(e);
+ o->qmlGlobal.mark(e);
+ o->m_statusChanged.mark(e);
+ Object::markObjects(that, e);
}
void QmlIncubatorObject::statusChanged(QQmlIncubator::Status s)
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 1547b2a89d..4b34792421 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -1232,9 +1232,9 @@ void QQmlVMEMetaObject::ensureQObjectWrapper()
QV4::QObjectWrapper::wrap(v4, object);
}
-void QQmlVMEMetaObject::mark()
+void QQmlVMEMetaObject::mark(QV4::ExecutionEngine *e)
{
- varProperties.markOnce();
+ varProperties.markOnce(e);
// add references created by VMEVariant properties
int maxDataIdx = metaData->propertyCount - metaData->varPropertyCount;
@@ -1245,13 +1245,13 @@ void QQmlVMEMetaObject::mark()
if (ref) {
QQmlData *ddata = QQmlData::get(ref);
if (ddata)
- ddata->jsWrapper.markOnce();
+ ddata->jsWrapper.markOnce(e);
}
}
}
if (QQmlVMEMetaObject *parent = parentVMEMetaObject())
- parent->mark();
+ parent->mark(e);
}
void QQmlVMEMetaObject::allocateVarPropertiesArray()
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 25a577d2e6..a9a0308ded 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -209,7 +209,7 @@ public:
void ensureQObjectWrapper();
- void mark();
+ void mark(QV4::ExecutionEngine *e);
void connectAlias(int aliasId);
QBitArray aConnected;
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index ab4c94704c..43adce3e8c 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -1646,10 +1646,10 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
static void destroy(Managed *that) {
that->as<QQmlXMLHttpRequestCtor>()->~QQmlXMLHttpRequestCtor();
}
- static void markObjects(Managed *that) {
+ static void markObjects(Managed *that, ExecutionEngine *e) {
QQmlXMLHttpRequestCtor *c = that->as<QQmlXMLHttpRequestCtor>();
if (c->proto)
- c->proto->mark();
+ c->proto->mark(e);
}
static ReturnedValue construct(Managed *that, QV4::CallData *)
{
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index c02096614b..adbd4da0eb 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1193,11 +1193,11 @@ struct BindingFunction : public QV4::FunctionObject
return This->originalFunction->call(callData);
}
- static void markObjects(Managed *that)
+ static void markObjects(Managed *that, ExecutionEngine *e)
{
BindingFunction *This = static_cast<BindingFunction*>(that);
- This->originalFunction->mark();
- QV4::FunctionObject::markObjects(that);
+ This->originalFunction->mark(e);
+ QV4::FunctionObject::markObjects(that, e);
}
QV4::FunctionObject *originalFunction;
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 3088c41cd7..99dfff47a2 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -908,8 +908,9 @@ struct QQuickJSContext2DImageData : public QV4::Object
static QV4::ReturnedValue method_get_height(QV4::SimpleCallContext *ctx);
static QV4::ReturnedValue method_get_data(QV4::SimpleCallContext *ctx);
- static void markObjects(Managed *that) {
- static_cast<QQuickJSContext2DImageData *>(that)->pixelData.mark();
+ static void markObjects(Managed *that, QV4::ExecutionEngine *engine) {
+ static_cast<QQuickJSContext2DImageData *>(that)->pixelData.mark(engine);
+ QV4::Object::markObjects(that, engine);
}