diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2016-06-14 15:44:09 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2016-06-16 18:00:35 +0000 |
commit | 0058ac5f28c64979f359972e03ee91ae146b0cd3 (patch) | |
tree | b9063a18a2182668424ce22e5a3cd95f4e1e2b15 | |
parent | c2c13cacd450d866e60c58c87ff1ab16ae736804 (diff) |
Clean up property cache array handling
The QQmlPropertyCacheVector in the CompilationUnit encapsulates the
property caches for the objects declared in the QML tree as well as the
bits indicating whether a VME meta-object is needed. The ref-counting
for the caches in that vector was done "manually" and thus error prone.
This patch replaces the vector with a wrapper container that has
explicit move semantics and takes care of the addref() and release()
calls upon insertion, replacement and destruction.
Change-Id: If805fe016f1a1c70e56f8a90909ab87b653ea026
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r-- | src/qml/compiler/qqmlpropertycachecreator.cpp | 33 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 63 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 23 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 5 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 7 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 11 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycache_p.h | 43 |
8 files changed, 107 insertions, 80 deletions
diff --git a/src/qml/compiler/qqmlpropertycachecreator.cpp b/src/qml/compiler/qqmlpropertycachecreator.cpp index d5b42752a4..5e696652bd 100644 --- a/src/qml/compiler/qqmlpropertycachecreator.cpp +++ b/src/qml/compiler/qqmlpropertycachecreator.cpp @@ -79,10 +79,6 @@ QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlTypeCompiler *typeCompile QQmlPropertyCacheCreator::~QQmlPropertyCacheCreator() { - for (int i = 0; i < propertyCaches.count(); ++i) - if (QQmlPropertyCache *cache = propertyCaches.at(i).data()) - cache->release(); - propertyCaches.clear(); } bool QQmlPropertyCacheCreator::buildMetaObjects() @@ -97,8 +93,7 @@ bool QQmlPropertyCacheCreator::buildMetaObjects() return false; } - compiler->setPropertyCaches(propertyCaches); - propertyCaches.clear(); + compiler->setPropertyCaches(std::move(propertyCaches)); return true; } @@ -116,8 +111,7 @@ QQmlCompileError QQmlPropertyCacheCreator::buildMetaObjectRecursively(int object // the property that references us, for the latter we only need a meta-object on the referencing object // because interceptors can't go to the shared value type instances. if (context.instantiatingProperty && QQmlValueTypeFactory::isValueType(context.instantiatingProperty->propType)) { - const bool willCreateVMEMetaObject = propertyCaches.at(context.referencingObjectIndex).flag(); - if (!willCreateVMEMetaObject) { + if (!propertyCaches.needsVMEMetaObject(context.referencingObjectIndex)) { const QmlIR::Object *obj = qmlObjects.at(context.referencingObjectIndex); auto *typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex); Q_ASSERT(typeRef); @@ -149,14 +143,11 @@ QQmlCompileError QQmlPropertyCacheCreator::buildMetaObjectRecursively(int object if (error.isSet()) return error; } else { - if (QQmlPropertyCache *oldCache = propertyCaches.at(objectIndex).data()) - oldCache->release(); - propertyCaches[objectIndex] = baseTypeCache; - baseTypeCache->addref(); + propertyCaches.set(objectIndex, baseTypeCache); } } - if (QQmlPropertyCache *thisCache = propertyCaches.at(objectIndex).data()) { + if (QQmlPropertyCache *thisCache = propertyCaches.at(objectIndex)) { for (const QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) if (binding->type >= QV4::CompiledData::Binding::Type_Object) { InstantiationContext context(objectIndex, binding, stringAt(binding->propertyNameIndex), thisCache); @@ -230,15 +221,13 @@ QQmlPropertyCache *QQmlPropertyCacheCreator::propertyCacheForObject(const QmlIR: QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, const QmlIR::Object *obj, QQmlPropertyCache *baseTypeCache) { - QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(obj->propertyCount() + obj->aliasCount(), - obj->functionCount() + obj->propertyCount() + obj->aliasCount() + obj->signalCount(), - obj->signalCount() + obj->propertyCount() + obj->aliasCount()); - - if (QQmlPropertyCache *oldCache = propertyCaches.at(objectIndex).data()) - oldCache->release(); - propertyCaches[objectIndex] = cache; - // Indicate that this object also needs a VME meta-object at run-time - propertyCaches[objectIndex].setFlag(); + QQmlRefPointer<QQmlPropertyCache> cache; + cache.adopt(baseTypeCache->copyAndReserve(obj->propertyCount() + obj->aliasCount(), + obj->functionCount() + obj->propertyCount() + obj->aliasCount() + obj->signalCount(), + obj->signalCount() + obj->propertyCount() + obj->aliasCount())); + + propertyCaches.set(objectIndex, cache); + propertyCaches.setNeedsVMEMetaObject(objectIndex); struct TypeData { QV4::CompiledData::Property::Type dtype; diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index e48b3eb449..3e7fde871c 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -241,13 +241,14 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile() QV4::CompiledData::CompilationUnit *compilationUnit = document->javaScriptCompilationUnit; compilationUnit = document->javaScriptCompilationUnit; - compilationUnit->propertyCaches = m_propertyCaches; compilationUnit->importCache = importCache; compilationUnit->dependentScripts = dependentScripts; compilationUnit->resolvedTypes = m_resolvedTypes; + compilationUnit->propertyCaches = std::move(m_propertyCaches); + Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->data->nObjects)); // Add to type registry of composites - if (compilationUnit->isCompositeType()) + if (compilationUnit->propertyCaches.needsVMEMetaObject(qmlUnit->indexOfRootObject)) engine->registerInternalCompositeType(compilationUnit); else { const QV4::CompiledData::Object *obj = qmlUnit->objectAt(qmlUnit->indexOfRootObject); @@ -263,7 +264,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile() } // Sanity check property bindings - QQmlPropertyValidator validator(this); + QQmlPropertyValidator validator(this, &compilationUnit->propertyCaches); if (!validator.validate()) return nullptr; @@ -292,8 +293,6 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile() compilationUnit->totalParserStatusCount = parserStatusCount; compilationUnit->totalObjectCount = objectCount; - Q_ASSERT(compilationUnit->propertyCaches.count() == static_cast<int>(compilationUnit->data->nObjects)); - if (errors.isEmpty()) return compilationUnit; else @@ -347,15 +346,20 @@ int QQmlTypeCompiler::rootObjectIndex() const return document->indexOfRootObject; } -void QQmlTypeCompiler::setPropertyCaches(const QQmlPropertyCacheVector &caches) +void QQmlTypeCompiler::setPropertyCaches(QQmlPropertyCacheVector &&caches) +{ + m_propertyCaches = std::move(caches); + Q_ASSERT(m_propertyCaches.count() >= document->indexOfRootObject); +} + +const QQmlPropertyCacheVector *QQmlTypeCompiler::propertyCaches() const { - m_propertyCaches = caches; - Q_ASSERT(caches.count() >= document->indexOfRootObject); + return &m_propertyCaches; } -const QQmlPropertyCacheVector &QQmlTypeCompiler::propertyCaches() const +QQmlPropertyCacheVector &&QQmlTypeCompiler::takePropertyCaches() { - return m_propertyCaches; + return std::move(m_propertyCaches); } QQmlJS::MemoryPool *QQmlTypeCompiler::memoryPool() @@ -413,7 +417,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio { for (int objectIndex = 0; objectIndex < qmlObjects.count(); ++objectIndex) { const QmlIR::Object * const obj = qmlObjects.at(objectIndex); - QQmlPropertyCache *cache = propertyCaches.at(objectIndex).data(); + QQmlPropertyCache *cache = propertyCaches->at(objectIndex); if (!cache) continue; if (QQmlCustomParser *customParser = customParsers.value(obj->inheritedTypeNameIndex)) { @@ -621,7 +625,7 @@ QQmlEnumTypeResolver::QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler) bool QQmlEnumTypeResolver::resolveEnumBindings() { for (int i = 0; i < qmlObjects.count(); ++i) { - QQmlPropertyCache *propertyCache = propertyCaches.at(i).data(); + QQmlPropertyCache *propertyCache = propertyCaches->at(i); if (!propertyCache) continue; const QmlIR::Object *obj = qmlObjects.at(i); @@ -807,7 +811,7 @@ QQmlAliasAnnotator::QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler) void QQmlAliasAnnotator::annotateBindingsToAliases() { for (int i = 0; i < qmlObjects.count(); ++i) { - QQmlPropertyCache *propertyCache = propertyCaches.at(i).data(); + QQmlPropertyCache *propertyCache = propertyCaches->at(i); if (!propertyCache) continue; @@ -839,7 +843,7 @@ void QQmlScriptStringScanner::scan() { const int scriptStringMetaType = qMetaTypeId<QQmlScriptString>(); for (int i = 0; i < qmlObjects.count(); ++i) { - QQmlPropertyCache *propertyCache = propertyCaches.at(i).data(); + QQmlPropertyCache *propertyCache = propertyCaches->at(i); if (!propertyCache) continue; @@ -874,7 +878,7 @@ QQmlComponentAndAliasResolver::QQmlComponentAndAliasResolver(QQmlTypeCompiler *t , indexOfRootObject(typeCompiler->rootObjectIndex()) , _componentIndex(-1) , resolvedTypes(typeCompiler->resolvedTypes()) - , propertyCaches(typeCompiler->propertyCaches()) + , propertyCaches(std::move(typeCompiler->takePropertyCaches())) { } @@ -942,7 +946,6 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI const int componentIndex = qmlObjects->count() - 1; // Keep property caches symmetric QQmlPropertyCache *componentCache = enginePrivate->cache(&QQmlComponent::staticMetaObject); - componentCache->addref(); propertyCaches.append(componentCache); QmlIR::Binding *syntheticBinding = pool->New<QmlIR::Binding>(); @@ -967,7 +970,7 @@ bool QQmlComponentAndAliasResolver::resolve() const int objCountWithoutSynthesizedComponents = qmlObjects->count(); for (int i = 0; i < objCountWithoutSynthesizedComponents; ++i) { QmlIR::Object *obj = qmlObjects->at(i); - QQmlPropertyCache *cache = propertyCaches.at(i).data(); + QQmlPropertyCache *cache = propertyCaches.at(i); if (obj->inheritedTypeNameIndex == 0 && !cache) continue; @@ -1046,7 +1049,7 @@ bool QQmlComponentAndAliasResolver::resolve() // Implicit component insertion may have added objects and thus we also need // to extend the symmetric propertyCaches. - compiler->setPropertyCaches(propertyCaches); + compiler->setPropertyCaches(std::move(propertyCaches)); compiler->setComponentRoots(componentRoots); return true; @@ -1090,7 +1093,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases() foreach (int objectIndex, _objectsWithAliases) { const QmlIR::Object *obj = qmlObjects->at(objectIndex); - QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex).data(); + QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex); Q_ASSERT(propertyCache); int effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.count(); @@ -1142,7 +1145,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases() alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; propertyFlags |= QQmlPropertyData::IsQObjectDerived; } else { - QQmlPropertyCache *targetCache = propertyCaches.at(targetObjectIndex).data(); + QQmlPropertyCache *targetCache = propertyCaches.at(targetObjectIndex); Q_ASSERT(targetCache); QmlIR::PropertyResolver resolver(targetCache); @@ -1247,7 +1250,7 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex) return scanObject(componentBinding->value.objectIndex); } - QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex).data(); + QQmlPropertyCache *propertyCache = propertyCaches->at(objectIndex); if (!propertyCache) return true; @@ -1340,13 +1343,13 @@ bool QQmlDeferredAndCustomParserBindingScanner::scanObject(int objectIndex) } -QQmlPropertyValidator::QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler) +QQmlPropertyValidator::QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler, const QQmlPropertyCacheVector *propertyCaches) : QQmlCompilePass(typeCompiler) , enginePrivate(typeCompiler->enginePrivate()) , qmlUnit(typeCompiler->qmlUnit()) , resolvedTypes(*typeCompiler->resolvedTypes()) , customParsers(typeCompiler->customParserCache()) - , propertyCaches(typeCompiler->propertyCaches()) + , propertyCaches(propertyCaches) { } @@ -1393,7 +1396,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD return validateObject(componentBinding->value.objectIndex, componentBinding); } - QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex).data(); + QQmlPropertyCache *propertyCache = propertyCaches->at(objectIndex); if (!propertyCache) return true; @@ -1962,7 +1965,7 @@ bool QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, co } else if (property->isQList()) { const int listType = enginePrivate->listType(property->propType); if (!QQmlMetaType::isInterface(listType)) { - QQmlPropertyCache *source = propertyCaches.at(binding->value.objectIndex).data(); + QQmlPropertyCache *source = propertyCaches->at(binding->value.objectIndex); if (!canCoerce(listType, source)) { recordError(binding->valueLocation, tr("Cannot assign object to list property \"%1\"").arg(propertyName)); return false; @@ -1989,7 +1992,7 @@ bool QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, co bool isAssignable = false; // Determine isAssignable value if (propertyMetaObject) { - QQmlPropertyCache *c = propertyCaches.at(binding->value.objectIndex).data(); + QQmlPropertyCache *c = propertyCaches->at(binding->value.objectIndex); while (c && !isAssignable) { isAssignable |= c == propertyMetaObject; c = c->parent(); @@ -2043,7 +2046,7 @@ bool QQmlJSCodeGenerator::compileComponent(int contextObject) const QmlIR::Object *obj = qmlObjects.at(objectIndex); m.name = stringAt(obj->idNameIndex); m.idIndex = obj->id; - m.type = propertyCaches.at(objectIndex).data(); + m.type = propertyCaches->at(objectIndex); auto *tref = resolvedTypes.value(obj->inheritedTypeNameIndex); if (tref && tref->isFullyDynamicType) @@ -2051,7 +2054,7 @@ bool QQmlJSCodeGenerator::compileComponent(int contextObject) idMapping << m; } - v4CodeGen->beginContextScope(idMapping, propertyCaches.at(contextObject).data()); + v4CodeGen->beginContextScope(idMapping, propertyCaches->at(contextObject)); if (!compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject)) return false; @@ -2066,7 +2069,7 @@ bool QQmlJSCodeGenerator::compileJavaScriptCodeInObjectsRecursively(int objectIn return true; if (object->functionsAndExpressions->count > 0) { - QQmlPropertyCache *scopeObject = propertyCaches.at(scopeObjectIndex).data(); + QQmlPropertyCache *scopeObject = propertyCaches->at(scopeObjectIndex); v4CodeGen->beginObjectScope(scopeObject); QList<QmlIR::CompiledFunctionOrExpression> functionsToCompile; @@ -2118,7 +2121,7 @@ void QQmlDefaultPropertyMerger::mergeDefaultProperties() void QQmlDefaultPropertyMerger::mergeDefaultProperties(int objectIndex) { - QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex).data(); + QQmlPropertyCache *propertyCache = propertyCaches->at(objectIndex); if (!propertyCache) return; diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 5e8bf4538e..07ad65d473 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -98,8 +98,9 @@ public: QHash<int, QV4::CompiledData::CompilationUnit::ResolvedTypeReference *> *resolvedTypes(); QList<QmlIR::Object*> *qmlObjects(); int rootObjectIndex() const; - void setPropertyCaches(const QQmlPropertyCacheVector &caches); - const QQmlPropertyCacheVector &propertyCaches() const; + void setPropertyCaches(QQmlPropertyCacheVector &&caches); + const QQmlPropertyCacheVector *propertyCaches() const; + QQmlPropertyCacheVector &&takePropertyCaches(); void setComponentRoots(const QVector<quint32> &roots) { m_componentRoots = roots; } const QVector<quint32> &componentRoots() const { return m_componentRoots; } QQmlJS::MemoryPool *memoryPool(); @@ -173,7 +174,7 @@ private: const QHash<int, QQmlCustomParser*> &customParsers; const QHash<int, QV4::CompiledData::CompilationUnit::ResolvedTypeReference*> &resolvedTypes; const QSet<QString> &illegalNames; - const QQmlPropertyCacheVector &propertyCaches; + const QQmlPropertyCacheVector * const propertyCaches; }; // ### This will go away when the codegen resolves all enums to constant expressions @@ -200,7 +201,7 @@ private: const QList<QmlIR::Object*> &qmlObjects; - const QQmlPropertyCacheVector propertyCaches; + const QQmlPropertyCacheVector * const propertyCaches; const QQmlImports *imports; QHash<int, QV4::CompiledData::CompilationUnit::ResolvedTypeReference *> *resolvedTypes; }; @@ -228,7 +229,7 @@ public: void annotateBindingsToAliases(); private: const QList<QmlIR::Object*> &qmlObjects; - const QQmlPropertyCacheVector propertyCaches; + const QQmlPropertyCacheVector * const propertyCaches; }; class QQmlScriptStringScanner : public QQmlCompilePass @@ -240,7 +241,7 @@ public: private: const QList<QmlIR::Object*> &qmlObjects; - const QQmlPropertyCacheVector propertyCaches; + const QQmlPropertyCacheVector * const propertyCaches; }; class QQmlComponentAndAliasResolver : public QQmlCompilePass @@ -284,7 +285,7 @@ private: bool scanObject(int objectIndex); QList<QmlIR::Object*> *qmlObjects; - QQmlPropertyCacheVector propertyCaches; + const QQmlPropertyCacheVector * const propertyCaches; const QHash<int, QQmlCustomParser*> &customParsers; bool _seenObjectWithId; @@ -294,7 +295,7 @@ class QQmlPropertyValidator : public QQmlCompilePass { Q_DECLARE_TR_FUNCTIONS(QQmlPropertyValidator) public: - QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler); + QQmlPropertyValidator(QQmlTypeCompiler *typeCompiler, const QQmlPropertyCacheVector *propertyCaches); bool validate(); @@ -312,7 +313,7 @@ private: const QV4::CompiledData::Unit *qmlUnit; const QHash<int, QV4::CompiledData::CompilationUnit::ResolvedTypeReference*> &resolvedTypes; const QHash<int, QQmlCustomParser*> &customParsers; - const QQmlPropertyCacheVector &propertyCaches; + const QQmlPropertyCacheVector * const propertyCaches; // collected state variables, essentially write-only mutable QVector<QV4::CompiledData::BindingPropertyData> _bindingPropertyDataPerObject; @@ -333,7 +334,7 @@ private: const QHash<int, QV4::CompiledData::CompilationUnit::ResolvedTypeReference*> &resolvedTypes; const QHash<int, QQmlCustomParser*> &customParsers; const QList<QmlIR::Object*> &qmlObjects; - const QQmlPropertyCacheVector &propertyCaches; + const QQmlPropertyCacheVector * const propertyCaches; QmlIR::JSCodeGen * const v4CodeGen; }; @@ -348,7 +349,7 @@ private: void mergeDefaultProperties(int objectIndex); const QList<QmlIR::Object*> &qmlObjects; - const QQmlPropertyCacheVector &propertyCaches; + const QQmlPropertyCacheVector * const propertyCaches; }; class QQmlJavaScriptBindingExpressionSimplificationPass : public QQmlCompilePass diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index df29930aad..db25e265d0 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -170,15 +170,12 @@ void CompilationUnit::unlink() engine->compilationUnits.erase(engine->compilationUnits.find(this)); if (isRegisteredWithEngine) { - Q_ASSERT(data && quint32(propertyCaches.count()) > data->indexOfRootObject && !propertyCaches.at(data->indexOfRootObject).isNull()); + Q_ASSERT(data && quint32(propertyCaches.count()) > data->indexOfRootObject && propertyCaches.at(data->indexOfRootObject)); QQmlEnginePrivate *qmlEngine = QQmlEnginePrivate::get(propertyCaches.at(data->indexOfRootObject)->engine); qmlEngine->unregisterInternalCompositeType(this); isRegisteredWithEngine = false; } - for (int ii = 0; ii < propertyCaches.count(); ++ii) - if (propertyCaches.at(ii).data()) - propertyCaches.at(ii)->release(); propertyCaches.clear(); for (int ii = 0; ii < dependentScripts.count(); ++ii) diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 760f6b6737..b24d93d995 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -76,10 +76,6 @@ class QQmlScriptData; class QQmlType; class QQmlEngine; -// The vector is indexed by QV4::CompiledData::Object index and the flag -// indicates whether instantiation of the object requires a VME meta-object. -typedef QVector<QFlagPointer<QQmlPropertyCache>> QQmlPropertyCacheVector; - namespace QmlIR { struct Document; } @@ -706,8 +702,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount // QML specific fields QQmlPropertyCacheVector propertyCaches; - QQmlPropertyCache *rootPropertyCache() const { return propertyCaches.at(data->indexOfRootObject).data(); } - bool isCompositeType() const { return propertyCaches.at(data->indexOfRootObject).flag(); } + QQmlPropertyCache *rootPropertyCache() const { return propertyCaches.at(data->indexOfRootObject); } QQmlRefPointer<QQmlTypeNameCache> importCache; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 9e2040469b..6a54555f3f 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -73,7 +73,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil : phase(Startup) , compilationUnit(compilationUnit) , resolvedTypes(compilationUnit->resolvedTypes) - , propertyCaches(compilationUnit->propertyCaches) + , propertyCaches(&compilationUnit->propertyCaches) , activeVMEDataForRootContext(activeVMEDataForRootContext) { init(parentContext); @@ -97,7 +97,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QV4::Compil : phase(Startup) , compilationUnit(compilationUnit) , resolvedTypes(compilationUnit->resolvedTypes) - , propertyCaches(compilationUnit->propertyCaches) + , propertyCaches(&compilationUnit->propertyCaches) , activeVMEDataForRootContext(0) { init(parentContext); @@ -1147,7 +1147,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo return instance; } - QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(index).data(); + QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches->at(index); Q_ASSERT(!cache.isNull()); if (installPropertyCache) { if (ddata->propertyCache) @@ -1278,11 +1278,10 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * QV4::Scope valueScope(v4); QV4::ScopedValue scopeObjectProtector(valueScope); - QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(_compiledObjectIndex).data(); + QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches->at(_compiledObjectIndex); QQmlVMEMetaObject *vmeMetaObject = 0; - const bool needVMEMetaObject = propertyCaches.at(_compiledObjectIndex).flag(); - if (needVMEMetaObject) { + if (propertyCaches->needsVMEMetaObject(_compiledObjectIndex)) { Q_ASSERT(!cache.isNull()); // install on _object vmeMetaObject = new QQmlVMEMetaObject(_qobject, cache, compilationUnit, _compiledObjectIndex); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index b4e706941b..2320edf809 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -140,7 +140,7 @@ private: QQmlGuardedContextData parentContext; QQmlContextData *context; const QHash<int, QV4::CompiledData::CompilationUnit::ResolvedTypeReference*> &resolvedTypes; - const QQmlPropertyCacheVector &propertyCaches; + const QQmlPropertyCacheVector *propertyCaches; QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState; bool topLevelCreator; void *activeVMEDataForRootContext; diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 3e84fb3070..34b6b96ebe 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -655,6 +655,49 @@ const QMetaObject *QQmlMetaObject::metaObject() const else return _m.asT2(); } +class QQmlPropertyCacheVector +{ +public: + QQmlPropertyCacheVector() {} + QQmlPropertyCacheVector(QQmlPropertyCacheVector &&other) + : data(std::move(other.data)) {} + QQmlPropertyCacheVector &operator=(QQmlPropertyCacheVector &&other) { + QVector<QFlagPointer<QQmlPropertyCache>> moved(std::move(other.data)); + data.swap(moved); + return *this; + } + + ~QQmlPropertyCacheVector() { clear(); } + void resize(int size) { return data.resize(size); } + int count() const { return data.count(); } + void clear() + { + for (int i = 0; i < data.count(); ++i) { + if (QQmlPropertyCache *cache = data.at(i).data()) + cache->release(); + } + data.clear(); + } + + void append(QQmlPropertyCache *cache) { cache->addref(); data.append(cache); } + QQmlPropertyCache *at(int index) const { return data.at(index).data(); } + void set(int index, QQmlPropertyCache *replacement) { + if (QQmlPropertyCache *oldCache = data.at(index).data()) { + if (replacement == oldCache) + return; + oldCache->release(); + } + data[index] = replacement; + replacement->addref(); + } + + void setNeedsVMEMetaObject(int index) { data[index].setFlag(); } + bool needsVMEMetaObject(int index) const { return data.at(index).flag(); } +private: + Q_DISABLE_COPY(QQmlPropertyCacheVector) + QVector<QFlagPointer<QQmlPropertyCache>> data; +}; + QT_END_NAMESPACE #endif // QQMLPROPERTYCACHE_P_H |