Bug 1647342 - Part 4: Convert forEachDebuggerFrame helper to expose Debugger*. r=arai! draft
authorLogan Smyth <loganfsmyth@gmail.com>
Fri, 19 Jun 2020 21:59:48 -0700
changeset 3000037 1bd332c4dddda11a2f30db626fa54daa3c0c91d8
parent 3000036 cc2fbb85bf68f98afb3550aaf7135dfd43563e02
child 3000038 d8c013d6bf679d885b2a9e2249acf128622bd45a
push id558605
push userloganfsmyth@gmail.com
push dateWed, 24 Jun 2020 00:03:09 +0000
treeherdertry@205d063a3098 [default view] [failures only]
reviewersarai
bugs1647342
milestone79.0a1
Bug 1647342 - Part 4: Convert forEachDebuggerFrame helper to expose Debugger*. r=arai! This is just a tiny refactor to avoid needing to then get the Debugger* from the frame when we already know it. Differential Revision: https://phabricator.services.mozilla.com/D80737
js/src/debugger/Debugger.cpp
js/src/debugger/Debugger.h
--- a/js/src/debugger/Debugger.cpp
+++ b/js/src/debugger/Debugger.cpp
@@ -1170,35 +1170,36 @@ bool DebugAPI::slowPathOnLeaveFrame(JSCo
 bool DebugAPI::slowPathOnNewGenerator(JSContext* cx, AbstractFramePtr frame,
                                       Handle<AbstractGeneratorObject*> genObj) {
   // This is called from JSOp::Generator, after default parameter expressions
   // are evaluated and well after onEnterFrame, so Debugger.Frame objects for
   // `frame` may already have been exposed to debugger code. The
   // AbstractGeneratorObject for this generator call, though, has just been
   // created. It must be associated with any existing Debugger.Frames.
   bool ok = true;
-  Debugger::forEachDebuggerFrame(frame, [&](DebuggerFrame* frameObjPtr) {
-    if (!ok) {
-      return;
-    }
-
-    RootedDebuggerFrame frameObj(cx, frameObjPtr);
-    {
-      AutoRealm ar(cx, frameObj);
-
-      if (!frameObj->setGeneratorInfo(cx, genObj)) {
-        ReportOutOfMemory(cx);
-
-        // This leaves `genObj` and `frameObj` unassociated. It's OK
-        // because we won't pause again with this generator on the stack:
-        // the caller will immediately discard `genObj` and unwind `frame`.
-        ok = false;
-      }
-    }
-  });
+  Debugger::forEachDebuggerFrame(
+      frame, [&](Debugger*, DebuggerFrame* frameObjPtr) {
+        if (!ok) {
+          return;
+        }
+
+        RootedDebuggerFrame frameObj(cx, frameObjPtr);
+        {
+          AutoRealm ar(cx, frameObj);
+
+          if (!frameObj->setGeneratorInfo(cx, genObj)) {
+            ReportOutOfMemory(cx);
+
+            // This leaves `genObj` and `frameObj` unassociated. It's OK
+            // because we won't pause again with this generator on the stack:
+            // the caller will immediately discard `genObj` and unwind `frame`.
+            ok = false;
+          }
+        }
+      });
   return ok;
 }
 
 /* static */
 bool DebugAPI::slowPathOnDebuggerStatement(JSContext* cx,
                                            AbstractFramePtr frame) {
   return Debugger::dispatchResumptionHook(
       cx, frame,
@@ -3204,26 +3205,26 @@ bool Debugger::updateExecutionObservabil
 }
 
 template <typename FrameFn>
 /* static */
 void Debugger::forEachDebuggerFrame(AbstractFramePtr frame, FrameFn fn) {
   for (Realm::DebuggerVectorEntry& entry : frame.global()->getDebuggers()) {
     Debugger* dbg = entry.dbg;
     if (FrameMap::Ptr frameEntry = dbg->frames.lookup(frame)) {
-      fn(frameEntry->value());
+      fn(dbg, frameEntry->value());
     }
   }
 }
 
 /* static */
 bool Debugger::getDebuggerFrames(AbstractFramePtr frame,
                                  MutableHandle<DebuggerFrameVector> frames) {
   bool hadOOM = false;
-  forEachDebuggerFrame(frame, [&](DebuggerFrame* frameobj) {
+  forEachDebuggerFrame(frame, [&](Debugger*, DebuggerFrame* frameobj) {
     if (!hadOOM && !frames.append(frameobj)) {
       hadOOM = true;
     }
   });
   return !hadOOM;
 }
 
 /* static */
@@ -6281,29 +6282,28 @@ bool Debugger::replaceFrameGuts(JSContex
   MOZ_ASSERT_IF(!frames.empty(), DebugAPI::inFrameMaps(to));
   return true;
 }
 
 /* static */
 bool DebugAPI::inFrameMaps(AbstractFramePtr frame) {
   bool foundAny = false;
   Debugger::forEachDebuggerFrame(
-      frame, [&](DebuggerFrame* frameobj) { foundAny = true; });
+      frame, [&](Debugger*, DebuggerFrame* frameobj) { foundAny = true; });
   return foundAny;
 }
 
 /* static */
 void Debugger::removeFromFrameMapsAndClearBreakpointsIn(JSContext* cx,
                                                         AbstractFramePtr frame,
                                                         bool suspending) {
-  forEachDebuggerFrame(frame, [&](DebuggerFrame* frameobj) {
+  forEachDebuggerFrame(frame, [&](Debugger* dbg, DebuggerFrame* frameobj) {
     JSFreeOp* fop = cx->runtime()->defaultFreeOp();
     frameobj->freeFrameIterData(fop);
 
-    Debugger* dbg = Debugger::fromChildJSObject(frameobj);
     dbg->frames.remove(frame);
 
     if (frameobj->hasGeneratorInfo()) {
       // If this is a generator's final pop, remove its entry from
       // generatorFrames. Such an entry exists if and only if the
       // Debugger.Frame's generator has been set.
       if (!suspending) {
         // Terminally exiting a generator.
--- a/js/src/debugger/Debugger.h
+++ b/js/src/debugger/Debugger.h
@@ -903,17 +903,17 @@ class Debugger : private mozilla::Linked
       IsObserving observing);
   static bool updateExecutionObservabilityOfScripts(
       JSContext* cx, const DebugAPI::ExecutionObservableSet& obs,
       IsObserving observing);
   static bool updateExecutionObservability(
       JSContext* cx, DebugAPI::ExecutionObservableSet& obs,
       IsObserving observing);
 
-  template <typename FrameFn /* void (DebuggerFrame*) */>
+  template <typename FrameFn /* void (Debugger*, DebuggerFrame*) */>
   static void forEachDebuggerFrame(AbstractFramePtr frame, FrameFn fn);
 
   /*
    * Return a vector containing all Debugger.Frame instances referring to
    * |frame|. |global| is |frame|'s global object; if nullptr or omitted, we
    * compute it ourselves from |frame|.
    */
   using DebuggerFrameVector = GCVector<DebuggerFrame*>;