diff options
author | Simon Hausmann <[email protected]> | 2013-10-24 14:51:02 +0200 |
---|---|---|
committer | The Qt Project <[email protected]> | 2013-10-31 10:50:38 +0100 |
commit | 34c85bb56c92316a6ce1c79d25f9653fec14791c (patch) | |
tree | 6d3d43de33fa53a1353c52506e989ae126f1361b /src/qml/compiler/qv4compiler.cpp | |
parent | bb7d26ebb0c2e7a9f06a030be8bfcd00e346e06f (diff) |
Initial support for resolving meta-property access for the scope and context objects at QML compile time
This avoids having to do a string lookup for ids and in the import cache at
run-time, before we can do a string hash lookup in the property cache. Instead
we resolve final properties in the context and scope object at compile time and
look them up at run-time using their index instead. The dependencies to these
properties are also tracked separately and recorded in the compiled data.
This is merely the initial patch. There's a lot left to do, such as having
specialized getter and setters for specific property types. Setters are missing
altogether right now and will fall back to name lookup.
Change-Id: If3cb4e7c9454ef4850a615f0935b311c9395b165
Reviewed-by: Lars Knoll <[email protected]>
Diffstat (limited to 'src/qml/compiler/qv4compiler.cpp')
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 95 |
1 files changed, 82 insertions, 13 deletions
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index 0b3e85352e..4ee34d8aec 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -43,6 +43,7 @@ #include <qv4compileddata_p.h> #include <qv4isel_p.h> #include <qv4engine_p.h> +#include <private/qqmlpropertycache_p.h> QV4::Compiler::JSUnitGenerator::JSUnitGenerator(QQmlJS::V4IR::Module *module, int headerSize) : irModule(module) @@ -172,9 +173,19 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(int *total if (f->hasQmlDependencies) { QQmlJS::V4IR::QmlDependenciesCollector depCollector; - QSet<int> idObjectDeps = depCollector.run(f); + + QSet<int> idObjectDeps; + QSet<QQmlPropertyData*> contextPropertyDeps; + QSet<QQmlPropertyData*> scopePropertyDeps; + + depCollector.run(f, &idObjectDeps, &contextPropertyDeps, &scopePropertyDeps); + if (!idObjectDeps.isEmpty()) qmlIdObjectDependenciesPerFunction.insert(f, idObjectDeps); + if (!contextPropertyDeps.isEmpty()) + qmlContextPropertyDependenciesPerFunction.insert(f, contextPropertyDeps); + if (!scopePropertyDeps.isEmpty()) + qmlScopePropertyDependenciesPerFunction.insert(f, scopePropertyDeps); } } @@ -192,9 +203,24 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(int *total if (lineNumberMapping != lineNumberMappingsPerFunction.constEnd()) lineNumberMappingCount = lineNumberMapping->count() / 2; - const int qmlIdDepsCount = f->hasQmlDependencies ? qmlIdObjectDependenciesPerFunction.value(f).count() : 0; + int qmlIdDepsCount = 0; + int qmlPropertyDepsCount = 0; + + if (f->hasQmlDependencies) { + IdDependencyHash::ConstIterator idIt = qmlIdObjectDependenciesPerFunction.find(f); + if (idIt != qmlIdObjectDependenciesPerFunction.constEnd()) + qmlIdDepsCount += idIt->count(); + + PropertyDependencyHash::ConstIterator it = qmlContextPropertyDependenciesPerFunction.find(f); + if (it != qmlContextPropertyDependenciesPerFunction.constEnd()) + qmlPropertyDepsCount += it->count(); - functionDataSize += QV4::CompiledData::Function::calculateSize(f->formals.size(), f->locals.size(), f->nestedFunctions.size(), lineNumberMappingCount, qmlIdDepsCount); + it = qmlScopePropertyDependenciesPerFunction.find(f); + if (it != qmlScopePropertyDependenciesPerFunction.constEnd()) + qmlPropertyDepsCount += it->count(); + } + + functionDataSize += QV4::CompiledData::Function::calculateSize(f->formals.size(), f->locals.size(), f->nestedFunctions.size(), lineNumberMappingCount, qmlIdDepsCount, qmlPropertyDepsCount); } const int totalSize = unitSize + functionDataSize + stringDataSize + jsClassDataSize; @@ -292,7 +318,7 @@ int QV4::Compiler::JSUnitGenerator::writeFunction(char *f, int index, QQmlJS::V4 { QV4::CompiledData::Function *function = (QV4::CompiledData::Function *)f; - QHash<QQmlJS::V4IR::Function *, QVector<uint> >::ConstIterator lineNumberMapping = lineNumberMappingsPerFunction.find(irFunction); + quint32 currentOffset = sizeof(QV4::CompiledData::Function); function->index = index; function->nameIndex = getStringId(*irFunction->name); @@ -306,25 +332,55 @@ int QV4::Compiler::JSUnitGenerator::writeFunction(char *f, int index, QQmlJS::V4 if (irFunction->isNamedExpression) function->flags |= CompiledData::Function::IsNamedExpression; function->nFormals = irFunction->formals.size(); - function->formalsOffset = sizeof(QV4::CompiledData::Function); + function->formalsOffset = currentOffset; + currentOffset += function->nFormals * sizeof(quint32); + function->nLocals = irFunction->locals.size(); - function->localsOffset = function->formalsOffset + function->nFormals * sizeof(quint32); + function->localsOffset = currentOffset; + currentOffset += function->nLocals * sizeof(quint32); function->nLineNumberMappingEntries = 0; + QHash<QQmlJS::V4IR::Function *, QVector<uint> >::ConstIterator lineNumberMapping = lineNumberMappingsPerFunction.find(irFunction); if (lineNumberMapping != lineNumberMappingsPerFunction.constEnd()) { function->nLineNumberMappingEntries = lineNumberMapping->count() / 2; } - function->lineNumberMappingOffset = function->localsOffset + function->nLocals * sizeof(quint32); + function->lineNumberMappingOffset = currentOffset; + currentOffset += function->nLineNumberMappingEntries * 2 * sizeof(quint32); function->nInnerFunctions = irFunction->nestedFunctions.size(); - function->innerFunctionsOffset = function->lineNumberMappingOffset + function->nLineNumberMappingEntries * 2 * sizeof(quint32); + function->innerFunctionsOffset = currentOffset; + currentOffset += function->nInnerFunctions * sizeof(quint32); function->nDependingIdObjects = 0; + function->nDependingContextProperties = 0; + function->nDependingScopeProperties = 0; + QSet<int> qmlIdObjectDeps; + QSet<QQmlPropertyData*> qmlContextPropertyDeps; + QSet<QQmlPropertyData*> qmlScopePropertyDeps; + if (irFunction->hasQmlDependencies) { qmlIdObjectDeps = qmlIdObjectDependenciesPerFunction.value(irFunction); - function->nDependingIdObjects = qmlIdObjectDeps.count(); - function->dependingIdObjectsOffset = function->innerFunctionsOffset + function->nInnerFunctions * sizeof(quint32); + qmlContextPropertyDeps = qmlContextPropertyDependenciesPerFunction.value(irFunction); + qmlScopePropertyDeps = qmlScopePropertyDependenciesPerFunction.value(irFunction); + + if (!qmlIdObjectDeps.isEmpty()) { + function->nDependingIdObjects = qmlIdObjectDeps.count(); + function->dependingIdObjectsOffset = currentOffset; + currentOffset += function->nDependingIdObjects * sizeof(quint32); + } + + if (!qmlContextPropertyDeps.isEmpty()) { + function->nDependingContextProperties = qmlContextPropertyDeps.count(); + function->dependingContextPropertiesOffset = currentOffset; + currentOffset += function->nDependingContextProperties * sizeof(quint32) * 2; + } + + if (!qmlScopePropertyDeps.isEmpty()) { + function->nDependingScopeProperties = qmlScopePropertyDeps.count(); + function->dependingScopePropertiesOffset = currentOffset; + currentOffset += function->nDependingScopeProperties * sizeof(quint32) * 2; + } } function->location.line = irFunction->line; @@ -352,11 +408,24 @@ int QV4::Compiler::JSUnitGenerator::writeFunction(char *f, int index, QQmlJS::V4 innerFunctions[i] = functionOffsets.value(irFunction->nestedFunctions.at(i)); // write QML dependencies - quint32 *writtenIdDeps = (quint32 *)(f + function->dependingIdObjectsOffset); + quint32 *writtenDeps = (quint32 *)(f + function->dependingIdObjectsOffset); foreach (int id, qmlIdObjectDeps) - *writtenIdDeps++ = id; + *writtenDeps++ = id; + + writtenDeps = (quint32 *)(f + function->dependingContextPropertiesOffset); + foreach (QQmlPropertyData *property, qmlContextPropertyDeps) { + *writtenDeps++ = property->coreIndex; + *writtenDeps++ = property->notifyIndex; + } + + writtenDeps = (quint32 *)(f + function->dependingScopePropertiesOffset); + foreach (QQmlPropertyData *property, qmlScopePropertyDeps) { + *writtenDeps++ = property->coreIndex; + *writtenDeps++ = property->notifyIndex; + } - return CompiledData::Function::calculateSize(function->nFormals, function->nLocals, function->nInnerFunctions, function->nLineNumberMappingEntries, function->nDependingIdObjects); + return CompiledData::Function::calculateSize(function->nFormals, function->nLocals, function->nInnerFunctions, function->nLineNumberMappingEntries, + function->nDependingIdObjects, function->nDependingContextProperties + function->nDependingScopeProperties); } |