aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2016-05-25 14:55:44 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-05-26 19:57:55 +0000
commite850416fcffe48cc19cdbf6a01f759964815681c (patch)
tree87afa793953710a74c530900ab7cbf93fd6cb3cb /src/qml/qml
parent6f84a09dfbd15aac023580cf06e7b8c24f3b524c (diff)
Optimize named object handling
By storing the object indices of named objects in the CompiledData::Object of a component, we can achieve two things: (1) We can eliminate the hash of vectors in QQmlCompiledData for the object-to-id mapping (2) We can store the mapping from object name to integer object id in the CompilationUnit and share it across different QQmlContextData instances (as long as it is not modified). Also added a new test that verifies the functionality of a .qml file starting with Component{} itself with object names, something that was previously only implicitly tested through some of the examples (corkboards.qml for example). Change-Id: I28c70217222dc0e5252bf5247b7e3fc4def47446 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlcompiler_p.h3
-rw-r--r--src/qml/qml/qqmlcontext.cpp44
-rw-r--r--src/qml/qml/qqmlcontext_p.h11
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp6
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h1
5 files changed, 33 insertions, 32 deletions
diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h
index e953673a4d..cd2c533150 100644
--- a/src/qml/qml/qqmlcompiler_p.h
+++ b/src/qml/qml/qqmlcompiler_p.h
@@ -131,9 +131,6 @@ public:
QList<QQmlScriptData *> scripts;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
- // index in first hash is component index, vector inside contains object indices of objects with id property
- QHash<int, QVector<quint32>> namedObjectsPerComponent;
- QVector<quint32> namedObjectsInRootScope;
// hash key is object index, value is indicies of bindings covered by custom parser
QHash<int, QBitArray> customParserBindings;
QHash<int, QBitArray> deferredBindingsPerObject; // index is object index
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 11a8e81d8f..b3081ddbe6 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -310,7 +310,7 @@ void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
}
}
- QV4::IdentifierHash<int> &properties = data->propertyNames();
+ QV4::IdentifierHash<int> &properties = data->detachedPropertyNames();
int idx = properties.value(name);
if (idx == -1) {
properties.add(name, data->idValueCount + d->propertyValues.count());
@@ -346,7 +346,7 @@ void QQmlContext::setContextProperty(const QString &name, QObject *value)
return;
}
- QV4::IdentifierHash<int> &properties = data->propertyNames();
+ QV4::IdentifierHash<int> &properties = data->detachedPropertyNames();
int idx = properties.value(name);
if (idx == -1) {
@@ -523,7 +523,7 @@ QQmlContextData::QQmlContextData()
QQmlContextData::QQmlContextData(QQmlContext *ctxt)
: parent(0), engine(0), isInternal(false), ownedByParent(false), isJSContext(false),
isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
- publicContext(ctxt), activeVMEData(0),
+ publicContext(ctxt), activeVMEData(0), componentObjectIndex(-1),
contextObject(0), imports(0), childContexts(0), nextChild(0), prevChild(0),
expressions(0), contextObjects(0), contextGuards(0), idValues(0), idValueCount(0), linkedContext(0),
componentAttached(0)
@@ -760,15 +760,6 @@ void QQmlContextData::setIdProperty(int idx, QObject *obj)
idValues[idx].context = this;
}
-void QQmlContextData::setNamedObjects(const QVector<quint32> &objects)
-{
- Q_ASSERT(namedObjects.isEmpty());
- namedObjects = objects;
- Q_ASSERT(propertyNameCache.isEmpty());
- idValueCount = objects.count();
- idValues = new ContextGuard[idValueCount];
-}
-
QString QQmlContextData::findObjectId(const QObject *obj) const
{
const QV4::IdentifierHash<int> &properties = propertyNames();
@@ -804,20 +795,33 @@ QQmlContextPrivate *QQmlContextData::asQQmlContextPrivate()
return QQmlContextPrivate::get(asQQmlContext());
}
-QV4::IdentifierHash<int> &QQmlContextData::propertyNames() const
+void QQmlContextData::initFromTypeCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit, int subComponentIndex)
+{
+ typeCompilationUnit = unit;
+ componentObjectIndex = subComponentIndex == -1 ? typeCompilationUnit->data->indexOfRootObject : subComponentIndex;
+ Q_ASSERT(!idValues);
+ idValueCount = typeCompilationUnit->data->objectAt(componentObjectIndex)->nNamedObjectsInComponent;
+ idValues = new ContextGuard[idValueCount];
+}
+
+const QV4::IdentifierHash<int> &QQmlContextData::propertyNames() const
{
if (propertyNameCache.isEmpty()) {
- propertyNameCache = QV4::IdentifierHash<int>(QV8Engine::getV4(engine->handle()));
- 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);
- }
- namedObjects.clear();
+ if (typeCompilationUnit)
+ propertyNameCache = typeCompilationUnit->namedObjectsPerComponent(componentObjectIndex);
+ else
+ propertyNameCache = QV4::IdentifierHash<int>(QV8Engine::getV4(engine));
}
return propertyNameCache;
}
+QV4::IdentifierHash<int> &QQmlContextData::detachedPropertyNames()
+{
+ propertyNames();
+ propertyNameCache.detach();
+ return propertyNameCache;
+}
+
QUrl QQmlContextData::url() const
{
if (typeCompilationUnit)
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index e455c1f07b..05ce39401e 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -151,9 +151,15 @@ public:
// Compilation unit for contexts that belong to a compiled type.
QQmlRefPointer<QV4::CompiledData::CompilationUnit> typeCompilationUnit;
- mutable QVector<quint32> namedObjects;
+ // object index in CompiledData::Unit to component that created this context
+ int componentObjectIndex;
+
+ void initFromTypeCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit, int subComponentIndex);
+
+ // flag indicates whether the context owns the cache (after mutation) or not.
mutable QV4::IdentifierHash<int> propertyNameCache;
- QV4::IdentifierHash<int> &propertyNames() const;
+ const QV4::IdentifierHash<int> &propertyNames() const;
+ QV4::IdentifierHash<int> &detachedPropertyNames();
// Context object
QObject *contextObject;
@@ -201,7 +207,6 @@ public:
ContextGuard *idValues;
int idValueCount;
void setIdProperty(int, QObject *);
- void setNamedObjects(const QVector<quint32> &objects);
// Linked contexts. this owns linkedContext.
QQmlContextData *linkedContext;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 215423cb6d..a6b24c4f16 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -158,10 +158,8 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
int objectToCreate;
if (subComponentIndex == -1) {
- namedObjects = compiledData->namedObjectsInRootScope;
objectToCreate = qmlUnit->indexOfRootObject;
} else {
- namedObjects = compiledData->namedObjectsPerComponent[subComponentIndex];
const QV4::CompiledData::Object *compObj = qmlUnit->objectAt(subComponentIndex);
objectToCreate = compObj->bindingTable()->value.objectIndex;
}
@@ -170,7 +168,7 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
context->isInternal = true;
context->imports = compiledData->importCache;
context->imports->addref();
- context->typeCompilationUnit = compiledData->compilationUnit;
+ context->initFromTypeCompilationUnit(compiledData->compilationUnit, subComponentIndex);
context->setParent(parentContext);
if (!sharedState->rootContext) {
@@ -185,8 +183,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
if (topLevelCreator)
sharedState->allJavaScriptObjects = scope.alloc(compiledData->totalObjectCount);
- context->setNamedObjects(namedObjects);
-
if (subComponentIndex == -1 && compiledData->scripts.count()) {
QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count()));
context->importedScripts.set(v4, scripts);
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index e2e17bcf6c..730237acfe 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -143,7 +143,6 @@ private:
QQmlContextData *context;
const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes;
const QQmlPropertyCacheVector &propertyCaches;
- QVector<quint32> namedObjects;
QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
bool topLevelCreator;
void *activeVMEDataForRootContext;