aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator.cpp33
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp63
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h23
-rw-r--r--src/qml/compiler/qv4compileddata.cpp5
-rw-r--r--src/qml/compiler/qv4compileddata_p.h7
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp11
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h2
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h43
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