diff options
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); } |