From 2b00cb4fc62f64b75c906a9f65cfc2b60ecfcb43 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 13 Jan 2014 09:42:55 +0100 Subject: [new compiler] Clean up property cache / meta object builder Move the outter loop into the builder class itself, use a vector instead of a list (we know that it's a fixed size and we only do indexed access) Change-Id: I933f0496ea47b3bc7c2bebde7f1a14b4f603b4c3 Reviewed-by: Lars Knoll --- src/qml/compiler/qqmltypecompiler.cpp | 109 ++++++++++++++++++++-------------- src/qml/compiler/qqmltypecompiler_p.h | 23 ++++--- src/qml/qml/qqmlcompiler_p.h | 4 +- src/qml/qml/qqmlobjectcreator_p.h | 4 +- 4 files changed, 86 insertions(+), 54 deletions(-) (limited to 'src/qml') diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 50bb5ef5a1..0c4ebcdf01 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -99,33 +99,11 @@ bool QQmlTypeCompiler::compile() compiledData->datas.reserve(objectCount); compiledData->propertyCaches.reserve(objectCount); - QQmlPropertyCacheCreator propertyCacheBuilder(this); - - for (int i = 0; i < objectCount; ++i) { - const QtQml::QmlObject *obj = parsedQML->objects.at(i); - - QByteArray vmeMetaObjectData; - QQmlPropertyCache *propertyCache = 0; - - // If the object has no type, then it's probably a nested object definition as part - // of a group property. - const bool objectHasType = !propertyCacheBuilder.stringAt(obj->inheritedTypeNameIndex).isEmpty(); - if (objectHasType) { - if (!propertyCacheBuilder.create(obj, &propertyCache, &vmeMetaObjectData)) { - errors << propertyCacheBuilder.errors; - return false; - } - } - - compiledData->datas << vmeMetaObjectData; - if (propertyCache) - propertyCache->addref(); - compiledData->propertyCaches << propertyCache; - - if (i == parsedQML->indexOfRootObject) { - Q_ASSERT(propertyCache); - compiledData->rootPropertyCache = propertyCache; - propertyCache->addref(); + { + QQmlPropertyCacheCreator propertyCacheBuilder(this); + if (!propertyCacheBuilder.buildMetaObjects()) { + errors << propertyCacheBuilder.errors; + return false; } } @@ -263,12 +241,26 @@ int QQmlTypeCompiler::rootObjectIndex() const return parsedQML->indexOfRootObject; } -const QList &QQmlTypeCompiler::propertyCaches() const +void QQmlTypeCompiler::setPropertyCaches(const QVector &caches) +{ + Q_ASSERT(compiledData->propertyCaches.isEmpty()); + compiledData->propertyCaches = caches; + Q_ASSERT(caches.count() >= parsedQML->indexOfRootObject); + compiledData->rootPropertyCache = caches.at(parsedQML->indexOfRootObject); +} + +const QVector &QQmlTypeCompiler::propertyCaches() const { return compiledData->propertyCaches; } -QList *QQmlTypeCompiler::vmeMetaObjects() const +void QQmlTypeCompiler::setVMEMetaObjects(const QVector &metaObjects) +{ + Q_ASSERT(compiledData->datas.isEmpty()); + compiledData->datas = metaObjects; +} + +QVector *QQmlTypeCompiler::vmeMetaObjects() const { return &compiledData->datas; } @@ -312,31 +304,62 @@ static QAtomicInt classIndexCounter(0); QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlTypeCompiler *typeCompiler) : QQmlCompilePass(typeCompiler) , enginePrivate(typeCompiler->enginePrivate()) + , qmlObjects(*typeCompiler->qmlObjects()) , imports(typeCompiler->imports()) , resolvedTypes(typeCompiler->resolvedTypes()) { } -bool QQmlPropertyCacheCreator::create(const QtQml::QmlObject *obj, QQmlPropertyCache **resultCache, QByteArray *vmeMetaObjectData) +QQmlPropertyCacheCreator::~QQmlPropertyCacheCreator() { - Q_ASSERT(!stringAt(obj->inheritedTypeNameIndex).isEmpty()); - - QQmlCompiledData::TypeReference typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex); - QQmlPropertyCache *baseTypeCache = typeRef.createPropertyCache(QQmlEnginePrivate::get(enginePrivate)); - Q_ASSERT(baseTypeCache); - if (obj->properties->count == 0 && obj->qmlSignals->count == 0 && obj->functions->count == 0) { - *resultCache = baseTypeCache; - vmeMetaObjectData->clear(); - return true; + for (int i = 0; i < propertyCaches.count(); ++i) + if (QQmlPropertyCache *cache = propertyCaches.at(i)) + cache->release(); + propertyCaches.clear(); +} + +bool QQmlPropertyCacheCreator::buildMetaObjects() +{ + propertyCaches.resize(qmlObjects.count()); + vmeMetaObjects.resize(qmlObjects.count()); + + for (int i = 0; i < qmlObjects.count(); ++i) { + const QtQml::QmlObject *obj = qmlObjects.at(i); + + // If the object has no type, then it's probably a nested object definition as part + // of a group property. + const bool objectHasType = !stringAt(obj->inheritedTypeNameIndex).isEmpty(); + if (objectHasType) { + QQmlCompiledData::TypeReference typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex); + QQmlPropertyCache *baseTypeCache = typeRef.createPropertyCache(QQmlEnginePrivate::get(enginePrivate)); + Q_ASSERT(baseTypeCache); + + bool needVMEMetaObject = obj->properties->count != 0 || obj->qmlSignals->count != 0 || obj->functions->count != 0; + if (needVMEMetaObject) { + if (!createMetaObject(i, obj, baseTypeCache)) + return false; + } else { + propertyCaches[i] = baseTypeCache; + baseTypeCache->addref(); + } + } } + compiler->setVMEMetaObjects(vmeMetaObjects); + compiler->setPropertyCaches(propertyCaches); + propertyCaches.clear(); + + return true; +} + +bool QQmlPropertyCacheCreator::createMetaObject(int objectIndex, const QtQml::QmlObject *obj, QQmlPropertyCache *baseTypeCache) +{ QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(QQmlEnginePrivate::get(enginePrivate), obj->properties->count, obj->functions->count + obj->properties->count + obj->qmlSignals->count, obj->qmlSignals->count + obj->properties->count); - *resultCache = cache; - - vmeMetaObjectData->clear(); + propertyCaches[objectIndex] = cache; + cache->addref(); struct TypeData { QV4::CompiledData::Property::Type dtype; @@ -406,7 +429,7 @@ bool QQmlPropertyCacheCreator::create(const QtQml::QmlObject *obj, QQmlPropertyC typedef QQmlVMEMetaData VMD; - QByteArray &dynamicData = *vmeMetaObjectData = QByteArray(sizeof(QQmlVMEMetaData) + QByteArray &dynamicData = vmeMetaObjects[objectIndex] = QByteArray(sizeof(QQmlVMEMetaData) + obj->properties->count * sizeof(VMD::PropertyData) + obj->functions->count * sizeof(VMD::MethodData) + aliasCount * sizeof(VMD::AliasData), 0); diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 9f055f4376..7f7adf1c86 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -84,8 +84,10 @@ struct QQmlTypeCompiler QHash *resolvedTypes(); QList *qmlObjects(); int rootObjectIndex() const; - const QList &propertyCaches() const; - QList *vmeMetaObjects() const; + void setPropertyCaches(const QVector &caches); + const QVector &propertyCaches() const; + void setVMEMetaObjects(const QVector &metaObjects); + QVector *vmeMetaObjects() const; QHash *objectIndexToIdForRoot(); QHash > *objectIndexToIdPerComponent(); QHash *customParserData(); @@ -101,6 +103,8 @@ private: struct QQmlCompilePass { + virtual ~QQmlCompilePass() {} + QQmlCompilePass(QQmlTypeCompiler *typeCompiler); QList errors; @@ -117,13 +121,18 @@ class QQmlPropertyCacheCreator : public QQmlCompilePass Q_DECLARE_TR_FUNCTIONS(QQmlPropertyCacheCreator) public: QQmlPropertyCacheCreator(QQmlTypeCompiler *typeCompiler); + ~QQmlPropertyCacheCreator(); - bool create(const QtQml::QmlObject *obj, QQmlPropertyCache **cache, QByteArray *vmeMetaObjectData); - + bool buildMetaObjects(); protected: + bool createMetaObject(int objectIndex, const QtQml::QmlObject *obj, QQmlPropertyCache *baseTypeCache); + QQmlEnginePrivate *enginePrivate; + const QList &qmlObjects; const QQmlImports *imports; QHash *resolvedTypes; + QVector vmeMetaObjects; + QVector propertyCaches; }; class QQmlComponentAndAliasResolver : public QQmlCompilePass @@ -157,8 +166,8 @@ protected: QList _objectsWithAliases; QHash *resolvedTypes; - const QList propertyCaches; - QList *vmeMetaObjectData; + const QVector propertyCaches; + QVector *vmeMetaObjectData; QHash *objectIndexToIdForRoot; QHash > *objectIndexToIdPerComponent; }; @@ -178,7 +187,7 @@ private: const QV4::CompiledData::QmlUnit *qmlUnit; const QHash &resolvedTypes; - const QList &propertyCaches; + const QVector &propertyCaches; const QHash > objectIndexToIdPerComponent; QHash *customParserData; }; diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index d410d396e3..c94cee16cf 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -144,9 +144,9 @@ public: QQmlPropertyCache *rootPropertyCache; QList primitives; - QList datas; + QVector datas; QByteArray bytecode; - QList propertyCaches; + QVector propertyCaches; QList > contextCaches; QList scripts; QList urls; diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 3c180c65f7..a198396467 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -87,8 +87,8 @@ private: QQmlContextData *parentContext; QQmlContextData *context; const QHash resolvedTypes; - const QList propertyCaches; - const QList vmeMetaObjectData; + const QVector propertyCaches; + const QVector vmeMetaObjectData; QHash objectIndexToId; QLinkedList > allCreatedBindings; QLinkedList > allParserStatusCallbacks; -- cgit v1.2.3