Bug 1060936 - Directly call debugger hooks. r=shu
authorTom Schuster <evilpies@gmail.com>
Fri, 03 Oct 2014 18:46:51 +0200
changeset 208826 2374287a24ab3d60373eea2d4349c5b8129be182
parent 208825 75c93e9a7c970d66c8c1af12d400fd45e1871e96
child 208827 85dc7c0f9f7105a2e6f5501da08568c72cb6663e
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersshu
bugs1060936
milestone35.0a1
Bug 1060936 - Directly call debugger hooks. r=shu
js/src/jit/IonFrames.cpp
js/src/jit/VMFunctions.cpp
js/src/vm/Debugger-inl.h
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
js/src/vm/OldDebugAPI.cpp
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -506,18 +506,17 @@ HandleExceptionBaseline(JSContext *cx, c
     if (cx->isPropagatingForcedReturn()) {
         cx->clearPropagatingForcedReturn();
         ForcedReturn(cx, frame, pc, rfe, calledDebugEpilogue);
         return;
     }
 
     if (cx->isExceptionPending() && cx->compartment()->debugMode()) {
         BaselineFrame *baselineFrame = frame.baselineFrame();
-        JSTrapStatus status = DebugExceptionUnwind(cx, baselineFrame, pc);
-        switch (status) {
+        switch (Debugger::onExceptionUnwind(cx, baselineFrame)) {
           case JSTRAP_ERROR:
             // Uncatchable exception.
             MOZ_ASSERT(!cx->isExceptionPending());
             break;
 
           case JSTRAP_CONTINUE:
           case JSTRAP_THROW:
             MOZ_ASSERT(cx->isExceptionPending());
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -17,16 +17,17 @@
 #include "vm/Debugger.h"
 #include "vm/Interpreter.h"
 #include "vm/TraceLogging.h"
 
 #include "jsinferinlines.h"
 
 #include "jit/BaselineFrame-inl.h"
 #include "jit/IonFrames-inl.h"
+#include "vm/Debugger-inl.h"
 #include "vm/Interpreter-inl.h"
 #include "vm/ObjectImpl-inl.h"
 #include "vm/StringObject-inl.h"
 
 using namespace js;
 using namespace js::jit;
 
 namespace js {
@@ -758,34 +759,33 @@ GetIndexFromString(JSString *str)
     return index;
 }
 
 bool
 DebugPrologue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool *mustReturn)
 {
     *mustReturn = false;
 
-    JSTrapStatus status = ScriptDebugPrologue(cx, frame, pc);
-    switch (status) {
+    switch (Debugger::onEnterFrame(cx, frame)) {
       case JSTRAP_CONTINUE:
         return true;
 
       case JSTRAP_RETURN:
         // The script is going to return immediately, so we have to call the
         // debug epilogue handler as well.
         MOZ_ASSERT(frame->hasReturnValue());
         *mustReturn = true;
         return jit::DebugEpilogue(cx, frame, pc, true);
 
       case JSTRAP_THROW:
       case JSTRAP_ERROR:
         return false;
 
       default:
-        MOZ_CRASH("Invalid trap status");
+        MOZ_CRASH("bad Debugger::onEnterFrame status");
     }
 }
 
 bool
 DebugEpilogueOnBaselineReturn(JSContext *cx, BaselineFrame *frame, jsbytecode *pc)
 {
     if (!DebugEpilogue(cx, frame, pc, true)) {
         // DebugEpilogue popped the frame by updating jitTop, so run the stop event
@@ -803,20 +803,20 @@ bool
 DebugEpilogue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool ok)
 {
     // Unwind scope chain to stack depth 0.
     ScopeIter si(frame, pc, cx);
     UnwindAllScopes(cx, si);
     jsbytecode *unwindPc = frame->script()->main();
     frame->setUnwoundScopeOverridePc(unwindPc);
 
-    // If ScriptDebugEpilogue returns |true| we have to return the frame's
+    // If Debugger::onLeaveFrame returns |true| we have to return the frame's
     // return value. If it returns |false|, the debugger threw an exception.
     // In both cases we have to pop debug scopes.
-    ok = ScriptDebugEpilogue(cx, frame, pc, ok);
+    ok = Debugger::onLeaveFrame(cx, frame, ok);
 
     if (frame->isNonEvalFunctionFrame()) {
         MOZ_ASSERT_IF(ok, frame->hasReturnValue());
         DebugScopes::onPopCall(frame, cx);
     } else if (frame->isStrictEvalFrame()) {
         MOZ_ASSERT_IF(frame->hasCallObj(), frame->scopeChain()->as<CallObject>().isForEval());
         DebugScopes::onPopStrictEvalScope(frame);
     }
--- a/js/src/vm/Debugger-inl.h
+++ b/js/src/vm/Debugger-inl.h
@@ -9,16 +9,17 @@
 
 #include "vm/Debugger.h"
 
 #include "vm/Stack-inl.h"
 
 inline bool
 js::Debugger::onLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok)
 {
+    MOZ_ASSERT_IF(frame.isInterpreterFrame(), frame.asInterpreterFrame() == cx->interpreterFrame());
     /* Traps must be cleared from eval frames, see slowPathOnLeaveFrame. */
     bool evalTraps = frame.isEvalFrame() &&
                      frame.script()->hasAnyBreakpointsOrStepMode();
     if (cx->compartment()->debugMode() || evalTraps)
         ok = slowPathOnLeaveFrame(cx, frame, ok);
     return ok;
 }
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -493,44 +493,67 @@ Debugger::hasAnyLiveHooks() const
             !frameObj->getReservedSlot(JSSLOT_DEBUGFRAME_ONPOP_HANDLER).isUndefined())
             return true;
     }
 
     return false;
 }
 
 JSTrapStatus
-Debugger::slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame, MutableHandleValue vp)
-{
-    /* Build the list of recipients. */
+Debugger::slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame)
+{
+    // Build the list of recipients.
     AutoValueVector triggered(cx);
     Handle<GlobalObject*> global = cx->global();
 
     if (GlobalObject::DebuggerVector *debuggers = global->getDebuggers()) {
         for (Debugger **p = debuggers->begin(); p != debuggers->end(); p++) {
             Debugger *dbg = *p;
             if (dbg->observesFrame(frame) && dbg->observesEnterFrame() &&
                 !triggered.append(ObjectValue(*dbg->toJSObject())))
             {
+                cx->clearPendingException();
                 return JSTRAP_ERROR;
             }
         }
     }
 
-    /* Deliver the event, checking again as in dispatchHook. */
+    JSTrapStatus status = JSTRAP_CONTINUE;
+    RootedValue rval(cx);
+    // Deliver the event, checking again as in dispatchHook.
     for (Value *p = triggered.begin(); p != triggered.end(); p++) {
         Debugger *dbg = Debugger::fromJSObject(&p->toObject());
         if (dbg->debuggees.has(global) && dbg->observesEnterFrame()) {
-            JSTrapStatus status = dbg->fireEnterFrame(cx, frame, vp);
+            status = dbg->fireEnterFrame(cx, frame, &rval);
             if (status != JSTRAP_CONTINUE)
-                return status;
+                break;
         }
     }
 
-    return JSTRAP_CONTINUE;
+    switch (status) {
+      case JSTRAP_CONTINUE:
+        break;
+
+      case JSTRAP_THROW:
+        cx->setPendingException(rval);
+        break;
+
+      case JSTRAP_ERROR:
+        cx->clearPendingException();
+        break;
+
+      case JSTRAP_RETURN:
+        frame.setReturnValue(rval);
+        break;
+
+      default:
+        MOZ_CRASH("bad Debugger::onEnterFrame JSTrapStatus value");
+    }
+
+    return status;
 }
 
 static void
 DebuggerFrame_maybeDecrementFrameScriptStepModeCount(FreeOp *fop, AbstractFramePtr frame,
                                                      NativeObject *frameobj);
 
 static void
 DebuggerFrame_freeScriptFrameIterData(FreeOp *fop, JSObject *obj);
@@ -639,16 +662,46 @@ Debugger::slowPathOnLeaveFrame(JSContext
         MOZ_ASSERT(!cx->isExceptionPending());
         return false;
 
       default:
         MOZ_CRASH("bad final trap status");
     }
 }
 
+JSTrapStatus
+Debugger::slowPathOnExceptionUnwind(JSContext *cx, AbstractFramePtr frame)
+{
+    RootedValue rval(cx);
+    JSTrapStatus status = dispatchHook(cx, &rval, OnExceptionUnwind);
+
+    switch (status) {
+      case JSTRAP_CONTINUE:
+        break;
+
+      case JSTRAP_THROW:
+        cx->setPendingException(rval);
+        break;
+
+      case JSTRAP_ERROR:
+        cx->clearPendingException();
+        break;
+
+      case JSTRAP_RETURN:
+        cx->clearPendingException();
+        frame.setReturnValue(rval);
+        break;
+
+      default:
+        MOZ_CRASH("Invalid trap status");
+    }
+
+    return status;
+}
+
 bool
 Debugger::wrapEnvironment(JSContext *cx, Handle<Env*> env, MutableHandleValue rval)
 {
     if (!env) {
         rval.setNull();
         return true;
     }
 
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -364,19 +364,19 @@ class Debugger : private mozilla::Linked
     static bool makeGlobalObjectReference(JSContext *cx, unsigned argc, Value *vp);
     static bool construct(JSContext *cx, unsigned argc, Value *vp);
     static const JSPropertySpec properties[];
     static const JSFunctionSpec methods[];
 
     JSObject *getHook(Hook hook) const;
     bool hasAnyLiveHooks() const;
 
-    static JSTrapStatus slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame,
-                                             MutableHandleValue vp);
+    static JSTrapStatus slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame);
     static bool slowPathOnLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok);
+    static JSTrapStatus slowPathOnExceptionUnwind(JSContext *cx, AbstractFramePtr frame);
     static void slowPathOnNewScript(JSContext *cx, HandleScript script,
                                     GlobalObject *compileAndGoGlobal);
     static void slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
     static bool slowPathOnLogAllocationSite(JSContext *cx, HandleSavedFrame frame,
                                             GlobalObject::DebuggerVector &dbgs);
     static JSTrapStatus dispatchHook(JSContext *cx, MutableHandleValue vp, Hook which);
 
     JSTrapStatus fireDebuggerStatement(JSContext *cx, MutableHandleValue vp);
@@ -448,23 +448,71 @@ class Debugger : private mozilla::Linked
      */
     static void markCrossCompartmentDebuggerObjectReferents(JSTracer *tracer);
     static bool markAllIteratively(GCMarker *trc);
     static void markAll(JSTracer *trc);
     static void sweepAll(FreeOp *fop);
     static void detachAllDebuggersFromGlobal(FreeOp *fop, GlobalObject *global);
     static void findCompartmentEdges(JS::Zone *v, gc::ComponentFinder<JS::Zone> &finder);
 
-    static inline JSTrapStatus onEnterFrame(JSContext *cx, AbstractFramePtr frame,
-                                            MutableHandleValue vp);
+    /*
+     * Announce to the debugger that the thread has entered a new JavaScript frame,
+     * |frame|. Call whatever hooks have been registered to observe new frames, and
+     * return a JSTrapStatus code indication how execution should proceed:
+     *
+     * - JSTRAP_CONTINUE: Continue execution normally.
+     *
+     * - JSTRAP_THROW: Throw an exception. onEnterFrame has set |cx|'s
+     *   pending exception to the value to be thrown.
+     *
+     * - JSTRAP_ERROR: Terminate execution (as is done when a script is terminated
+     *   for running too long). onEnterFrame has cleared |cx|'s pending
+     *   exception.
+     *
+     * - JSTRAP_RETURN: Return from the new frame immediately. onEnterFrame
+     *   has set |frame|'s return value appropriately.
+     */
+    static inline JSTrapStatus onEnterFrame(JSContext *cx, AbstractFramePtr frame);
+
+    /*
+     * Announce to the debugger that the thread has exited a JavaScript frame, |frame|.
+     * If |ok| is true, the frame is returning normally; if |ok| is false, the frame
+     * is throwing an exception or terminating.
+     *
+     * Change cx's current exception and |frame|'s return value to reflect the changes
+     * in behavior the hooks request, if any. Return the new error/success value.
+     *
+     * This function may be called twice for the same outgoing frame; only the
+     * first call has any effect. (Permitting double calls simplifies some
+     * cases where an onPop handler's resumption value changes a return to a
+     * throw, or vice versa: we can redirect to a complete copy of the
+     * alternative path, containing its own call to onLeaveFrame.)
+     */
     static inline bool onLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok);
+
     static inline JSTrapStatus onDebuggerStatement(JSContext *cx, MutableHandleValue vp);
-    static inline JSTrapStatus onExceptionUnwind(JSContext *cx, MutableHandleValue vp);
-    static inline void onNewScript(JSContext *cx, HandleScript script,
-                                   GlobalObject *compileAndGoGlobal);
+
+    /*
+     * Announce to the debugger that an exception has been thrown and propagated
+     * to |frame|. Call whatever hooks have been registered to observe this and
+     * return a JSTrapStatus code indication how execution should proceed:
+     *
+     * - JSTRAP_CONTINUE: Continue throwing the current exception.
+     *
+     * - JSTRAP_THROW: Throw another value. onExceptionUnwind has set |cx|'s
+     *   pending exception to the new value.
+     *
+     * - JSTRAP_ERROR: Terminate execution. onExceptionUnwind has cleared |cx|'s
+     *   pending exception.
+     *
+     * - JSTRAP_RETURN: Return from |frame|. onExceptionUnwind has cleared
+     *   |cx|'s pending exception and set |frame|'s return value.
+     */
+    static inline JSTrapStatus onExceptionUnwind(JSContext *cx, AbstractFramePtr frame);
+    static inline void onNewScript(JSContext *cx, HandleScript script, GlobalObject *compileAndGoGlobal);
     static inline void onNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
     static inline bool onLogAllocationSite(JSContext *cx, HandleSavedFrame frame);
     static JSTrapStatus onTrap(JSContext *cx, MutableHandleValue vp);
     static JSTrapStatus onSingleStep(JSContext *cx, MutableHandleValue vp);
     static bool handleBaselineOsr(JSContext *cx, InterpreterFrame *from, jit::BaselineFrame *to);
     static bool handleIonBailout(JSContext *cx, jit::RematerializedFrame *from, jit::BaselineFrame *to);
     static void propagateForcedReturn(JSContext *cx, AbstractFramePtr frame, HandleValue rval);
 
@@ -729,37 +777,37 @@ Debugger::observesNewGlobalObject() cons
 
 bool
 Debugger::observesGlobal(GlobalObject *global) const
 {
     return debuggees.has(global);
 }
 
 JSTrapStatus
-Debugger::onEnterFrame(JSContext *cx, AbstractFramePtr frame, MutableHandleValue vp)
+Debugger::onEnterFrame(JSContext *cx, AbstractFramePtr frame)
 {
     if (!cx->compartment()->debugMode())
         return JSTRAP_CONTINUE;
-    return slowPathOnEnterFrame(cx, frame, vp);
+    return slowPathOnEnterFrame(cx, frame);
 }
 
 JSTrapStatus
 Debugger::onDebuggerStatement(JSContext *cx, MutableHandleValue vp)
 {
     return cx->compartment()->debugMode()
            ? dispatchHook(cx, vp, OnDebuggerStatement)
            : JSTRAP_CONTINUE;
 }
 
 JSTrapStatus
-Debugger::onExceptionUnwind(JSContext *cx, MutableHandleValue vp)
+Debugger::onExceptionUnwind(JSContext *cx, AbstractFramePtr frame)
 {
-    return cx->compartment()->debugMode()
-           ? dispatchHook(cx, vp, OnExceptionUnwind)
-           : JSTRAP_CONTINUE;
+    if (!cx->compartment()->debugMode())
+        return JSTRAP_CONTINUE;
+    return slowPathOnExceptionUnwind(cx, frame);
 }
 
 void
 Debugger::onNewScript(JSContext *cx, HandleScript script, GlobalObject *compileAndGoGlobal)
 {
     MOZ_ASSERT_IF(script->compileAndGo(), compileAndGoGlobal);
     MOZ_ASSERT_IF(script->compileAndGo(), compileAndGoGlobal == &script->uninlinedGlobal());
     // We early return in slowPathOnNewScript for self-hosted scripts, so we can
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -42,16 +42,17 @@
 
 #include "jsatominlines.h"
 #include "jsboolinlines.h"
 #include "jsfuninlines.h"
 #include "jsinferinlines.h"
 #include "jsscriptinlines.h"
 
 #include "jit/IonFrames-inl.h"
+#include "vm/Debugger-inl.h"
 #include "vm/ObjectImpl-inl.h"
 #include "vm/Probes-inl.h"
 #include "vm/ScopeObject-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
@@ -1019,33 +1020,31 @@ HandleError(JSContext *cx, InterpreterRe
     MOZ_ASSERT(regs.fp()->script()->containsPC(regs.pc));
 
     ScopeIter si(regs.fp(), regs.pc, cx);
     bool ok = false;
 
   again:
     if (cx->isExceptionPending()) {
         /* Call debugger throw hooks. */
-        if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
-            JSTrapStatus status = DebugExceptionUnwind(cx, regs.fp(), regs.pc);
-            switch (status) {
-              case JSTRAP_ERROR:
-                goto again;
-
-              case JSTRAP_CONTINUE:
-              case JSTRAP_THROW:
-                break;
-
-              case JSTRAP_RETURN:
-                ForcedReturn(cx, si, regs);
-                return SuccessfulReturnContinuation;
-
-              default:
-                MOZ_CRASH("Invalid trap status");
-            }
+        JSTrapStatus status = Debugger::onExceptionUnwind(cx, regs.fp());
+        switch (status) {
+          case JSTRAP_ERROR:
+            goto again;
+
+          case JSTRAP_CONTINUE:
+          case JSTRAP_THROW:
+            break;
+
+          case JSTRAP_RETURN:
+            ForcedReturn(cx, si, regs);
+            return SuccessfulReturnContinuation;
+
+          default:
+            MOZ_CRASH("Bad Debugger::onExceptionUnwind status");
         }
 
         RootedValue exception(cx);
         for (TryNoteIter tni(cx, regs); !tni.done(); ++tni) {
             JSTryNote *tn = *tni;
 
             // Unwind the scope to the beginning of the JSOP_TRY.
             UnwindScope(cx, si, UnwindScopeToTryPc(regs.fp()->script(), tn));
@@ -1500,30 +1499,28 @@ Interpret(JSContext *cx, RunState &state
             goto error;
     } else {
         if (!probes::EnterScript(cx, script, script->functionNonDelazifying(),
                                  activation.entryFrame()))
         {
             goto error;
         }
     }
-    if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
-        JSTrapStatus status = ScriptDebugPrologue(cx, activation.entryFrame(), REGS.pc);
-        switch (status) {
-          case JSTRAP_CONTINUE:
-            break;
-          case JSTRAP_RETURN:
-            ForcedReturn(cx, REGS);
-            goto successful_return_continuation;
-          case JSTRAP_THROW:
-          case JSTRAP_ERROR:
-            goto error;
-          default:
-            MOZ_CRASH("bad ScriptDebugPrologue status");
-        }
+
+    switch (Debugger::onEnterFrame(cx, activation.entryFrame())) {
+      case JSTRAP_CONTINUE:
+        break;
+      case JSTRAP_RETURN:
+        ForcedReturn(cx, REGS);
+        goto successful_return_continuation;
+      case JSTRAP_THROW:
+      case JSTRAP_ERROR:
+        goto error;
+      default:
+        MOZ_CRASH("bad Debugger::onEnterFrame status");
     }
 
     if (cx->runtime()->profilingScripts)
         activation.enableInterruptsUnconditionally();
 
     // Enter the interpreter loop starting at the current pc.
     ADVANCE_AND_DISPATCH(0);
 
@@ -1782,18 +1779,17 @@ CASE(JSOP_RETRVAL)
   inline_return:
     {
         // Stop the engine. (No details about which engine exactly, could be
         // interpreter, Baseline or IonMonkey.)
         TraceLogStopEvent(logger);
         // Stop the script. (Again no details about which script exactly.)
         TraceLogStopEvent(logger);
 
-        if (MOZ_UNLIKELY(cx->compartment()->debugMode()))
-            interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), REGS.pc, interpReturnOK);
+        interpReturnOK = Debugger::onLeaveFrame(cx, REGS.fp(), interpReturnOK);
 
         if (!REGS.fp()->isYielding())
             REGS.fp()->epilogue(cx);
         else
             probes::ExitScript(cx, script, script->functionNonDelazifying(),
                                REGS.fp()->hasPushedSPSFrame());
 
   jit_return_pop_frame:
@@ -2604,29 +2600,28 @@ CASE(JSOP_FUNCALL)
     SET_SCRIPT(REGS.fp()->script());
 
     uint32_t scriptLogId = TraceLogCreateTextId(logger, script);
     TraceLogStartEvent(logger, scriptLogId);
     TraceLogStartEvent(logger, TraceLogger::Interpreter);
 
     if (!REGS.fp()->prologue(cx))
         goto error;
-    if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
-        switch (ScriptDebugPrologue(cx, REGS.fp(), REGS.pc)) {
-          case JSTRAP_CONTINUE:
-            break;
-          case JSTRAP_RETURN:
-            ForcedReturn(cx, REGS);
-            goto successful_return_continuation;
-          case JSTRAP_THROW:
-          case JSTRAP_ERROR:
-            goto error;
-          default:
-            MOZ_CRASH("bad ScriptDebugPrologue status");
-        }
+
+    switch (Debugger::onEnterFrame(cx, REGS.fp())) {
+      case JSTRAP_CONTINUE:
+        break;
+      case JSTRAP_RETURN:
+        ForcedReturn(cx, REGS);
+        goto successful_return_continuation;
+      case JSTRAP_THROW:
+      case JSTRAP_ERROR:
+        goto error;
+      default:
+        MOZ_CRASH("bad Debugger::onEnterFrame status");
     }
 
     /* Load first op and dispatch it (safe since JSOP_RETRVAL). */
     ADVANCE_AND_DISPATCH(0);
 }
 
 CASE(JSOP_SETCALL)
 {
@@ -3462,18 +3457,18 @@ DEFAULT()
         PUSH_COPY(exception);
         cx->clearPendingException();
         ADVANCE_AND_DISPATCH(0);
     }
 
     MOZ_CRASH("Invalid HandleError continuation");
 
   exit:
-    if (MOZ_UNLIKELY(cx->compartment()->debugMode()))
-        interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), REGS.pc, interpReturnOK);
+    interpReturnOK = Debugger::onLeaveFrame(cx, REGS.fp(), interpReturnOK);
+
     if (!REGS.fp()->isYielding())
         REGS.fp()->epilogue(cx);
     else
         probes::ExitScript(cx, script, script->functionNonDelazifying(),
                            REGS.fp()->hasPushedSPSFrame());
 
     gc::MaybeVerifyBarriers(cx, true);
 
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -16,73 +16,16 @@
 
 #include "vm/Stack.h"
 
 namespace js {
 
 class ScopeIter;
 
 /*
- * Announce to the debugger that the thread has entered a new JavaScript frame,
- * |frame|. Call whatever hooks have been registered to observe new frames, and
- * return a JSTrapStatus code indication how execution should proceed:
- *
- * - JSTRAP_CONTINUE: Continue execution normally.
- *
- * - JSTRAP_THROW: Throw an exception. ScriptDebugPrologue has set |cx|'s
- *   pending exception to the value to be thrown.
- *
- * - JSTRAP_ERROR: Terminate execution (as is done when a script is terminated
- *   for running too long). ScriptDebugPrologue has cleared |cx|'s pending
- *   exception.
- *
- * - JSTRAP_RETURN: Return from the new frame immediately. ScriptDebugPrologue
- *   has set |frame|'s return value appropriately.
- */
-extern JSTrapStatus
-ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc);
-
-/*
- * Announce to the debugger that the thread has exited a JavaScript frame, |frame|.
- * If |ok| is true, the frame is returning normally; if |ok| is false, the frame
- * is throwing an exception or terminating.
- *
- * Call whatever hooks have been registered to observe frame exits. Change cx's
- * current exception and |frame|'s return value to reflect the changes in behavior
- * the hooks request, if any. Return the new error/success value.
- *
- * This function may be called twice for the same outgoing frame; only the
- * first call has any effect. (Permitting double calls simplifies some
- * cases where an onPop handler's resumption value changes a return to a
- * throw, or vice versa: we can redirect to a complete copy of the
- * alternative path, containing its own call to ScriptDebugEpilogue.)
- */
-extern bool
-ScriptDebugEpilogue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc, bool ok);
-
-/*
- * Announce to the debugger that an exception has been thrown and propagated
- * to |frame|. Call whatever hooks have been registered to observe this and
- * return a JSTrapStatus code indication how execution should proceed:
- *
- * - JSTRAP_CONTINUE: Continue throwing the current exception.
- *
- * - JSTRAP_THROW: Throw another value. DebugExceptionUnwind has set |cx|'s
- *   pending exception to the new value.
- *
- * - JSTRAP_ERROR: Terminate execution. DebugExceptionUnwind has cleared |cx|'s
- *   pending exception.
- *
- * - JSTRAP_RETURN: Return from |frame|. DebugExceptionUnwind has cleared
- *   |cx|'s pending exception and set |frame|'s return value.
- */
-extern JSTrapStatus
-DebugExceptionUnwind(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc);
-
-/*
  * For a given |call|, convert null/undefined |this| into the global object for
  * the callee and replace other primitives with boxed versions. This assumes
  * that call.callee() is not strict mode code. This is the special/slow case of
  * ComputeThis.
  */
 extern bool
 BoxNonStrictThis(JSContext *cx, const CallReceiver &call);
 
--- a/js/src/vm/OldDebugAPI.cpp
+++ b/js/src/vm/OldDebugAPI.cpp
@@ -34,86 +34,16 @@
 #include "vm/Interpreter-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 using namespace js::gc;
 
 using mozilla::PodZero;
 
-JSTrapStatus
-js::ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
-{
-    MOZ_ASSERT_IF(frame.isInterpreterFrame(), frame.asInterpreterFrame() == cx->interpreterFrame());
-
-    RootedValue rval(cx);
-    JSTrapStatus status = Debugger::onEnterFrame(cx, frame, &rval);
-    switch (status) {
-      case JSTRAP_CONTINUE:
-        break;
-      case JSTRAP_THROW:
-        cx->setPendingException(rval);
-        break;
-      case JSTRAP_ERROR:
-        cx->clearPendingException();
-        break;
-      case JSTRAP_RETURN:
-        frame.setReturnValue(rval);
-        break;
-      default:
-        MOZ_CRASH("bad Debugger::onEnterFrame JSTrapStatus value");
-    }
-    return status;
-}
-
-bool
-js::ScriptDebugEpilogue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc, bool okArg)
-{
-    MOZ_ASSERT_IF(frame.isInterpreterFrame(), frame.asInterpreterFrame() == cx->interpreterFrame());
-
-    bool ok = okArg;
-
-    return Debugger::onLeaveFrame(cx, frame, ok);
-}
-
-JSTrapStatus
-js::DebugExceptionUnwind(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
-{
-    MOZ_ASSERT(cx->compartment()->debugMode());
-
-    /* Call debugger throw hook if set. */
-    RootedValue rval(cx);
-    JSTrapStatus status = Debugger::onExceptionUnwind(cx, &rval);
-
-    switch (status) {
-      case JSTRAP_ERROR:
-        cx->clearPendingException();
-        break;
-
-      case JSTRAP_RETURN:
-        cx->clearPendingException();
-        frame.setReturnValue(rval);
-        break;
-
-      case JSTRAP_THROW:
-        cx->setPendingException(rval);
-        break;
-
-      case JSTRAP_CONTINUE:
-        break;
-
-      default:
-        MOZ_CRASH("Invalid trap status");
-    }
-
-    return status;
-}
-
-/************************************************************************/
-
 JS_PUBLIC_API(JSScript *)
 JS_GetFunctionScript(JSContext *cx, HandleFunction fun)
 {
     if (fun->isNative())
         return nullptr;
     if (fun->isInterpretedLazy()) {
         AutoCompartment funCompartment(cx, fun);
         JSScript *script = fun->getOrCreateScript(cx);