From 78a2887d8c5d866fc430f197abea6bb31293c4b1 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 4 Jan 2019 10:41:02 +0100 Subject: Accelerate access to id objects in lookups Task-number: QTBUG-69898 Change-Id: Ifbd9b3bf8d4b0c82b4c3933912e61eea8e0bb987 Reviewed-by: Ulf Hermann --- src/qml/jsruntime/qv4lookup_p.h | 5 +++++ src/qml/jsruntime/qv4qmlcontext.cpp | 35 +++++++++++++++++++++++++++++++++-- src/qml/jsruntime/qv4qmlcontext_p.h | 1 + 3 files changed, 39 insertions(+), 2 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index 2384a1194e..68da224273 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -138,6 +138,11 @@ struct Lookup { Heap::Object *singleton; quintptr unused; } qmlContextSingletonLookup; + struct { + quintptr unused1; + quintptr unused2; + int objectId; + } qmlContextIdObjectLookup; }; uint nameIndex; diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index ab80e6bc45..3d9e1cc0f8 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -223,11 +223,17 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r if (propertyIdx != -1) { if (propertyIdx < context->idValueCount) { + if (hasProperty) + *hasProperty = true; + + if (lookup) { + lookup->qmlContextIdObjectLookup.objectId = propertyIdx; + lookup->qmlContextPropertyGetter = QQmlContextWrapper::lookupIdObject; + return lookup->qmlContextPropertyGetter(lookup, v4, base); + } if (ep->propertyCapture) ep->propertyCapture->captureProperty(&context->idValues[propertyIdx].bindings); - if (hasProperty) - *hasProperty = true; return QV4::QObjectWrapper::wrap(v4, context->idValues[propertyIdx]); } else { @@ -281,6 +287,10 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r } context = context->parent; + + // As the hierarchy of contexts is not stable, we can't do accelerated lookups beyond + // the immediate QML context (of the .qml file). + lookup = nullptr; } // Do a lookup in the global object here to avoid expressionContext->unresolvedNames becoming @@ -418,6 +428,27 @@ ReturnedValue QQmlContextWrapper::lookupSingleton(Lookup *l, ExecutionEngine *en return Value::fromHeapObject(l->qmlContextSingletonLookup.singleton).asReturnedValue(); } +ReturnedValue QQmlContextWrapper::lookupIdObject(Lookup *l, ExecutionEngine *engine, Value *base) +{ + Q_UNUSED(base) + Scope scope(engine); + Scoped qmlContext(scope, engine->qmlContext()); + if (!qmlContext) + return QV4::Encode::null(); + + QQmlContextData *context = qmlContext->qmlContext(); + if (!context) + return QV4::Encode::null(); + + QQmlEnginePrivate *qmlEngine = QQmlEnginePrivate::get(engine->qmlEngine()); + const int objectId = l->qmlContextIdObjectLookup.objectId; + + if (qmlEngine->propertyCapture) + qmlEngine->propertyCapture->captureProperty(&context->idValues[objectId].bindings); + + return QV4::QObjectWrapper::wrap(engine, context->idValues[objectId]); +} + void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml) { Heap::ExecutionContext::init(Heap::ExecutionContext::Type_QmlContext); diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h index 5eacea5830..caf9281540 100644 --- a/src/qml/jsruntime/qv4qmlcontext_p.h +++ b/src/qml/jsruntime/qv4qmlcontext_p.h @@ -107,6 +107,7 @@ struct Q_QML_EXPORT QQmlContextWrapper : Object static ReturnedValue resolveQmlContextPropertyLookupGetter(Lookup *l, ExecutionEngine *engine, Value *base); 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); }; struct Q_QML_EXPORT QmlContext : public ExecutionContext -- cgit v1.2.3