aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-04-07 17:23:36 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-04-07 21:24:35 +0200
commit11a1f28e3c5ebf9dd20a4b7767a66d64edb3ae9d (patch)
tree6860900e23e78e43721d666e3eced4152032f0f7 /src
parentab62ad883041221ceda6cf8f80bf4720b9e93998 (diff)
Change the Context stack back to a singly linked list
The other implementation was too complicated, and only solved one special case (indirect eval calls), but that one can be solved by simply creating a GlobalContext when needed. In addition it'll make it simpler to implement context optimisations for simple methods in the future. Speeds up the V8 benchmark by 3% Change-Id: I61ac7753821e0174476094f51a9a4e934563f8e0 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/v4/qv4context.cpp3
-rw-r--r--src/v4/qv4context.h1
-rw-r--r--src/v4/qv4engine.cpp77
-rw-r--r--src/v4/qv4engine.h22
-rw-r--r--src/v4/qv4mm.cpp4
-rw-r--r--src/v4/qv4runtime.cpp2
-rw-r--r--src/v4/qv4v8.cpp9
7 files changed, 33 insertions, 85 deletions
diff --git a/src/v4/qv4context.cpp b/src/v4/qv4context.cpp
index c2ecec820c..462ac969fb 100644
--- a/src/v4/qv4context.cpp
+++ b/src/v4/qv4context.cpp
@@ -213,9 +213,6 @@ void CallContext::initCallContext(ExecutionEngine *engine)
desc.enumerable = PropertyDescriptor::Enabled;
activation->__defineOwnProperty__(this, engine->id_arguments, &desc);
}
-
- if (engine->debugger)
- engine->debugger->aboutToCall(function, this);
}
diff --git a/src/v4/qv4context.h b/src/v4/qv4context.h
index e70ca8b5a6..c26cc6bfc5 100644
--- a/src/v4/qv4context.h
+++ b/src/v4/qv4context.h
@@ -93,6 +93,7 @@ struct ExecutionContext
Value thisObject;
ExecutionEngine *engine;
+ ExecutionContext *parent;
ExecutionContext *outer;
Lookup *lookups;
ExecutionContext *next; // used in the GC
diff --git a/src/v4/qv4engine.cpp b/src/v4/qv4engine.cpp
index eb0aab878d..4e23fa2b98 100644
--- a/src/v4/qv4engine.cpp
+++ b/src/v4/qv4engine.cpp
@@ -68,9 +68,6 @@ namespace VM {
ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
: memoryManager(new QQmlJS::VM::MemoryManager)
, executableAllocator(new QQmlJS::VM::ExecutableAllocator)
- , contextStack(0)
- , contextStackPosition(0)
- , contextStackSize(0)
, debugger(0)
, globalObject(Value::nullValue())
, globalCode(0)
@@ -243,7 +240,6 @@ ExecutionEngine::~ExecutionEngine()
{
delete regExpCache;
delete globalObject.asObject();
- delete [] contextStack;
UnwindHelper::deregisterFunctions(functions);
qDeleteAll(functions);
delete memoryManager;
@@ -252,37 +248,18 @@ ExecutionEngine::~ExecutionEngine()
void ExecutionEngine::initRootContext()
{
- ensureContextStackSize();
rootContext = static_cast<GlobalContext *>(memoryManager->allocContext(sizeof(GlobalContext)));
current = rootContext;
- contextStack[0] = rootContext;
+ current->parent = 0;
rootContext->init(this);
}
-void ExecutionEngine::ensureContextStackSize()
-{
- if (contextStackPosition < contextStackSize - 1)
- return;
-
- const int stackSize = qMax(32, 2*contextStackSize);
- ExecutionContext **newStack = new ExecutionContext *[stackSize];
- if (contextStack)
- memcpy(newStack, contextStack, contextStackSize*sizeof(ExecutionContext *));
- memset(newStack + contextStackSize, 0, (stackSize - contextStackSize)*sizeof(ExecutionContext *));
- delete [] contextStack;
- contextStackSize = stackSize;
- contextStack = newStack;
-}
-
WithContext *ExecutionEngine::newWithContext(Object *with)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
ExecutionContext *p = current;
WithContext *w = static_cast<WithContext *>(memoryManager->allocContext(sizeof(WithContext)));
+ w->parent = current;
current = w;
- contextStack[++contextStackPosition] = current;
w->init(p, with);
return w;
@@ -290,13 +267,10 @@ WithContext *ExecutionEngine::newWithContext(Object *with)
CatchContext *ExecutionEngine::newCatchContext(String *exceptionVarName, const Value &exceptionValue)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
ExecutionContext *p = current;
CatchContext *c = static_cast<CatchContext *>(memoryManager->allocContext(sizeof(CatchContext)));
+ c->parent = current;
current = c;
- contextStack[++contextStackPosition] = current;
c->init(p, exceptionVarName, exceptionValue);
return c;
@@ -304,12 +278,9 @@ CatchContext *ExecutionEngine::newCatchContext(String *exceptionVarName, const V
CallContext *ExecutionEngine::newCallContext(FunctionObject *f, const Value &thisObject, Value *args, int argc)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
CallContext *c = static_cast<CallContext *>(memoryManager->allocContext(requiredMemoryForExecutionContect(f, argc)));
+ c->parent = current;
current = c;
- contextStack[++contextStackPosition] = current;
c->function = f;
c->thisObject = thisObject;
@@ -322,9 +293,6 @@ CallContext *ExecutionEngine::newCallContext(FunctionObject *f, const Value &thi
CallContext *ExecutionEngine::newCallContext(void *stackSpace, FunctionObject *f, const Value &thisObject, Value *args, int argc)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
CallContext *c;
uint memory = requiredMemoryForExecutionContect(f, argc);
if (f->needsActivation || memory > stackContextSize) {
@@ -335,10 +303,9 @@ CallContext *ExecutionEngine::newCallContext(void *stackSpace, FunctionObject *f
c->next = (CallContext *)0x1;
#endif
}
+ c->parent = current;
current = c;
- contextStack[++contextStackPosition] = current;
-
c->function = f;
c->thisObject = thisObject;
c->arguments = args;
@@ -351,30 +318,11 @@ CallContext *ExecutionEngine::newCallContext(void *stackSpace, FunctionObject *f
ExecutionContext *ExecutionEngine::pushGlobalContext()
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
- current = rootContext;
-
- contextStack[++contextStackPosition] = current;
- return current;
-}
-
-ExecutionContext *ExecutionEngine::popContext()
-{
- assert(current == contextStack[contextStackPosition]);
+ GlobalContext *g = static_cast<GlobalContext *>(memoryManager->allocContext(sizeof(GlobalContext)));
+ *g = *rootContext;
+ g->parent = current;
+ current = g;
- if (debugger)
- debugger->justLeft(current);
-
- CallContext *c = current->asCallContext();
- if (c && !c->needsOwnArguments()) {
- c->arguments = 0;
- c->argumentCount = 0;
- }
-
- contextStack[contextStackPosition] = 0;
- current = contextStack[--contextStackPosition];
return current;
}
@@ -558,8 +506,11 @@ void ExecutionEngine::markObjects()
pd.set->mark();
}
- for (int i = 0; i <= contextStackPosition; ++i)
- contextStack[i]->mark();
+ ExecutionContext *c = current;
+ while (c) {
+ c->mark();
+ c = c->parent;
+ }
for (int i = 0; i < functions.size(); ++i)
functions.at(i)->mark();
diff --git a/src/v4/qv4engine.h b/src/v4/qv4engine.h
index 1537027e4d..3991c809d7 100644
--- a/src/v4/qv4engine.h
+++ b/src/v4/qv4engine.h
@@ -109,10 +109,6 @@ struct Q_V4_EXPORT ExecutionEngine
ExecutableAllocator *executableAllocator;
QScopedPointer<EvalISelFactory> iselFactory;
- ExecutionContext **contextStack;
- int contextStackPosition;
- int contextStackSize;
-
ExecutionContext *current;
GlobalContext *rootContext;
@@ -245,19 +241,27 @@ struct Q_V4_EXPORT ExecutionEngine
Value run(VM::Function *function, ExecutionContext *ctx = 0);
void initRootContext();
- void ensureContextStackSize();
};
inline void ExecutionEngine::pushContext(SimpleCallContext *context)
{
- ensureContextStackSize();
- assert(contextStack[contextStackPosition + 1] == 0);
-
+ context->parent = current;
current = context;
+}
- contextStack[++contextStackPosition] = current;
+inline ExecutionContext *ExecutionEngine::popContext()
+{
+ CallContext *c = current->asCallContext();
+ if (c && !c->needsOwnArguments()) {
+ c->arguments = 0;
+ c->argumentCount = 0;
+ }
+
+ current = current->parent;
+ return current;
}
+
} // namespace VM
} // namespace QQmlJS
diff --git a/src/v4/qv4mm.cpp b/src/v4/qv4mm.cpp
index bc4bd66316..19e0e3fd68 100644
--- a/src/v4/qv4mm.cpp
+++ b/src/v4/qv4mm.cpp
@@ -237,10 +237,6 @@ void MemoryManager::mark()
{
m_d->engine->markObjects();
- ExecutionEngine *e = engine();
- for (int i = 0; i <= e->contextStackPosition; ++i)
- e->contextStack[i]->mark();
-
for (QHash<Managed *, uint>::const_iterator it = m_d->protectedObject.begin(); it != m_d->protectedObject.constEnd(); ++it)
it.key()->mark();
diff --git a/src/v4/qv4runtime.cpp b/src/v4/qv4runtime.cpp
index c889753392..b539f9d0ca 100644
--- a/src/v4/qv4runtime.cpp
+++ b/src/v4/qv4runtime.cpp
@@ -119,7 +119,7 @@ QString numberToString(double num, int radix = 10)
Exception::Exception(ExecutionContext *throwingContext, const Value &exceptionValue)
{
- this->throwingContext = throwingContext;
+ this->throwingContext = throwingContext->engine->current;
this->exception = PersistentValue(throwingContext->engine->memoryManager, exceptionValue);
accepted = false;
}
diff --git a/src/v4/qv4v8.cpp b/src/v4/qv4v8.cpp
index 835c825dfb..067e656134 100644
--- a/src/v4/qv4v8.cpp
+++ b/src/v4/qv4v8.cpp
@@ -334,17 +334,16 @@ Local<StackTrace> StackTrace::CurrentStackTrace(int frame_limit, StackTrace::Sta
{
StackTrace *trace = new StackTrace;
VM::ExecutionEngine *engine = currentEngine();
- VM::ExecutionContext **root = engine->contextStack;
- VM::ExecutionContext **current = root + engine->contextStackPosition;
- while (current >= root && frame_limit) {
- if (CallContext *c = (*current)->asCallContext()) {
+ VM::ExecutionContext *current = engine->current;
+ while (current && frame_limit) {
+ if (CallContext *c = current->asCallContext()) {
StackFrame *frame = new StackFrame(Value::fromVmValue(VM::Value::fromString(engine->id_null)),
Value::fromVmValue(VM::Value::fromString(c->function->name)),
0, 0);
trace->frames.append(frame);
--frame_limit;
}
- --current;
+ current = current->parent;
}
return Local<StackTrace>::New(Handle<StackTrace>(trace));