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 | |
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')
-rw-r--r-- | src/qml/jsruntime/qv4lookup_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qmlcontext.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qmlcontext_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqml.cpp | 49 |
4 files changed, 33 insertions, 27 deletions
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index b1eb1ea982..aab6b66597 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -144,8 +144,8 @@ struct Q_QML_PRIVATE_EXPORT Lookup { QV4::ReturnedValue singletonValue; } qmlContextSingletonLookup; struct { - Heap::Base *objectContextWrapper; - Heap::Base *ownContextWrapper; + quintptr unused1; + quintptr unused2; int objectId; } qmlContextIdObjectLookup; struct { diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index f845f1d6e5..e1eb7b7a86 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -566,6 +566,12 @@ ReturnedValue QQmlContextWrapper::lookupIdObject(Lookup *l, ExecutionEngine *eng return QV4::QObjectWrapper::wrap(engine, context->idValue(objectId)); } +ReturnedValue QQmlContextWrapper::lookupIdObjectInParentContext( + Lookup *l, ExecutionEngine *engine, Value *base) +{ + return QQmlContextWrapper::resolveQmlContextPropertyLookupGetter(l, engine, base); +} + ReturnedValue QQmlContextWrapper::lookupScopeObjectProperty(Lookup *l, ExecutionEngine *engine, Value *base) { Scope scope(engine); diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h index 83d90a08fd..d4e68a284d 100644 --- a/src/qml/jsruntime/qv4qmlcontext_p.h +++ b/src/qml/jsruntime/qv4qmlcontext_p.h @@ -109,6 +109,7 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object static ReturnedValue lookupScript(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupSingleton(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupIdObject(Lookup *l, ExecutionEngine *engine, Value *base); + static ReturnedValue lookupIdObjectInParentContext(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupScopeObjectProperty(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupContextObjectProperty(Lookup *l, ExecutionEngine *engine, Value *base); static ReturnedValue lookupInGlobalObject(Lookup *l, ExecutionEngine *engine, Value *base); 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; } |