From kde-commits Sat May 01 17:37:56 2010 From: Maks Orlovich Date: Sat, 01 May 2010 17:37:56 +0000 To: kde-commits Subject: KDE/kdelibs/kjs Message-Id: <20100501173756.1A567AC8AA () svn ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=127273529216194 SVN commit 1121561 by orlovich: Simplify the call sequence a bit more, by hoisting some of the debugger checks out to the compiler. Maybe a tiny speedup, too. M +24 -7 bytecode/codes.def M +28 -0 bytecode/machine.cpp.in M +0 -21 function.cpp M +5 -0 function.h M +32 -3 nodes2bytecode.cpp --- trunk/KDE/kdelibs/kjs/bytecode/codes.def #1121560:1121561 @@ -240,12 +240,6 @@ ]] } -operation ExitEval[endsBB] { - impl void(value val) [[ - return val; - ]] -} - operation Jump[endsBB] { impl void jmp(addr dest) [[ pc = base + dest; @@ -411,6 +405,17 @@ ]] } +operation ReactivateCompletionDebug { + // version for inside functions + debug mode, which calls ExitContext + impl void(bool insideFinally, node n) [[ + JSValue* retVal = exec->reactivateCompletion(insideFinally); + if (retVal) { + changeDebugContext(Exit, exec, n); + return retVal; + } + ]] +} + operation Throw { impl void throw(value exception) [[ exec->setException(exception); @@ -438,7 +443,7 @@ ]] } -operation Return { +operation Return[endsBB] { impl void return (value retVal) [[ return retVal; ]] @@ -459,6 +464,18 @@ ]] } +operation EnterDebugContext { + impl void(node n) [[ + changeDebugContext(Enter, exec, n); + ]] +} + +operation ExitDebugContext { + impl void(node n) [[ + changeDebugContext(Exit, exec, n); + ]] +} + // Variable stuff... Locals access can just use register addressing, // not specific get/put, but when we have to do symbolic lookup, we use these. --- trunk/KDE/kdelibs/kjs/bytecode/machine.cpp.in #1121560:1121561 @@ -31,6 +31,7 @@ #include "scriptfunction.h" #include "internal.h" // for printInfo #include "ustring.h" +#include "debugger.h" #include @@ -175,6 +176,33 @@ return ret; } +enum Dir { Enter, Exit }; + +NEVER_INLINE void changeDebugContext(Dir d, ExecState* exec, Node* n) { + FunctionBodyNode* body = static_cast(n); + Debugger* dbg = exec->dynamicInterpreter()->debugger(); + List args; + FunctionImp* fn = 0; + + // Find the activation that contains arguments, fn + const ScopeChain& chain = exec->scopeChain(); + for (ScopeChainIterator iter = chain.begin(); iter != chain.end(); ++iter) { + JSObject* scopeObj = *iter; + + if (scopeObj->isActivation()) { + ActivationImp* act = static_cast(scopeObj); + args = act->passedInArguments(); + fn = static_cast(act->function()); + break; + } + } + + if (d == Enter) + dbg->enterContext(exec, body->sourceId(), body->firstLine(), fn, args); + else + dbg->exitContext(exec, body->sourceId(), body->lastLine(), fn); +} + struct DepthCleanup { ~DepthCleanup() { --depth; } --- trunk/KDE/kdelibs/kjs/function.cpp #1121560:1121561 @@ -165,14 +165,6 @@ activation->setup(&newExec, this, &args, stackSpace); activation->tearOffNeededSlot() = body->tearOffAtEnd(); - if (dbg) { - bool cont = dbg->enterContext(&newExec, body->sourceId(), body->firstLine(), this, args); - if (!cont) { - dbg->imp()->abort(); - return jsUndefined(); - } - } - newExec.initLocalStorage(stackSpace, regs); JSValue* result = Machine::runBlock(&newExec, body->code(), exec); @@ -203,19 +195,6 @@ --callDepth; #endif - // The debugger may have been deallocated by now if the WebFrame - // we were running in has been destroyed, so refetch it. - // See http://bugs.webkit.org/show_bug.cgi?id=9477 - dbg = exec->dynamicInterpreter()->debugger(); - - if (dbg) { - int cont = dbg->exitContext(&newExec, body->sourceId(), body->lastLine(), this); - if (!cont) { - dbg->imp()->abort(); - return jsUndefined(); - } - } - return result; } --- trunk/KDE/kdelibs/kjs/function.h #1121560:1121561 @@ -140,6 +140,11 @@ virtual bool isActivation() const { return true; } void setupLocals(FunctionBodyNode* fbody); void setupFunctionLocals(FunctionBodyNode* fbody, ExecState *exec); + + const List& passedInArguments() const { return *arguments; } + + // really FunctionImp, but type isn't declared yet + JSValue* function() { return functionSlot(); } private: JSValue*& functionSlot() { return localStorage[FunctionSlot].val.valueVal; --- trunk/KDE/kdelibs/kjs/nodes2bytecode.cpp #1121560:1121561 @@ -70,6 +70,18 @@ CodeGen::emitOp(comp, Op_AtStatement, 0, &me); } +static inline bool exitContextNeeded(CompileState* comp) { + return comp->compileType() == Debug && + comp->codeType() == FunctionCode; +} + +static void generateExitContextIfNeeded(CompileState* comp) { + if (exitContextNeeded(comp)) { + OpValue ourNode = OpValue::immNode(comp->functionBody()); + CodeGen::emitOp(comp, Op_ExitDebugContext, 0, &ourNode); + } +} + // ------------------------------ Basic literals ----------------------------------------- OpValue NullNode::generateEvalCode(CompileState*) @@ -1405,6 +1417,9 @@ else arg = value->generateEvalCode(comp); + if (!comp->inTryFinally()) + generateExitContextIfNeeded(comp); + CodeGen::emitOp(comp, comp->inTryFinally() ? Op_ReturnInTryFinally : Op_Return, 0, &arg); } @@ -1525,7 +1540,13 @@ finallyBlock->generateExecCode(comp); OpValue otherTryFinally = OpValue::immBool(comp->inTryFinally()); + + if (exitContextNeeded(comp)) { + OpValue ourNode = OpValue::immNode(comp->functionBody()); + CodeGen::emitOp(comp, Op_ReactivateCompletionDebug, 0, &otherTryFinally, &ourNode); + } else { CodeGen::emitOp(comp, Op_ReactivateCompletion, 0, &otherTryFinally); + } comp->popNest(); } } @@ -1551,7 +1572,12 @@ comp->setEvalResultRegister(&evalResReg); // There is no need to initialize this as everything will be set to undefined anyway + } else { + if (comp->compileType() == Debug) { + OpValue ourNode = OpValue::immNode(this); + CodeGen::emitOp(comp, Op_EnterDebugContext, 0, &ourNode); } + } // Set unwind.. Addr unwind = CodeGen::emitOp(comp, Op_PushExceptionHandler, 0, OpValue::dummyAddr()); @@ -1560,13 +1586,16 @@ BlockNode::generateExecCode(comp); // Make sure we exit! - if (comp->codeType() != FunctionCode) - CodeGen::emitOp(comp, Op_ExitEval, 0, &evalResVal); - else + if (comp->codeType() != FunctionCode) { + CodeGen::emitOp(comp, Op_Return, 0, &evalResVal); + } else { + generateExitContextIfNeeded(comp); CodeGen::emitOp(comp, Op_Exit); + } // Unwind stuff.. CodeGen::patchJumpToNext(comp, unwind, 0); + generateExitContextIfNeeded(comp); CodeGen::emitOp(comp, Op_PropagateException); }