Back out 7196b000f9df (bug 673125 part 2).
authorJason Orendorff <jorendorff@mozilla.com>
Tue, 23 Aug 2011 15:34:59 -0500
changeset 77082 3cbe0a312779fa89bd7d5adbda36494437563c68
parent 77081 46dcf0b550eed68464e3a9a9ee942caa1e58a007
child 77083 5ed21fb6d81a9f530a8ce4b638db67c791f8f262
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs673125
milestone9.0a1
backs out7196b000f9dfc0ef65d2e1b82d96f8cc3695668e
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out 7196b000f9df (bug 673125 part 2).
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsinterp.h
js/src/jsscript.cpp
js/src/jsscript.h
js/src/methodjit/Compiler.cpp
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -76,16 +76,19 @@
 #include "jsinterpinlines.h"
 #include "jsscopeinlines.h"
 #include "jsscriptinlines.h"
 
 #include "vm/Stack-inl.h"
 
 #include "jsautooplen.h"
 
+#include "methodjit/MethodJIT.h"
+#include "methodjit/Retcon.h"
+
 #ifdef __APPLE__
 #include "sharkctl.h"
 #endif
 
 using namespace js;
 using namespace js::gc;
 
 JS_PUBLIC_API(JSBool)
@@ -146,16 +149,44 @@ ScriptDebugEpilogue(JSContext *cx, Stack
 } /* namespace js */
 
 JS_FRIEND_API(JSBool)
 JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug)
 {
     return comp->setDebugModeFromC(cx, !!debug);
 }
 
+JS_FRIEND_API(JSBool)
+js_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep)
+{
+    assertSameCompartment(cx, script);
+
+#ifdef JS_METHODJIT
+    if (!script->singleStepMode == !singleStep)
+        return JS_TRUE;
+#endif
+
+    JS_ASSERT_IF(singleStep, cx->compartment->debugMode());
+
+#ifdef JS_METHODJIT
+    /* request the next recompile to inject single step interrupts */
+    script->singleStepMode = !!singleStep;
+
+    js::mjit::JITScript *jit = script->jitNormal ? script->jitNormal : script->jitCtor;
+    if (jit && script->singleStepMode != jit->singleStepMode) {
+        js::mjit::Recompiler recompiler(cx, script);
+        if (!recompiler.recompile()) {
+            script->singleStepMode = !singleStep;
+            return JS_FALSE;
+        }
+    }
+#endif
+    return JS_TRUE;
+}
+
 static JSBool
 CheckDebugMode(JSContext *cx)
 {
     JSBool debugMode = JS_GetDebugMode(cx);
     /*
      * :TODO:
      * This probably should be an assertion, since it's indicative of a severe
      * API misuse.
@@ -169,17 +200,17 @@ CheckDebugMode(JSContext *cx)
 
 JS_PUBLIC_API(JSBool)
 JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep)
 {
     assertSameCompartment(cx, script);
     if (!CheckDebugMode(cx))
         return JS_FALSE;
 
-    return script->setStepModeFlag(cx, singleStep);
+    return js_SetSingleStepMode(cx, script, singleStep);
 }
 
 jsbytecode *
 js_UntrapScriptCode(JSContext *cx, JSScript *script)
 {
     jsbytecode *code = script->code;
     BreakpointSiteMap &sites = script->compartment->breakpointSites;
     for (BreakpointSiteMap::Range r = sites.all(); !r.empty(); r.popFront()) {
--- a/js/src/jsdbgapi.h
+++ b/js/src/jsdbgapi.h
@@ -126,16 +126,20 @@ JS_FRIEND_API(JSBool)
 JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug);
 
 /*
  * Turn on/off debugging mode for a context's compartment.
  */
 JS_FRIEND_API(JSBool)
 JS_SetDebugMode(JSContext *cx, JSBool debug);
 
+/* Turn on single step mode. Requires debug mode. */
+extern JS_FRIEND_API(JSBool)
+js_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep);
+
 /* Turn on single step mode. */
 extern JS_PUBLIC_API(JSBool)
 JS_SetSingleStepMode(JSContext *cx, JSScript *script, JSBool singleStep);
 
 /*
  * Unexported library-private helper used to unpatch all traps in a script.
  * Returns script->code if script has no traps, else a JS_malloc'ed copy of
  * script->code which the caller must JS_free, or null on JS_malloc OOM.
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -340,22 +340,21 @@ class InterpreterFrames {
     ~InterpreterFrames();
 
     /* If this js::Interpret frame is running |script|, enable interrupts. */
     void enableInterruptsIfRunning(JSScript *script) {
         if (script == regs->fp()->script())
             enabler.enableInterrupts();
     }
 
-    InterpreterFrames *older;
-
   private:
     JSContext *context;
     FrameRegs *regs;
     const InterruptEnablerBase &enabler;
+    InterpreterFrames *older;
 };
 
 } /* namespace js */
 
 /*
  * JS_LONE_INTERPRET indicates that the compiler should see just the code for
  * the js_Interpret function when compiling jsinterp.cpp. The rest of the code
  * from the file should be visible only when compiling jsinvoke.cpp. It allows
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -64,17 +64,16 @@
 #include "jsparse.h"
 #include "jsscope.h"
 #include "jsscript.h"
 #include "jstracer.h"
 #if JS_HAS_XDR
 #include "jsxdrapi.h"
 #endif
 #include "methodjit/MethodJIT.h"
-#include "methodjit/Retcon.h"
 #include "vm/Debugger.h"
 
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
@@ -1825,63 +1824,8 @@ js_CloneScript(JSContext *cx, JSScript *
     return script;
 }
 
 void
 JSScript::copyClosedSlotsTo(JSScript *other)
 {
     memcpy(other->closedSlots, closedSlots, nClosedArgs + nClosedVars);
 }
-
-bool
-JSScript::recompileForStepMode(JSContext *cx)
-{
-#ifdef JS_METHODJIT
-    js::mjit::JITScript *jit = jitNormal ? jitNormal : jitCtor;
-    if (jit && stepModeEnabled() != jit->singleStepMode) {
-        js::mjit::Recompiler recompiler(cx, this);
-        return recompiler.recompile();
-    }
-#endif
-    return true;
-}
-
-bool
-JSScript::tryNewStepMode(JSContext *cx, uint32 newValue)
-{
-    uint32 prior = stepMode;
-    stepMode = newValue;
-
-    if (!prior != !newValue) {
-        /* Step mode has been enabled or disabled. Alert the methodjit. */
-        if (!recompileForStepMode(cx)) {
-            stepMode = prior;
-            return false;
-        }
-
-        if (newValue) {
-            /* Step mode has been enabled. Alert the interpreter. */
-            InterpreterFrames *frames;
-            for (frames = JS_THREAD_DATA(cx)->interpreterFrames; frames; frames = frames->older)
-                frames->enableInterruptsIfRunning(this);
-        }
-    }
-    return true;
-}
-
-bool
-JSScript::setStepModeFlag(JSContext *cx, bool step)
-{
-    return tryNewStepMode(cx, (stepMode & stepCountMask) | (step ? stepFlagMask : 0));
-}
-
-bool
-JSScript::changeStepModeCount(JSContext *cx, int delta)
-{
-    assertSameCompartment(cx, this);
-    JS_ASSERT_IF(delta > 0, cx->compartment->debugMode());
-
-    uint32 count = stepMode & stepCountMask;
-    JS_ASSERT(((count + delta) & stepCountMask) == count + delta);
-    return tryNewStepMode(cx, 
-                          (stepMode & stepFlagMask) |
-                          ((count + delta) & stepCountMask));
-}
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -458,25 +458,16 @@ struct JSScript {
 
   public:
     uint16          nfixed;     /* number of slots besides stack operands in
                                    slot array */
   private:
     size_t          callCount_; /* Number of times the script has been called. */
 
     /*
-     * When non-zero, compile script in single-step mode. The top bit is set and
-     * cleared by setStepMode, as used by JSD. The lower bits are a count,
-     * adjusted by changeStepModeCount, used by the Debugger object. Only
-     * when the bit is clear and the count is zero may we compile the script
-     * without single-step support.
-     */
-    uint32          stepMode;
-
-    /*
      * Offsets to various array structures from the end of this script, or
      * JSScript::INVALID_OFFSET if the array has length 0.
      */
   public:
     uint8           objectsOffset;  /* offset to the array of nested function,
                                        block, scope, xml and one-time regexps
                                        objects */
     uint8           upvarsOffset;   /* offset of the array of display ("up")
@@ -496,16 +487,17 @@ struct JSScript {
     bool            usesEval:1;       /* script uses eval() */
     bool            usesArguments:1;  /* script uses arguments */
     bool            warnedAboutTwoArgumentEval:1; /* have warned about use of
                                                      obsolete eval(s, o) in
                                                      this script */
     bool            hasSingletons:1;  /* script has singleton objects */
 #ifdef JS_METHODJIT
     bool            debugMode:1;      /* script was compiled in debug mode */
+    bool            singleStepMode:1; /* compile script in single-step mode */
 #endif
 
     jsbytecode      *main;      /* main entry point, after predef'ing prolog */
     JSAtomMap       atomMap;    /* maps immediate index to literal struct */
     JSCompartment   *compartment; /* compartment the script was compiled for */
     const char      *filename;  /* source filename or null */
     uint32          lineno;     /* base line number of script */
     uint16          nslots;     /* vars plus maximum stack depth */
@@ -682,52 +674,16 @@ struct JSScript {
     }
 
     uint32 getClosedVar(uint32 index) {
         JS_ASSERT(index < nClosedVars);
         return closedSlots[nClosedArgs + index];
     }
 
     void copyClosedSlotsTo(JSScript *other);
-
-  private:
-    static const uint32 stepFlagMask = 0x80000000U;
-    static const uint32 stepCountMask = 0x7fffffffU;
-
-    /*
-     * Attempt to recompile with or without single-stepping support, as directed
-     * by stepModeEnabled().
-     */
-    bool recompileForStepMode(JSContext *cx);
-
-    /* Attempt to change this->stepMode to |newValue|. */
-    bool tryNewStepMode(JSContext *cx, uint32 newValue);
-
-  public:
-    /*
-     * Set or clear the single-step flag. If the flag is set or the count
-     * (adjusted by changeStepModeCount) is non-zero, then the script is in
-     * single-step mode. (JSD uses an on/off-style interface; Debugger uses a
-     * count-style interface.)
-     */
-    bool setStepModeFlag(JSContext *cx, bool step);
-    
-    /*
-     * Increment or decrement the single-step count. If the count is non-zero or
-     * the flag (set by setStepModeFlag) is set, then the script is in
-     * single-step mode. (JSD uses an on/off-style interface; Debugger uses a
-     * count-style interface.)
-     */
-    bool changeStepModeCount(JSContext *cx, int delta);
-
-    bool stepModeEnabled() { return !!stepMode; }
-
-#ifdef DEBUG
-    uint32 stepModeCount() { return stepMode & stepCountMask; }
-#endif
 };
 
 #define SHARP_NSLOTS            2       /* [#array, #depth] slots if the script
                                            uses sharp variables */
 
 static JS_INLINE uintN
 StackDepth(JSScript *script)
 {
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -469,17 +469,17 @@ mjit::Compiler::finishThisUp(JITScript *
         return Compile_Error;
     }
 
     JITScript *jit = new(cursor) JITScript;
     cursor += sizeof(JITScript);
 
     jit->code = JSC::MacroAssemblerCodeRef(result, execPool, masm.size() + stubcc.size());
     jit->invokeEntry = result;
-    jit->singleStepMode = script->stepModeEnabled();
+    jit->singleStepMode = script->singleStepMode;
     if (fun) {
         jit->arityCheckEntry = stubCode.locationOf(arityLabel).executableAddress();
         jit->fastEntry = fullCode.locationOf(invokeLabel).executableAddress();
     }
 
     /* 
      * WARNING: mics(), callICs() et al depend on the ordering of these
      * variable-length sections.  See JITScript's declaration for details.
@@ -898,17 +898,17 @@ mjit::Compiler::generateMethod()
         JSOp op = JSOp(*PC);
         int trap = stubs::JSTRAP_NONE;
         if (op == JSOP_TRAP) {
             if (!trapper.untrap(PC))
                 return Compile_Error;
             op = JSOp(*PC);
             trap |= stubs::JSTRAP_TRAP;
         }
-        if (script->stepModeEnabled() && scanner.firstOpInLine(PC - script->code))
+        if (script->singleStepMode && scanner.firstOpInLine(PC - script->code))
             trap |= stubs::JSTRAP_SINGLESTEP;
 
         if (cx->hasRunOption(JSOPTION_PCCOUNT) && script->pcCounters) {
             RegisterID r1 = frame.allocReg();
             RegisterID r2 = frame.allocReg();
 
             masm.move(ImmPtr(&script->pcCounters.get(JSRUNMODE_METHODJIT, PC - script->code)), r1);
             Address pcCounter(r1);