diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-04-30 10:23:34 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-04-30 17:54:10 +0200 |
commit | e354d8b43c7d9331ea0bf77f0f5342b2fd1b53ee (patch) | |
tree | 1a6440a6b3985fe777c510e68bda7d14e5061d7d /src/qml/qml/qqml.cpp | |
parent | 2b49615db4381fa7c54b1ebbc9875d214ad292aa (diff) |
Remove caching of recursive AOT context lookups
Such lookups are usually caused by repeaters or similar constructs where
many objects look up something in their parent context. As all those
objects have different contexts, we would constantly invalidate the cache.
Change-Id: I06c7d337d859e5e6a81f6e9a8693b155b2af7498
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqml.cpp')
-rw-r--r-- | src/qml/qml/qqml.cpp | 49 |
1 files changed, 24 insertions, 25 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index afe6bedf56..ab513803b0 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -877,30 +877,32 @@ void AOTCompiledContext::initCallQmlContextPropertyLookup(uint index) const bool AOTCompiledContext::loadContextIdLookup(uint index, void *target) const { QV4::Lookup *l = compilationUnit->runtimeLookups + index; - if (l->qmlContextPropertyGetter != QV4::QQmlContextWrapper::lookupIdObject) - return false; - + int objectId = -1; + QQmlContextData *context = nullptr; Q_ASSERT(qmlContext); - QQmlContextData *contextData; - if (auto *wrapper = l->qmlContextIdObjectLookup.ownContextWrapper) { + if (l->qmlContextPropertyGetter == QV4::QQmlContextWrapper::lookupIdObject) { + objectId = l->qmlContextIdObjectLookup.objectId; + context = qmlContext; + } else if (l->qmlContextPropertyGetter + == QV4::QQmlContextWrapper::lookupIdObjectInParentContext) { QV4::Scope scope(engine->handle()); - QV4::Scoped<QV4::QQmlContextWrapper> ownContext(scope, wrapper); - if (ownContext->d()->context != qmlContext) - return false; // context has changed. Look up again. - QV4::Scoped<QV4::QQmlContextWrapper> objectContext( - scope, l->qmlContextIdObjectLookup.objectContextWrapper); - contextData = objectContext->d()->context; + QV4::ScopedString name(scope, compilationUnit->runtimeStrings[l->nameIndex]); + for (context = qmlContext; context; context = context->parent().data()) { + objectId = context->propertyIndex(name); + if (objectId != -1 && objectId < context->numIdValues()) + break; + } } else { - contextData = qmlContext; + return false; } - const int objectId = l->qmlContextIdObjectLookup.objectId; + Q_ASSERT(objectId >= 0); + Q_ASSERT(context != nullptr); QQmlEnginePrivate *engine = QQmlEnginePrivate::get(qmlEngine()); - if (QQmlPropertyCapture *capture = engine->propertyCapture) - capture->captureProperty(contextData->idValueBindings(objectId)); - *static_cast<QObject **>(target) = contextData->idValue(objectId); + capture->captureProperty(context->idValueBindings(objectId)); + *static_cast<QObject **>(target) = context->idValue(objectId); return true; } @@ -916,16 +918,13 @@ void AOTCompiledContext::initLoadContextIdLookup(uint index) const if (propertyIdx == -1 || propertyIdx >= context->numIdValues()) continue; - l->qmlContextIdObjectLookup.objectId = propertyIdx; - l->qmlContextPropertyGetter = QV4::QQmlContextWrapper::lookupIdObject; - if (context.data() != ownContext.data()) { - l->qmlContextIdObjectLookup.objectContextWrapper - = scope.engine->memoryManager->allocate<QV4::QQmlContextWrapper>( - context, nullptr); - l->qmlContextIdObjectLookup.ownContextWrapper - = scope.engine->memoryManager->allocate<QV4::QQmlContextWrapper>( - ownContext, nullptr); + if (context.data() == ownContext.data()) { + l->qmlContextIdObjectLookup.objectId = propertyIdx; + l->qmlContextPropertyGetter = QV4::QQmlContextWrapper::lookupIdObject; + } else { + l->qmlContextPropertyGetter = QV4::QQmlContextWrapper::lookupIdObjectInParentContext; } + return; } |