diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2021-05-17 16:38:25 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2021-06-10 11:53:19 +0200 |
commit | e20650e0702259b4be79be85a3d27e45db42efc1 (patch) | |
tree | 7536cee98f4cc502774f807d1a609940cd20d4f5 /src/qml/jsruntime/qv4jscall_p.h | |
parent | 7fa28f98824a94396106eadfc028b329985a0cfc (diff) |
Eliminate JS call frame from metatypes calls
If we call an AOT-compiled function we never need the JavaScript call
frame. We can just skip its setup and save some overhead.
Change-Id: I39dc2ca6eea5b5a66f3b87b642a310534cecf6cd
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4jscall_p.h')
-rw-r--r-- | src/qml/jsruntime/qv4jscall_p.h | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h index c6d320ac20..337b86dbc0 100644 --- a/src/qml/jsruntime/qv4jscall_p.h +++ b/src/qml/jsruntime/qv4jscall_p.h @@ -56,6 +56,7 @@ #include "qv4context_p.h" #include "qv4scopedvalue_p.h" #include "qv4stackframe_p.h" +#include "qv4qobjectwrapper_p.h" #include <private/qv4alloca_p.h> QT_BEGIN_NAMESPACE @@ -134,27 +135,24 @@ ReturnedValue FunctionObject::call(const JSCallData &data) const void populateJSCallArguments(ExecutionEngine *v4, JSCallArguments &jsCall, int argc, void **args, const QMetaType *types); -struct ScopedStackFrame { - Scope &scope; - CppStackFrame frame; - - ScopedStackFrame(Scope &scope, Heap::ExecutionContext *context) - : scope(scope) +struct ScopedStackFrame +{ + ScopedStackFrame(const Scope &scope, ExecutionContext *context) + : engine(scope.engine) { - frame.setParentFrame(scope.engine->currentStackFrame); - if (!context) - return; - frame.jsFrame = reinterpret_cast<CallData *>(scope.alloc(sizeof(CallData)/sizeof(Value))); - frame.jsFrame->context = context; - if (auto *parent = frame.parentFrame()) - frame.v4Function = parent->v4Function; - else - frame.v4Function = nullptr; - scope.engine->currentStackFrame = &frame; + frame.init(engine->currentStackFrame ? engine->currentStackFrame->v4Function : nullptr, + nullptr, context, nullptr, nullptr, 0); + frame.push(engine); } - ~ScopedStackFrame() { - scope.engine->currentStackFrame = frame.parentFrame(); + + ~ScopedStackFrame() + { + frame.pop(engine); } + +private: + ExecutionEngine *engine = nullptr; + MetaTypesStackFrame frame; }; template<typename Callable> @@ -189,7 +187,10 @@ ReturnedValue convertAndCall( values[0] = nullptr; } - call(thisObject, values, types, argc); + if (const QV4::QObjectWrapper *cppThisObject = thisObject->as<QV4::QObjectWrapper>()) + call(cppThisObject->object(), values, types, argc); + else + call(nullptr, values, types, argc); ReturnedValue result; if (values[0]) { @@ -206,7 +207,7 @@ ReturnedValue convertAndCall( } template<typename Callable> -bool convertAndCall(ExecutionEngine *engine, const Value *thisObject, +bool convertAndCall(ExecutionEngine *engine, QObject *thisObject, void **a, const QMetaType *types, int argc, Callable call) { Scope scope(engine); @@ -215,7 +216,17 @@ bool convertAndCall(ExecutionEngine *engine, const Value *thisObject, for (int ii = 0; ii < argc; ++ii) jsCallData.args[ii] = engine->metaTypeToJS(types[ii + 1], a[ii + 1]); - ScopedValue jsResult(scope, call(thisObject, jsCallData.args, argc)); + ScopedObject jsThisObject(scope); + if (thisObject) { + // The result of wrap() can only be null, undefined, or an object. + jsThisObject = QV4::QObjectWrapper::wrap(engine, thisObject); + if (!jsThisObject) + jsThisObject = engine->globalObject; + } else { + jsThisObject = engine->globalObject; + } + + ScopedValue jsResult(scope, call(jsThisObject, jsCallData.args, argc)); void *result = a[0]; if (!result) return !jsResult->isUndefined(); |