[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/kjs
From:       Maks Orlovich <maksim () kde ! org>
Date:       2010-05-01 17:37:56
Message-ID: 20100501173756.1A567AC8AA () svn ! kde ! org
[Download RAW message or body]

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 <stdio.h>
 
@@ -175,6 +176,33 @@
     return ret;
 }
 
+enum Dir { Enter, Exit };
+
+NEVER_INLINE void changeDebugContext(Dir d, ExecState* exec, Node* n) {
+    FunctionBodyNode* body = static_cast<FunctionBodyNode*>(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<ActivationImp*>(scopeObj);
+            args = act->passedInArguments();
+            fn   = static_cast<FunctionImp*>(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);
 }
 
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic