Bug 830369 - Refactor ScriptDebugPrologue and ScriptDebugEpilogue to use AbstractFramePtr. r=djvj
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 15 Jan 2013 09:29:23 +0100
changeset 128746 65747e07d9dfb7648e17d83652bec7df93295a7b
parent 128745 5d19aad2dab3021ce12a03f14c227d6e35b3c6f4
child 128747 fd642fb004e66423a2a36756012bc4dfc824f9b2
child 138131 8bda06f509b6e4b1fd78da8111c9d20aa348daf8
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs830369
milestone21.0a1
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
Bug 830369 - Refactor ScriptDebugPrologue and ScriptDebugEpilogue to use AbstractFramePtr. r=djvj
js/src/jsdbgapi.cpp
js/src/jsinterp.h
js/src/vm/Stack-inl.h
js/src/vm/Stack.h
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -68,61 +68,63 @@ JS_SetDebugMode(JSContext *cx, JSBool de
 
 JS_PUBLIC_API(void)
 JS_SetRuntimeDebugMode(JSRuntime *rt, JSBool debug)
 {
     rt->debugMode = !!debug;
 }
 
 JSTrapStatus
-js::ScriptDebugPrologue(JSContext *cx, StackFrame *fp)
+js::ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame)
 {
-    JS_ASSERT(fp == cx->fp());
+    JS_ASSERT_IF(frame.isStackFrame(), frame.asStackFrame() == cx->fp());
 
-    if (fp->isFramePushedByExecute()) {
+    if (frame.isFramePushedByExecute()) {
         if (JSInterpreterHook hook = cx->runtime->debugHooks.executeHook)
-            fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->runtime->debugHooks.executeHookData));
+            frame.setHookData(hook(cx, Jsvalify(frame.asStackFrame()), true, 0,
+                                   cx->runtime->debugHooks.executeHookData));
     } else {
         if (JSInterpreterHook hook = cx->runtime->debugHooks.callHook)
-            fp->setHookData(hook(cx, Jsvalify(fp), true, 0, cx->runtime->debugHooks.callHookData));
+            frame.setHookData(hook(cx, Jsvalify(frame.asStackFrame()), true, 0,
+                                   cx->runtime->debugHooks.callHookData));
     }
 
     Value rval;
     JSTrapStatus status = Debugger::onEnterFrame(cx, &rval);
     switch (status) {
       case JSTRAP_CONTINUE:
         break;
       case JSTRAP_THROW:
         cx->setPendingException(rval);
         break;
       case JSTRAP_ERROR:
         cx->clearPendingException();
         break;
       case JSTRAP_RETURN:
-        fp->setReturnValue(rval);
+        frame.setReturnValue(rval);
         break;
       default:
         JS_NOT_REACHED("bad Debugger::onEnterFrame JSTrapStatus value");
     }
     return status;
 }
 
 bool
-js::ScriptDebugEpilogue(JSContext *cx, StackFrame *fp, bool okArg)
+js::ScriptDebugEpilogue(JSContext *cx, AbstractFramePtr frame, bool okArg)
 {
-    JS_ASSERT(fp == cx->fp());
+    JS_ASSERT_IF(frame.isStackFrame(), frame.asStackFrame() == cx->fp());
     JSBool ok = okArg;
 
-    if (void *hookData = fp->maybeHookData()) {
-        if (fp->isFramePushedByExecute()) {
+    if (void *hookData = frame.maybeHookData()) {
+        if (frame.isFramePushedByExecute()) {
             if (JSInterpreterHook hook = cx->runtime->debugHooks.executeHook)
-                hook(cx, Jsvalify(fp), false, &ok, hookData);
+                hook(cx, Jsvalify(frame.asStackFrame()), false, &ok, hookData);
         } else {
             if (JSInterpreterHook hook = cx->runtime->debugHooks.callHook)
-                hook(cx, Jsvalify(fp), false, &ok, hookData);
+                hook(cx, Jsvalify(frame.asStackFrame()), false, &ok, hookData);
         }
     }
 
     return Debugger::onLeaveFrame(cx, ok);
 }
 
 JS_FRIEND_API(JSBool)
 JS_SetDebugModeForAllCompartments(JSContext *cx, JSBool debug)
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -17,51 +17,51 @@
 #include "vm/Stack.h"
 
 namespace js {
 
 /* Implemented in jsdbgapi: */
 
 /*
  * Announce to the debugger that the thread has entered a new JavaScript frame,
- * |fp|. Call whatever hooks have been registered to observe new frames, and
+ * |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 |cx->fp()|'s return value appropriately.
+ *   has set |frame|'s return value appropriately.
  */
 extern JSTrapStatus
-ScriptDebugPrologue(JSContext *cx, StackFrame *fp);
+ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame);
 
 /*
- * Announce to the debugger that the thread has exited a JavaScript frame, |fp|.
+ * 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 |fp|'s return value to reflect the changes in behavior
+ * 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, StackFrame *fp, bool ok);
+ScriptDebugEpilogue(JSContext *cx, AbstractFramePtr frame, bool ok);
 
 /*
  * 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
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -604,16 +604,45 @@ inline void
 StackIter::ionForEachCanonicalActualArg(Op op)
 {
     JS_ASSERT(isIon());
 #ifdef JS_ION
     ionInlineFrames_.forEachCanonicalActualArg(op, 0, -1);
 #endif
 }
 
+inline void *
+AbstractFramePtr::maybeHookData() const
+{
+    if (isStackFrame())
+        return asStackFrame()->maybeHookData();
+    JS_NOT_REACHED("Invalid frame");
+    return NULL;
+}
+
+inline void
+AbstractFramePtr::setHookData(void *data) const
+{
+    if (isStackFrame()) {
+        asStackFrame()->setHookData(data);
+        return;
+    }
+    JS_NOT_REACHED("Invalid frame");
+}
+
+inline void
+AbstractFramePtr::setReturnValue(const Value &rval) const
+{
+    if (isStackFrame()) {
+        asStackFrame()->setReturnValue(rval);
+        return;
+    }
+    JS_NOT_REACHED("Invalid frame");
+}
+
 inline UnrootedObject
 AbstractFramePtr::scopeChain() const
 {
     if (isStackFrame())
         return asStackFrame()->scopeChain();
     JS_NOT_REACHED("Invalid frame");
     return NULL;
 }
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1785,16 +1785,19 @@ class AbstractFramePtr
         return false;
     }
     bool isEvalFrame() const {
         if (isStackFrame())
             return asStackFrame()->isEvalFrame();
         JS_NOT_REACHED("Invalid frame");
         return false;
     }
+    bool isFramePushedByExecute() const {
+        return isGlobalFrame() || isEvalFrame();
+    }
     bool isDebuggerFrame() const {
         if (isStackFrame())
             return asStackFrame()->isDebuggerFrame();
         JS_NOT_REACHED("Invalid frame");
         return false;
     }
     JSScript *script() const {
         if (isStackFrame())
@@ -1893,16 +1896,20 @@ class AbstractFramePtr
     }
     AbstractFramePtr evalPrev() const {
         JS_ASSERT(isEvalFrame());
         if (isStackFrame())
             return AbstractFramePtr(asStackFrame()->prev());
         JS_NOT_REACHED("Invalid frame");
         return AbstractFramePtr();
     }
+
+    inline void *maybeHookData() const;
+    inline void setHookData(void *data) const;
+    inline void setReturnValue(const Value &rval) const;
 };
 
 template <>
 struct DefaultHasher<AbstractFramePtr> {
     typedef AbstractFramePtr Lookup;
 
     static js::HashNumber hash(const Lookup &key) {
         return size_t(key.raw());