diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-08 16:56:59 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-08-10 08:19:24 +0000 |
commit | 55f17d0faad79dbb9adf793f7ce6e75ff5b70033 (patch) | |
tree | 5a5e34a98a196173c707f62d972a3a4984c146de /src | |
parent | 5bc4f4d958a3b76f3435d61206ca0109f07aa1a3 (diff) |
Get rid of simpleCall
After the recent changes this can easily be unified with
the call method without loss of performance.
Change-Id: I0385b47b6a86e890f97dcbada3a1be1129ae0b84
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 49 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 15 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4script.cpp | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 23 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression.cpp | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmljavascriptexpression_p.h | 2 |
7 files changed, 28 insertions, 81 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index c9565468ad..f82ea74227 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -57,18 +57,19 @@ DEFINE_MANAGED_VTABLE(ExecutionContext); DEFINE_MANAGED_VTABLE(CallContext); DEFINE_MANAGED_VTABLE(CatchContext); -Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData *callData) +Heap::CallContext *ExecutionContext::newCallContext(Heap::ExecutionContext *outer, Function *function, CallData *callData) { - uint localsAndFormals = function->compiledFunction->nLocals + sizeof(CallData)/sizeof(Value) - 1 + qMax(static_cast<uint>(callData->argc), function->nFormals); + uint nFormals = qMax(static_cast<uint>(callData->argc), function->nFormals); + uint localsAndFormals = function->compiledFunction->nLocals + sizeof(CallData)/sizeof(Value) - 1 + nFormals; size_t requiredMemory = sizeof(CallContext::Data) - sizeof(Value) + sizeof(Value) * (localsAndFormals); - ExecutionEngine *v4 = engine(); + ExecutionEngine *v4 = outer->internalClass->engine; Heap::CallContext *c = v4->memoryManager->allocManaged<CallContext>(requiredMemory, function->internalClass); c->init(Heap::ExecutionContext::Type_CallContext); c->v4Function = function; - c->outer.set(v4, this->d()); + c->outer.set(v4, outer); const CompiledData::Function *compiledFunction = function->compiledFunction; uint nLocals = compiledFunction->nLocals; @@ -83,9 +84,7 @@ Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData #endif c->callData = reinterpret_cast<CallData *>(c->locals.values + nLocals); - ::memcpy(c->callData, callData, sizeof(CallData) - sizeof(Value) + static_cast<uint>(callData->argc) * sizeof(Value)); - if (callData->argc < static_cast<int>(compiledFunction->nFormals)) - std::fill(c->callData->args + c->callData->argc, c->callData->args + compiledFunction->nFormals, Primitive::undefinedValue()); + ::memcpy(c->callData, callData, sizeof(CallData) - sizeof(Value) + nFormals * sizeof(Value)); return c; } @@ -229,38 +228,26 @@ bool ExecutionContext::deleteProperty(String *name) return !d()->v4Function->isStrict(); } -// Do a standard call with this execution context as the outer scope -ReturnedValue ExecutionContext::call(ExecutionEngine *engine, CallData *callData, Function *function, const FunctionObject *f) +// Do a call with this execution context as the outer scope +ReturnedValue ExecutionContext::call(Heap::ExecutionContext *context, CallData *callData, Function *function, const FunctionObject *f) { - Heap::CallContext *ctx = newCallContext(function, callData); - if (f) - ctx->function.set(engine, f->d()); - - ReturnedValue res = Q_V4_PROFILE(engine, ctx, function, f); - - if (function->hasQmlDependencies) { - Q_ASSERT(d()->type == Heap::ExecutionContext::Type_QmlContext); - QQmlPropertyCapture::registerQmlDependencies(static_cast<QmlContext *>(this), engine, function->compiledFunction); - } - - return res; -} - -// Do a simple, fast call with this execution context as the outer scope -ReturnedValue QV4::ExecutionContext::simpleCall(ExecutionEngine *engine, CallData *callData, Function *function) -{ - Q_ASSERT(function->canUseSimpleFunction()); - + ExecutionEngine *engine = context->internalClass->engine; Value *jsStackTop = engine->jsStackTop; engine->jsStackTop = reinterpret_cast<QV4::Value *>(callData) + 2 + (int)function->nFormals; for (int i = callData->argc; i < (int)function->nFormals; ++i) callData->args[i] = Encode::undefined(); - ReturnedValue res = Q_V4_PROFILE(engine, d(), function, 0); + if (!function->canUseSimpleCall) { + context = newCallContext(context, function, callData); + if (f) + static_cast<Heap::CallContext *>(context)->function.set(engine, f->d()); + } + + ReturnedValue res = Q_V4_PROFILE(engine, context, function, f); if (function->hasQmlDependencies) { - Q_ASSERT(d()->type == Heap::ExecutionContext::Type_QmlContext); - QQmlPropertyCapture::registerQmlDependencies(static_cast<QmlContext *>(this), engine, function->compiledFunction); + Q_ASSERT(context->type == Heap::ExecutionContext::Type_QmlContext); + QQmlPropertyCapture::registerQmlDependencies(static_cast<Heap::QmlContext *>(context), engine, function->compiledFunction); } engine->jsStackTop = jsStackTop; diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 44c434e637..1f62c64a23 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -193,7 +193,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed Q_MANAGED_TYPE(ExecutionContext) V4_INTERNALCLASS(ExecutionContext) - Heap::CallContext *newCallContext(Function *f, CallData *callData); + static Heap::CallContext *newCallContext(Heap::ExecutionContext *outer, Function *f, CallData *callData); Heap::ExecutionContext *newWithContext(Heap::Object *with); Heap::CatchContext *newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue); @@ -222,8 +222,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed return d()->callData->argument(i); } - ReturnedValue call(ExecutionEngine *engine, CallData *callData, QV4::Function *function, const QV4::FunctionObject *f = 0); - ReturnedValue simpleCall(ExecutionEngine *engine, CallData *callData, QV4::Function *function); + static ReturnedValue call(Heap::ExecutionContext *context, CallData *callData, QV4::Function *function, const QV4::FunctionObject *f = 0); }; struct Q_QML_EXPORT CallContext : public ExecutionContext diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index f175e2cd5d..95f8084607 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -368,13 +368,7 @@ ReturnedValue ScriptFunction::construct(const Managed *that, CallData *callData) QV4::Function *v4Function = f->function(); Q_ASSERT(v4Function); - Value s = Value::fromHeapObject(f->scope()); - ExecutionContext *outer = static_cast<ExecutionContext *>(&s); - ReturnedValue result; - if (v4Function->canUseSimpleCall) - result = outer->simpleCall(scope.engine, callData, v4Function); - else - result = outer->call(scope.engine, callData, v4Function, f); + ReturnedValue result = ExecutionContext::call(f->scope(), callData, v4Function, f); if (Q_UNLIKELY(v4->hasException)) return Encode::undefined(); @@ -394,12 +388,7 @@ ReturnedValue ScriptFunction::call(const Managed *that, CallData *callData) QV4::Function *v4Function = f->function(); Q_ASSERT(v4Function); - Value s = Value::fromHeapObject(f->scope()); - ExecutionContext *outer = static_cast<ExecutionContext *>(&s); - if (v4Function->canUseSimpleCall) - return outer->simpleCall(v4, callData, v4Function); - else - return outer->call(v4, callData, v4Function, f); + return ExecutionContext::call(f->scope(), callData, v4Function, f); } void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function) diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp index ef85ce43de..e5db62a749 100644 --- a/src/qml/jsruntime/qv4script.cpp +++ b/src/qml/jsruntime/qv4script.cpp @@ -156,10 +156,7 @@ ReturnedValue Script::run() Scoped<QmlContext> qml(valueScope, qmlContext.value()); ScopedCallData callData(valueScope); callData->thisObject = Primitive::undefinedValue(); - if (vmFunction->canUseSimpleFunction()) - return qml->simpleCall(valueScope.engine, callData, vmFunction); - else - return qml->call(valueScope.engine, callData, vmFunction); + return ExecutionContext::call(qml->d(), callData, vmFunction); } } diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 20c4f2ece6..02c346cf38 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -339,18 +339,6 @@ static struct InstrCount { #endif -// ### add write barrier here -#define STOREVALUE(param, value) { \ - QV4::ReturnedValue tmp = (value); \ - if (engine->hasException) \ - goto catchException; \ - if (Q_LIKELY(!engine->writeBarrierActive || !scopes[param.scope].base)) { \ - VALUE(param) = tmp; \ - } else { \ - QV4::WriteBarrier::write(engine, scopes[param.scope].base, VALUEPTR(param), QV4::Value::fromReturnedValue(tmp)); \ - } \ -} - #define STACK_VALUE(temp) stack[temp.stackSlot()] #define STORE_STACK_VALUE(temp, value) { \ QV4::ReturnedValue tmp = (value); \ @@ -448,15 +436,7 @@ QV4::ReturnedValue VME::exec(Heap::ExecutionContext *context, Function *function const uchar *exceptionHandler = 0; QV4::Scope scope(engine); - if (!function->canUseSimpleFunction()) { - int nFormals = function->nFormals; - stack = scope.alloc(nFormals + 1 + function->compiledFunction->nRegisters + sizeof(EngineBase::JSStackFrame)/sizeof(QV4::Value)); -// ### why copy those on the stack again? - memcpy(stack, &context->callData->thisObject, (nFormals + 1)*sizeof(Value)); - stack += nFormals + 1; - } else { - stack = scope.alloc(function->compiledFunction->nRegisters + sizeof(EngineBase::JSStackFrame)/sizeof(QV4::Value)); - } + stack = scope.alloc(function->compiledFunction->nRegisters + sizeof(EngineBase::JSStackFrame)/sizeof(QV4::Value)); frame.jsFrame = reinterpret_cast<EngineBase::JSStackFrame *>(stack); frame.jsFrame->context = context; if (jsFunction) @@ -777,7 +757,6 @@ QV4::ReturnedValue VME::exec(Heap::ExecutionContext *context, Function *function MOTH_BEGIN_INSTR(CreateValue) QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData.stackSlot()); STORE_ACCUMULATOR(Runtime::method_constructValue(engine, STACK_VALUE(instr.func), callData)); - //### write barrier? MOTH_END_INSTR(CreateValue) MOTH_BEGIN_INSTR(CreateProperty) diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 417698b5e8..614ec46afb 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -227,11 +227,7 @@ QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, b } QV4::ExecutionContext *outer = static_cast<QV4::ExecutionContext *>(m_qmlScope.valueRef()); - if (v4Function->canUseSimpleFunction()) { - result = outer->simpleCall(scope.engine, callData, v4Function); - } else { - result = outer->call(scope.engine, callData, v4Function); - } + result = QV4::ExecutionContext::call(outer->d(), callData, v4Function); if (scope.hasException()) { if (watcher.wasDeleted()) @@ -339,7 +335,7 @@ void QQmlPropertyCapture::captureProperty(QObject *o, int c, int n, Duration dur } } -void QQmlPropertyCapture::registerQmlDependencies(QV4::QmlContext *context, const QV4::ExecutionEngine *engine, const QV4::CompiledData::Function *compiledFunction) +void QQmlPropertyCapture::registerQmlDependencies(QV4::Heap::QmlContext *context, const QV4::ExecutionEngine *engine, const QV4::CompiledData::Function *compiledFunction) { // Let the caller check and avoid the function call :) Q_ASSERT(compiledFunction->hasQmlDependencies()); @@ -356,7 +352,7 @@ void QQmlPropertyCapture::registerQmlDependencies(QV4::QmlContext *context, cons capture->expression->m_permanentDependenciesRegistered = true; - QV4::Heap::QQmlContextWrapper *wrapper = context->d()->qml(); + QV4::Heap::QQmlContextWrapper *wrapper = context->qml(); QQmlContextData *qmlContext = wrapper->context->contextData(); const QV4::CompiledData::LEUInt32 *idObjectDependency = compiledFunction->qmlIdObjectDependencyTable(); diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index f6993436f1..4d4c2e6c9f 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -203,7 +203,7 @@ public: Permanently }; - static void registerQmlDependencies(QV4::QmlContext *context, const QV4::ExecutionEngine *engine, const QV4::CompiledData::Function *compiledFunction); + static void registerQmlDependencies(QV4::Heap::QmlContext *context, const QV4::ExecutionEngine *engine, const QV4::CompiledData::Function *compiledFunction); void captureProperty(QQmlNotifier *, Duration duration = OnlyOnce); void captureProperty(QObject *, int, int, Duration duration = OnlyOnce); |