aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4context.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-01-30 11:59:58 +0100
committerLars Knoll <lars.knoll@qt.io>2017-03-09 08:58:17 +0000
commit3a0bb11d730390ce9fd64932f58269cfbe8c378e (patch)
tree5594a367f4e785f81e78af077699942f76a50840 /src/qml/jsruntime/qv4context.cpp
parent10c1e4053366085080a39ea84ebbd189c8d827ec (diff)
Separate SimpleCallData and CallData
SimpleCallData doesn't need any loca variables, so move it into a separate CallData Heap object. This also allows getting rid of the manual markObjects() implementation for CallContext. Change-Id: I9014eb2f815d3e2fe63a951a9d126c38e8aaa0a3 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4context.cpp')
-rw-r--r--src/qml/jsruntime/qv4context.cpp110
1 files changed, 42 insertions, 68 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 569523595c..ec11422c15 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -54,20 +54,19 @@
using namespace QV4;
DEFINE_MANAGED_VTABLE(ExecutionContext);
+DEFINE_MANAGED_VTABLE(SimpleCallContext);
DEFINE_MANAGED_VTABLE(CallContext);
DEFINE_MANAGED_VTABLE(WithContext);
DEFINE_MANAGED_VTABLE(CatchContext);
DEFINE_MANAGED_VTABLE(GlobalContext);
-/* Function *f, int argc */
-#define requiredMemoryForExecutionContect(f, argc) \
- sizeof(CallContext::Data) - sizeof(Value) + \
- sizeof(Value) * (f->compiledFunction->nLocals + qMax((uint)argc, f->nFormals)) + sizeof(CallData)
-
Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData *callData)
{
- Heap::CallContext *c = d()->engine->memoryManager->allocManaged<CallContext>(
- requiredMemoryForExecutionContect(function, callData->argc));
+ uint localsAndFormals = function->compiledFunction->nLocals + qMax(static_cast<uint>(callData->argc), function->nFormals);
+ size_t requiredMemory = sizeof(CallContext::Data) - sizeof(Value) + \
+ sizeof(Value) * (localsAndFormals) + sizeof(CallData) - sizeof(Value);
+
+ Heap::CallContext *c = d()->engine->memoryManager->allocManaged<CallContext>(requiredMemory);
c->init(d()->engine, Heap::ExecutionContext::Type_CallContext);
c->v4Function = function;
@@ -75,36 +74,25 @@ Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData
c->strictMode = function->isStrict();
c->outer = this->d();
- c->activation = 0;
-
c->compilationUnit = function->compilationUnit;
c->lookups = c->compilationUnit->runtimeLookups;
c->constantTable = c->compilationUnit->constants;
const CompiledData::Function *compiledFunction = function->compiledFunction;
- int nLocals = compiledFunction->nLocals;
+ uint nLocals = compiledFunction->nLocals;
+ c->locals.size = nLocals;
+ c->locals.alloc = localsAndFormals;
if (nLocals)
- std::fill(c->locals, c->locals + nLocals, Primitive::undefinedValue());
+ std::fill(c->locals.v, c->locals.v + nLocals, Primitive::undefinedValue());
- c->callData = reinterpret_cast<CallData *>(c->locals + nLocals);
- ::memcpy(c->callData, callData, sizeof(CallData) + (callData->argc - 1) * sizeof(Value));
+ c->callData = reinterpret_cast<CallData *>(c->locals.v + 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());
return c;
}
-Heap::CallContext *Heap::CallContext::createSimpleContext(ExecutionEngine *v4)
-{
- Heap::CallContext *ctxt = v4->memoryManager->allocSimpleCallContext(v4);
- return ctxt;
-}
-
-void Heap::CallContext::freeSimpleCallContext()
-{
- engine->memoryManager->freeSimpleCallContext();
-}
-
Heap::WithContext *ExecutionContext::newWithContext(Heap::Object *with)
{
return d()->engine->memoryManager->alloc<WithContext>(d(), with);
@@ -128,7 +116,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
switch (ctx->d()->type) {
case Heap::ExecutionContext::Type_CallContext:
case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
+ Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
if (!activation) {
if (!c->activation)
c->activation = scope.engine->newObject();
@@ -184,22 +172,22 @@ void Heap::CatchContext::init(ExecutionContext *outerContext, String *exceptionV
}
-Identifier * const *CallContext::formals() const
+Identifier * const *SimpleCallContext::formals() const
{
return d()->v4Function ? d()->v4Function->internalClass->nameMap.constData() : 0;
}
-unsigned int CallContext::formalCount() const
+unsigned int SimpleCallContext::formalCount() const
{
return d()->v4Function ? d()->v4Function->nFormals : 0;
}
-Identifier * const *CallContext::variables() const
+Identifier * const *SimpleCallContext::variables() const
{
return d()->v4Function ? d()->v4Function->internalClass->nameMap.constData() + d()->v4Function->nFormals : 0;
}
-unsigned int CallContext::variableCount() const
+unsigned int SimpleCallContext::variableCount() const
{
return d()->v4Function ? d()->v4Function->compiledFunction->nLocals : 0;
}
@@ -234,7 +222,7 @@ bool ExecutionContext::deleteProperty(String *name)
}
case Heap::ExecutionContext::Type_CallContext:
case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
+ Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
if (c->v4Function && (c->v4Function->needsActivation() || hasWith)) {
uint index = c->v4Function->internalClass->find(name);
if (index < UINT_MAX)
@@ -257,30 +245,6 @@ bool ExecutionContext::deleteProperty(String *name)
return true;
}
-bool CallContext::needsOwnArguments() const
-{
- QV4::Function *f = d()->v4Function;
- return (f && f->needsActivation()) || (argc() < (f ? static_cast<int>(f->nFormals) : 0));
-}
-
-void CallContext::markObjects(Heap::Base *m, ExecutionEngine *engine)
-{
- QV4::Heap::CallContext *ctx = static_cast<Heap::CallContext *>(m);
-
- if (ctx->type == Heap::ExecutionContext::Type_CallContext) {
- Q_ASSERT(ctx->v4Function);
- ctx->callData->thisObject.mark(engine);
- for (int arg = 0; arg < qMax(ctx->callData->argc, (int)ctx->v4Function->nFormals); ++arg)
- ctx->callData->args[arg].mark(engine);
- for (unsigned local = 0, lastLocal = ctx->v4Function->compiledFunction->nLocals; local < lastLocal; ++local)
- ctx->locals[local].mark(engine);
- if (ctx->activation)
- ctx->activation->mark(engine);
- if (ctx->function)
- ctx->function->mark(engine);
- }
-}
-
// Do a standard call with this execution context as the outer scope
void ExecutionContext::call(Scope &scope, CallData *callData, Function *function, const FunctionObject *f)
{
@@ -304,7 +268,7 @@ void QV4::ExecutionContext::simpleCall(Scope &scope, CallData *callData, Functio
ExecutionContextSaver ctxSaver(scope);
- CallContext::Data *ctx = scope.engine->memoryManager->allocSimpleCallContext(scope.engine);
+ SimpleCallContext::Data *ctx = scope.engine->memoryManager->allocSimpleCallContext(scope.engine);
ctx->strictMode = function->isStrict();
ctx->callData = callData;
@@ -357,15 +321,16 @@ void ExecutionContext::setProperty(String *name, const Value &value)
}
case Heap::ExecutionContext::Type_CallContext:
case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
+ Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
if (c->v4Function) {
uint index = c->v4Function->internalClass->find(name);
if (index < UINT_MAX) {
if (index < c->v4Function->nFormals) {
c->callData->args[c->v4Function->nFormals - index - 1] = value;
} else {
+ Q_ASSERT(c->type = Heap::ExecutionContext::Type_CallContext);
index -= c->v4Function->nFormals;
- c->locals[index] = value;
+ static_cast<Heap::CallContext *>(c)->locals[index] = value;
}
return;
}
@@ -438,13 +403,14 @@ ReturnedValue ExecutionContext::getProperty(String *name)
}
case Heap::ExecutionContext::Type_CallContext:
case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
+ Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
if (c->v4Function && (c->v4Function->needsActivation() || hasWith || hasCatchScope)) {
uint index = c->v4Function->internalClass->find(name);
if (index < UINT_MAX) {
if (index < c->v4Function->nFormals)
return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue();
- return c->locals[index - c->v4Function->nFormals].asReturnedValue();
+ Q_ASSERT(c->type = Heap::ExecutionContext::Type_CallContext);
+ return static_cast<Heap::CallContext *>(c)->locals[index - c->v4Function->nFormals].asReturnedValue();
}
}
ScopedObject activation(scope, c->activation);
@@ -454,9 +420,12 @@ ReturnedValue ExecutionContext::getProperty(String *name)
if (hasProperty)
return v->asReturnedValue();
}
- if (c->function && c->v4Function->isNamedExpression()
- && name->equals(ScopedString(scope, c->v4Function->name())))
- return c->function->asReturnedValue();
+ if (c->v4Function->isNamedExpression()) {
+ Q_ASSERT(c->type == Heap::CallContext::Type_CallContext);
+ Heap::CallContext *ctx = static_cast<Heap::CallContext *>(c);
+ if (ctx->function && name->equals(ScopedString(scope, c->v4Function->name())))
+ return ctx->function->asReturnedValue();
+ }
break;
}
case Heap::ExecutionContext::Type_QmlContext: {
@@ -516,13 +485,15 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base)
}
case Heap::ExecutionContext::Type_CallContext:
case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
+ Heap::SimpleCallContext *c = static_cast<Heap::SimpleCallContext *>(ctx->d());
if (c->v4Function && (c->v4Function->needsActivation() || hasWith || hasCatchScope)) {
+ Q_ASSERT(c->type == Heap::CallContext::Type_CallContext);
+ Heap::CallContext *ctx = static_cast<Heap::CallContext *>(c);
uint index = c->v4Function->internalClass->find(name);
if (index < UINT_MAX) {
if (index < c->v4Function->nFormals)
return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue();
- return c->locals[index - c->v4Function->nFormals].asReturnedValue();
+ return ctx->locals[index - c->v4Function->nFormals].asReturnedValue();
}
}
ScopedObject activation(scope, c->activation);
@@ -532,9 +503,12 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base)
if (hasProperty)
return v->asReturnedValue();
}
- if (c->function && c->v4Function->isNamedExpression()
- && name->equals(ScopedString(scope, c->v4Function->name())))
- return c->function->asReturnedValue();
+ if (c->v4Function->isNamedExpression()) {
+ Q_ASSERT(c->type == Heap::CallContext::Type_CallContext);
+ Heap::CallContext *ctx = static_cast<Heap::CallContext *>(c);
+ if (ctx->function && name->equals(ScopedString(scope, c->v4Function->name())))
+ return ctx->function->asReturnedValue();
+ }
break;
}
case Heap::ExecutionContext::Type_QmlContext: {
@@ -558,7 +532,7 @@ Function *ExecutionContext::getFunction() const
Scope scope(d()->engine);
ScopedContext it(scope, this->d());
for (; it; it = it->d()->outer) {
- if (const CallContext *callCtx = it->asCallContext())
+ if (const SimpleCallContext *callCtx = it->asSimpleCallContext())
return callCtx->d()->v4Function;
else if (it->asCatchContext() || it->asWithContext())
continue; // look in the parent context for a FunctionObject