diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-04-03 20:24:38 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2013-04-04 15:32:21 +0200 |
commit | 90dbc177757e16ad6cfcf5a195cbf610fe68a92d (patch) | |
tree | 72a3305e60e86cc2729a599e2b6925d609996460 | |
parent | aecf1c22d38816269b27c8e8d70a9767c57dbc1d (diff) |
Create some execution contexts on the stack again
This seems to be working now, and speeds up our benchmarks
with another 20%.
Change-Id: Ib01bf8f66db91b0e06090eff705db79b0caf66ee
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r-- | src/v4/qv4context.cpp | 3 | ||||
-rw-r--r-- | src/v4/qv4context.h | 1 | ||||
-rw-r--r-- | src/v4/qv4engine.cpp | 27 | ||||
-rw-r--r-- | src/v4/qv4engine.h | 1 | ||||
-rw-r--r-- | src/v4/qv4functionobject.cpp | 9 |
5 files changed, 39 insertions, 2 deletions
diff --git a/src/v4/qv4context.cpp b/src/v4/qv4context.cpp index 51a80f4a..88365f4f 100644 --- a/src/v4/qv4context.cpp +++ b/src/v4/qv4context.cpp @@ -542,6 +542,9 @@ void ExecutionContext::initCallContext(ExecutionEngine *engine) marked = false; this->engine = engine; outer = function->scope; +#ifndef QT_NO_DEBUG + assert(outer->next != (ExecutionContext *)0x1); +#endif exceptionVarName = 0; exceptionValue = Value::undefinedValue(); diff --git a/src/v4/qv4context.h b/src/v4/qv4context.h index d2b05bbf..454cedb6 100644 --- a/src/v4/qv4context.h +++ b/src/v4/qv4context.h @@ -145,6 +145,7 @@ struct ExecutionContext /* Function *f, int argc */ #define requiredMemoryForExecutionContect(f, argc) \ sizeof(ExecutionContext) + sizeof(Value) * (f->varCount + qMax((uint)argc, f->formalParameterCount)) +#define stackContextSize (sizeof(ExecutionContext) + 32*sizeof(Value)) } // namespace VM } // namespace QQmlJS diff --git a/src/v4/qv4engine.cpp b/src/v4/qv4engine.cpp index d944de80..f23ce33b 100644 --- a/src/v4/qv4engine.cpp +++ b/src/v4/qv4engine.cpp @@ -317,6 +317,33 @@ ExecutionContext *ExecutionEngine::newCallContext(FunctionObject *f, const Value return current; } +ExecutionContext *ExecutionEngine::newCallContext(void *stackSpace, FunctionObject *f, const Value &thisObject, Value *args, int argc) +{ + ensureContextStackSize(); + assert(contextStack[contextStackPosition + 1] == 0); + + uint memory = requiredMemoryForExecutionContect(f, argc); + if (f->needsActivation || memory > stackContextSize) { + current = memoryManager->allocContext(memory); + } else { + current = (ExecutionContext *)stackSpace; +#ifndef QT_NO_DEBUG + current->next = (ExecutionContext *)0x1; +#endif + } + + contextStack[++contextStackPosition] = current; + + current->function = f; + current->thisObject = thisObject; + current->arguments = args; + current->argumentCount = argc; + current->initCallContext(this); + + return current; +} + + ExecutionContext *ExecutionEngine::pushGlobalContext() { ensureContextStackSize(); diff --git a/src/v4/qv4engine.h b/src/v4/qv4engine.h index a4b3bd83..b3dd3dc0 100644 --- a/src/v4/qv4engine.h +++ b/src/v4/qv4engine.h @@ -201,6 +201,7 @@ struct Q_V4_EXPORT ExecutionEngine ExecutionContext *newWithContext(Object *with); ExecutionContext *newCatchContext(String* exceptionVarName, const QQmlJS::VM::Value &exceptionValue); ExecutionContext *newCallContext(FunctionObject *f, const QQmlJS::VM::Value &thisObject, QQmlJS::VM::Value *args, int argc); + ExecutionContext *newCallContext(void *stackSpace, FunctionObject *f, const QQmlJS::VM::Value &thisObject, QQmlJS::VM::Value *args, int argc); ExecutionContext *pushGlobalContext(); ExecutionContext *popContext(); diff --git a/src/v4/qv4functionobject.cpp b/src/v4/qv4functionobject.cpp index 83762e85..801291e0 100644 --- a/src/v4/qv4functionobject.cpp +++ b/src/v4/qv4functionobject.cpp @@ -103,6 +103,9 @@ FunctionObject::FunctionObject(ExecutionContext *scope) needsActivation = true; usesArgumentsObject = false; strictMode = false; +#ifndef QT_NO_DEBUG + assert(scope->next != (ExecutionContext *)0x1); +#endif } bool FunctionObject::hasInstance(Managed *that, ExecutionContext *ctx, const Value &value) @@ -364,7 +367,8 @@ Value ScriptFunction::construct(Managed *that, ExecutionContext *context, Value if (proto.isObject()) obj->prototype = proto.objectValue(); - ExecutionContext *ctx = context->engine->newCallContext(f, Value::fromObject(obj), args, argc); + quintptr stackSpace[stackContextSize/sizeof(quintptr)]; + ExecutionContext *ctx = context->engine->newCallContext(stackSpace, f, Value::fromObject(obj), args, argc); Value result = Value::undefinedValue(); try { @@ -384,7 +388,8 @@ Value ScriptFunction::call(Managed *that, ExecutionContext *context, const Value { ScriptFunction *f = static_cast<ScriptFunction *>(that); assert(f->function->code); - ExecutionContext *ctx = context->engine->newCallContext(f, thisObject, args, argc); + quintptr stackSpace[stackContextSize/sizeof(quintptr)]; + ExecutionContext *ctx = context->engine->newCallContext(stackSpace, f, thisObject, args, argc); if (!f->strictMode && !thisObject.isObject()) { if (thisObject.isUndefined() || thisObject.isNull()) { |