From 11a1f28e3c5ebf9dd20a4b7767a66d64edb3ae9d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sun, 7 Apr 2013 17:23:36 +0200 Subject: [PATCH] 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 --- src/v4/qv4context.cpp | 3 -- src/v4/qv4context.h | 1 + src/v4/qv4engine.cpp | 77 ++++++++++----------------------------------------- src/v4/qv4engine.h | 22 +++++++++------ src/v4/qv4mm.cpp | 4 --- src/v4/qv4runtime.cpp | 2 +- src/v4/qv4v8.cpp | 9 +++--- 7 files changed, 33 insertions(+), 85 deletions(-) diff --git a/src/v4/qv4context.cpp b/src/v4/qv4context.cpp index c2ecec8..462ac96 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 e70ca8b..c26cc6b 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 eb0aab8..4e23fa2 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(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(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(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(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(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 1537027..3991c80 100644 --- a/src/v4/qv4engine.h +++ b/src/v4/qv4engine.h @@ -109,10 +109,6 @@ struct Q_V4_EXPORT ExecutionEngine ExecutableAllocator *executableAllocator; QScopedPointer 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 bc4bd66..19e0e3f 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::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 c889753..b539f9d 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 835c825..067e656 100644 --- a/src/v4/qv4v8.cpp +++ b/src/v4/qv4v8.cpp @@ -334,17 +334,16 @@ Local 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::New(Handle(trace)); -- 2.7.4