aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2016-06-14 15:44:09 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-06-16 18:00:35 +0000
commit0058ac5f28c64979f359972e03ee91ae146b0cd3 (patch)
treeb9063a18a2182668424ce22e5a3cd95f4e1e2b15
parentc2c13cacd450d866e60c58c87ff1ab16ae736804 (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.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