From 8457ca1b3dfb048acdb4426960ad7ee7c8227ed4 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 25 May 2016 10:25:25 +0200 Subject: Simplify object to id-in-context mapping By storing the calculated integer id for an id-named object in CompiledData::Object we can simplify the code and replace a hash table with a plain vector. Change-Id: I4a84cdd00e98766d603d152e5a6574b232771a02 Reviewed-by: Lars Knoll --- src/qml/qml/qqmlcompiler_p.h | 6 +++--- src/qml/qml/qqmlcontext.cpp | 19 +++++++++---------- src/qml/qml/qqmlcontext_p.h | 4 ++-- src/qml/qml/qqmlobjectcreator.cpp | 21 ++++++++++----------- src/qml/qml/qqmlobjectcreator_p.h | 4 ++-- 5 files changed, 26 insertions(+), 28 deletions(-) (limited to 'src/qml/qml') diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index a6856e60ed..e953673a4d 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -131,9 +131,9 @@ public: QList scripts; QQmlRefPointer compilationUnit; - // index in first hash is component index, hash inside maps from object index in that scope to integer id - QHash > objectIndexToIdPerComponent; - QHash objectIndexToIdForRoot; + // index in first hash is component index, vector inside contains object indices of objects with id property + QHash> namedObjectsPerComponent; + QVector namedObjectsInRootScope; // hash key is object index, value is indicies of bindings covered by custom parser QHash customParserBindings; QHash deferredBindingsPerObject; // index is object index diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index af06405376..11a8e81d8f 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -760,12 +760,12 @@ void QQmlContextData::setIdProperty(int idx, QObject *obj) idValues[idx].context = this; } -void QQmlContextData::setIdPropertyData(const QHash &data) +void QQmlContextData::setNamedObjects(const QVector &objects) { - Q_ASSERT(objectIndexToId.isEmpty()); - objectIndexToId = data; + Q_ASSERT(namedObjects.isEmpty()); + namedObjects = objects; Q_ASSERT(propertyNameCache.isEmpty()); - idValueCount = data.count(); + idValueCount = objects.count(); idValues = new ContextGuard[idValueCount]; } @@ -808,13 +808,12 @@ QV4::IdentifierHash &QQmlContextData::propertyNames() const { if (propertyNameCache.isEmpty()) { propertyNameCache = QV4::IdentifierHash(QV8Engine::getV4(engine->handle())); - for (QHash::ConstIterator it = objectIndexToId.cbegin(), end = objectIndexToId.cend(); - it != end; ++it) { - const QV4::CompiledData::Object *obj = typeCompilationUnit->data->objectAt(it.key()); - const QString name = typeCompilationUnit->data->stringAt(obj->idIndex); - propertyNameCache.add(name, it.value()); + for (int i = 0; i < namedObjects.count(); ++i) { + const QV4::CompiledData::Object *obj = typeCompilationUnit->data->objectAt(namedObjects.at(i)); + const QString name = typeCompilationUnit->data->stringAt(obj->idNameIndex); + propertyNameCache.add(name, obj->id); } - objectIndexToId.clear(); + namedObjects.clear(); } return propertyNameCache; } diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h index 48d596418d..e455c1f07b 100644 --- a/src/qml/qml/qqmlcontext_p.h +++ b/src/qml/qml/qqmlcontext_p.h @@ -151,7 +151,7 @@ public: // Compilation unit for contexts that belong to a compiled type. QQmlRefPointer typeCompilationUnit; - mutable QHash objectIndexToId; + mutable QVector namedObjects; mutable QV4::IdentifierHash propertyNameCache; QV4::IdentifierHash &propertyNames() const; @@ -201,7 +201,7 @@ public: ContextGuard *idValues; int idValueCount; void setIdProperty(int, QObject *); - void setIdPropertyData(const QHash &); + void setNamedObjects(const QVector &objects); // Linked contexts. this owns linkedContext. QQmlContextData *linkedContext; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 5cd6cb8685..215423cb6d 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -158,10 +158,10 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI int objectToCreate; if (subComponentIndex == -1) { - objectIndexToId = compiledData->objectIndexToIdForRoot; + namedObjects = compiledData->namedObjectsInRootScope; objectToCreate = qmlUnit->indexOfRootObject; } else { - objectIndexToId = compiledData->objectIndexToIdPerComponent[subComponentIndex]; + namedObjects = compiledData->namedObjectsPerComponent[subComponentIndex]; const QV4::CompiledData::Object *compObj = qmlUnit->objectAt(subComponentIndex); objectToCreate = compObj->bindingTable()->value.objectIndex; } @@ -185,7 +185,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI if (topLevelCreator) sharedState->allJavaScriptObjects = scope.alloc(compiledData->totalObjectCount); - context->setIdPropertyData(objectIndexToId); + context->setNamedObjects(namedObjects); if (subComponentIndex == -1 && compiledData->scripts.count()) { QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count())); @@ -637,7 +637,7 @@ void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip) const QV4::CompiledData::BindingPropertyData &propertyData = compiledData->compilationUnit->bindingPropertyDataPerObject.at(_compiledObjectIndex); - if (_compiledObject->idIndex) { + if (_compiledObject->idNameIndex) { const QQmlPropertyData *idProperty = propertyData.last(); Q_ASSERT(!idProperty || !idProperty->isValid() || idProperty->name(_qobject) == QLatin1String("id")); if (idProperty && idProperty->isValid() && idProperty->isWritable() && idProperty->propType == QMetaType::QString) { @@ -645,7 +645,7 @@ void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip) idBinding.propertyNameIndex = 0; // Not used idBinding.flags = 0; idBinding.type = QV4::CompiledData::Binding::Type_String; - idBinding.stringIndex = _compiledObject->idIndex; + idBinding.stringIndex = _compiledObject->idNameIndex; idBinding.location = _compiledObject->location; // ### setPropertyValue(idProperty, &idBinding); } @@ -1005,11 +1005,10 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location, errors << error; } -void QQmlObjectCreator::registerObjectWithContextById(int objectIndex, QObject *instance) const +void QQmlObjectCreator::registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const { - QHash::ConstIterator idEntry = objectIndexToId.find(objectIndex); - if (idEntry != objectIndexToId.constEnd()) - context->setIdProperty(idEntry.value(), instance); + if (object->id >= 0) + context->setIdProperty(object->id, instance); } QV4::Heap::QmlContext *QQmlObjectCreator::currentQmlContext() @@ -1146,7 +1145,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo } if (isComponent) { - registerObjectWithContextById(index, instance); + registerObjectWithContextById(obj, instance); return instance; } @@ -1298,7 +1297,7 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * vmeMetaObject = QQmlVMEMetaObject::get(_qobject); } - registerObjectWithContextById(_compiledObjectIndex, _qobject); + registerObjectWithContextById(_compiledObject, _qobject); qSwap(_propertyCache, cache); qSwap(_vmeMetaObject, vmeMetaObject); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 8045281cbb..e2e17bcf6c 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -122,7 +122,7 @@ private: QString stringAt(int idx) const { return qmlUnit->stringAt(idx); } void recordError(const QV4::CompiledData::Location &location, const QString &description); - void registerObjectWithContextById(int objectIndex, QObject *instance) const; + void registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const; QV4::Heap::QmlContext *currentQmlContext(); @@ -143,7 +143,7 @@ private: QQmlContextData *context; const QHash &resolvedTypes; const QQmlPropertyCacheVector &propertyCaches; - QHash objectIndexToId; + QVector namedObjects; QExplicitlySharedDataPointer sharedState; bool topLevelCreator; void *activeVMEDataForRootContext; -- cgit v1.2.3