summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-04-03 20:24:38 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-04-04 15:32:21 +0200
commit90dbc177757e16ad6cfcf5a195cbf610fe68a92d (patch)
tree72a3305e60e86cc2729a599e2b6925d609996460
parentaecf1c22d38816269b27c8e8d70a9767c57dbc1d (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.cpp3
-rw-r--r--src/v4/qv4context.h1
-rw-r--r--src/v4/qv4engine.cpp27
-rw-r--r--src/v4/qv4engine.h1
-rw-r--r--src/v4/qv4functionobject.cpp9
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()) {