summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2019-01-04 15:32:33 +0100
committerMichael Brasser <michael.brasser@live.com>2019-03-20 16:42:44 +0000
commitbb34abcc05d11f23c329f4c52aab638d991c1b98 (patch)
treefe568cb09a5f184c1c3b2470a76b56d1709a67c8
parent40ae0bfd9977e53a87384d79ae971a7ded260a12 (diff)
Fix lookup fallback into the global object in QML bindings
This change addresses in particular qmlbench's fib10.qml, where usage of properties of the global object needs to go be accelerated in order to avoid regressing in performance. Task-number: QTBUG-69898 Change-Id: Ic43c64f4dd5459c4e92f87f03235ea836f971515 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h7
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp33
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h1
3 files changed, 39 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index 68da224273..ee6da21121 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -143,6 +143,13 @@ struct Lookup {
quintptr unused2;
int objectId;
} qmlContextIdObjectLookup;
+ struct {
+ // Same as protoLookup, as used for global lookups
+ quintptr reserved1;
+ quintptr reserved2;
+ quintptr reserved3;
+ ReturnedValue (*getterTrampoline)(Lookup *l, ExecutionEngine *engine);
+ } qmlContextGlobalLookup;
};
uint nameIndex;
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 3d9e1cc0f8..e728cfb457 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -213,6 +213,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
}
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(v4->qmlEngine());
+ Lookup * const originalLookup = lookup;
while (context) {
// Search context properties
@@ -295,8 +296,24 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
// Do a lookup in the global object here to avoid expressionContext->unresolvedNames becoming
// true if we access properties of the global object.
- if (performGobalLookUp())
- return result->asReturnedValue();
+ if (originalLookup) {
+ // Try a lookup in the global object. It's theoretically possible to first find a property
+ // in the global object and then later a context property with the same name is added, but that
+ // never really worked as we used to detect access to global properties at type compile time anyway.
+ lookup = originalLookup;
+ result = lookup->resolveGlobalGetter(v4);
+ if (lookup->globalGetter != Lookup::globalGetterGeneric) {
+ if (hasProperty)
+ *hasProperty = true;
+ lookup->qmlContextGlobalLookup.getterTrampoline = lookup->globalGetter;
+ lookup->qmlContextPropertyGetter = QQmlContextWrapper::lookupInGlobalObject;
+ return result->asReturnedValue();
+ }
+ lookup->qmlContextPropertyGetter = QQmlContextWrapper::resolveQmlContextPropertyLookupGetter;
+ } else {
+ if (performGobalLookUp())
+ return result->asReturnedValue();
+ }
expressionContext->unresolvedNames = true;
@@ -449,6 +466,18 @@ ReturnedValue QQmlContextWrapper::lookupIdObject(Lookup *l, ExecutionEngine *eng
return QV4::QObjectWrapper::wrap(engine, context->idValues[objectId]);
}
+ReturnedValue QQmlContextWrapper::lookupInGlobalObject(Lookup *l, ExecutionEngine *engine, Value *base)
+{
+ Q_UNUSED(base);
+ ReturnedValue result = l->qmlContextGlobalLookup.getterTrampoline(l, engine);
+ // In the unlikely event of mutation of the global object, update the trampoline.
+ if (l->qmlContextPropertyGetter != lookupInGlobalObject) {
+ l->qmlContextGlobalLookup.getterTrampoline = l->globalGetter;
+ l->qmlContextPropertyGetter = QQmlContextWrapper::lookupInGlobalObject;
+ }
+ return result;
+}
+
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 caf9281540..cfcc53c7c9 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -108,6 +108,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 lookupInGlobalObject(Lookup *l, ExecutionEngine *engine, Value *base);
};
struct Q_QML_EXPORT QmlContext : public ExecutionContext