aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-08 16:56:59 +0200
committerLars Knoll <lars.knoll@qt.io>2017-08-10 08:19:24 +0000
commit55f17d0faad79dbb9adf793f7ce6e75ff5b70033 (patch)
tree5a5e34a98a196173c707f62d972a3a4984c146de /src
parent5bc4f4d958a3b76f3435d61206ca0109f07aa1a3 (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.cpp49
-rw-r--r--src/qml/jsruntime/qv4context_p.h5
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp15
-rw-r--r--src/qml/jsruntime/qv4script.cpp5
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp23
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp10
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h2
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);