Backed out changeset 0064d8949f0c (bug 1102541) for build bustage on a CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Fri, 12 Dec 2014 12:39:07 -0800
changeset 219586 93ede5de8bd31bd3316ade72b0731fe11bd4e660
parent 219585 d37c4cbaf41dbc75503d05fd34816c086ebf33eb
child 219587 4c12f753a0049ceac0dbc8f2e72fa892e2b1e150
push idunknown
push userunknown
push dateunknown
bugs1102541
milestone37.0a1
backs out0064d8949f0c0cd397696b894a6eeb51107c5315
Backed out changeset 0064d8949f0c (bug 1102541) for build bustage on a CLOSED TREE
js/public/UbiNode.h
js/src/vm/Debugger.cpp
js/src/vm/DebuggerMemory.cpp
js/src/vm/UbiNode.cpp
--- a/js/public/UbiNode.h
+++ b/js/public/UbiNode.h
@@ -467,55 +467,49 @@ typedef mozilla::Vector<SimpleEdge, 8, j
 // runtime. Having a single root |ubi::Node| is useful for algorithms written
 // with the assumption that there aren't multiple roots (such as computing
 // dominator trees) and you want a single point of entry. It also ensures that
 // the roots themselves get visited by |ubi::BreadthFirst| (they would otherwise
 // only be used as starting points).
 //
 // RootList::init itself causes a minor collection, but once the list of roots
 // has been created, GC must not occur, as the referent ubi::Nodes are not
-// stable across GC. The init calls emplace on |noGC|'s AutoCheckCannotGC, whose
+// stable across GC. The init calls emplace |gcp|'s AutoCheckCannotGC, whose
 // lifetime must extend at least as long as the RootList itself.
 //
 // Example usage:
 //
 //    {
 //        mozilla::Maybe<JS::AutoCheckCannotGC> maybeNoGC;
 //        JS::ubi::RootList rootList(cx, maybeNoGC);
-//        if (!rootList.init())
+//        if (!rootList.init(cx))
 //            return false;
 //
 //        // The AutoCheckCannotGC is guaranteed to exist if init returned true.
 //        MOZ_ASSERT(maybeNoGC.isSome());
 //
 //        JS::ubi::Node root(&rootList);
 //
 //        ...
 //    }
 class MOZ_STACK_CLASS RootList {
     Maybe<AutoCheckCannotGC> &noGC;
-    JSContext                *cx;
 
   public:
     SimpleEdgeVector edges;
     bool             wantNames;
 
     RootList(JSContext *cx, Maybe<AutoCheckCannotGC> &noGC, bool wantNames = false);
 
     // Find all GC roots.
-    bool init();
+    bool init(JSContext *cx);
     // Find only GC roots in the provided set of |Zone|s.
-    bool init(ZoneSet &debuggees);
+    bool init(JSContext *cx, ZoneSet &debuggees);
     // Find only GC roots in the given Debugger object's set of debuggee zones.
-    bool init(HandleObject debuggees);
-
-    // Explicitly add the given Node as a root in this RootList. If wantNames is
-    // true, you must pass an edgeName. The RootList does not take ownership of
-    // edgeName.
-    bool addRoot(Node node, const char16_t *edgeName = nullptr);
+    bool init(JSContext *cx, HandleObject debuggees);
 };
 
 
 // Concrete classes for ubi::Node referent types.
 
 template<>
 struct Concrete<RootList> : public Base {
     EdgeRange *edges(JSContext *cx, bool wantNames) const MOZ_OVERRIDE;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -3554,25 +3554,33 @@ class MOZ_STACK_CLASS Debugger::ObjectQu
     /*
      * Traverse the heap to find all relevant objects and add them to the
      * provided vector.
      */
     bool findObjects(AutoObjectVector &objs) {
         if (!prepareQuery())
             return false;
 
+        // Ensure that all of our debuggee globals are rooted so that they are
+        // visible in the RootList.
+        JS::AutoObjectVector debuggees(cx);
+        for (GlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) {
+            if (!debuggees.append(r.front()))
+                return false;
+        }
+
         {
             /*
              * We can't tolerate the GC moving things around while we're
              * searching the heap. Check that nothing we do causes a GC.
              */
             Maybe<JS::AutoCheckCannotGC> maybeNoGC;
             RootedObject dbgObj(cx, dbg->object);
             JS::ubi::RootList rootList(cx, maybeNoGC);
-            if (!rootList.init(dbgObj))
+            if (!rootList.init(cx, dbgObj))
                 return false;
 
             Traversal traversal(cx, *this, maybeNoGC.ref());
             if (!traversal.init())
                 return false;
             traversal.wantNames = false;
 
             if (!traversal.addStart(JS::ubi::Node(&rootList)) ||
--- a/js/src/vm/DebuggerMemory.cpp
+++ b/js/src/vm/DebuggerMemory.cpp
@@ -752,28 +752,32 @@ DebuggerMemory::takeCensus(JSContext *cx
     if (!census.init())
         return false;
 
     dbg::DefaultCensusHandler handler(census);
     if (!handler.init(census))
         return false;
 
     Debugger *dbg = memory->getDebugger();
-    RootedObject dbgObj(cx, dbg->object);
 
-    // Populate our target set of debuggee zones.
+    // Populate census.debuggeeZones and ensure that all of our debuggee globals
+    // are rooted so that they are visible in the RootList.
+    JS::AutoObjectVector debuggees(cx);
     for (GlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) {
-        if (!census.debuggeeZones.put(r.front()->zone()))
+        if (!census.debuggeeZones.put(r.front()->zone()) ||
+            !debuggees.append(static_cast<JSObject *>(r.front())))
+        {
             return false;
+        }
     }
 
     {
         Maybe<JS::AutoCheckCannotGC> maybeNoGC;
         JS::ubi::RootList rootList(cx, maybeNoGC);
-        if (!rootList.init(dbgObj))
+        if (!rootList.init(cx, census.debuggeeZones))
             return false;
 
         dbg::DefaultCensusTraversal traversal(cx, handler, maybeNoGC.ref());
         if (!traversal.init())
             return false;
         traversal.wantNames = false;
 
         if (!traversal.addStart(JS::ubi::Node(&rootList)) ||
--- a/js/src/vm/UbiNode.cpp
+++ b/js/src/vm/UbiNode.cpp
@@ -4,23 +4,21 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "js/UbiNode.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Scoped.h"
-#include "mozilla/UniquePtr.h"
 
 #include "jscntxt.h"
 #include "jsinfer.h"
 #include "jsobj.h"
 #include "jsscript.h"
-#include "jsstr.h"
 
 #include "jit/IonCode.h"
 #include "js/Debug.h"
 #include "js/TracingAPI.h"
 #include "js/TypeDecls.h"
 #include "js/Utility.h"
 #include "js/Vector.h"
 #include "vm/GlobalObject.h"
@@ -260,35 +258,34 @@ template class TracerConcrete<js::types:
 }
 
 
 namespace JS {
 namespace ubi {
 
 RootList::RootList(JSContext *cx, Maybe<AutoCheckCannotGC> &noGC, bool wantNames /* = false */)
   : noGC(noGC),
-    cx(cx),
     edges(cx),
     wantNames(wantNames)
 { }
 
 
 bool
-RootList::init()
+RootList::init(JSContext *cx)
 {
     SimpleEdgeVectorTracer tracer(cx, &edges, wantNames);
     JS_TraceRuntime(&tracer);
     if (!tracer.okay)
         return false;
     noGC.emplace(cx->runtime());
     return true;
 }
 
 bool
-RootList::init(ZoneSet &debuggees)
+RootList::init(JSContext *cx, ZoneSet &debuggees)
 {
     SimpleEdgeVector allRootEdges(cx);
     SimpleEdgeVectorTracer tracer(cx, &allRootEdges, wantNames);
 
     JS_TraceRuntime(&tracer);
     if (!tracer.okay)
         return false;
     JS_TraceIncomingCCWs(&tracer, debuggees);
@@ -304,59 +301,31 @@ RootList::init(ZoneSet &debuggees)
             return false;
     }
 
     noGC.emplace(cx->runtime());
     return true;
 }
 
 bool
-RootList::init(HandleObject debuggees)
+RootList::init(JSContext *cx, HandleObject debuggees)
 {
     MOZ_ASSERT(debuggees && JS::dbg::IsDebugger(ObjectValue(*debuggees)));
     js::Debugger *dbg = js::Debugger::fromJSObject(debuggees);
 
     ZoneSet debuggeeZones;
     if (!debuggeeZones.init())
         return false;
 
     for (js::GlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) {
         if (!debuggeeZones.put(r.front()->zone()))
             return false;
     }
 
-    if (!init(debuggeeZones))
-        return false;
-
-    // Ensure that each of our debuggee globals are in the root list.
-    for (GlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) {
-        if (!addRoot(JS::ubi::Node(static_cast<JSObject *>(r.front())),
-                     MOZ_UTF16("debuggee global")))
-        {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool
-RootList::addRoot(Node node, const char16_t *edgeName)
-{
-    MOZ_ASSERT(noGC.isSome());
-    MOZ_ASSERT_IF(wantNames, edgeName);
-
-    mozilla::UniquePtr<char16_t[], JS::FreePolicy> name;
-    if (edgeName) {
-        name = DuplicateString(cx, edgeName);
-        if (!name)
-            return false;
-    }
-
-    return edges.append(mozilla::Move(SimpleEdge(name.release(), node)));
+    return init(cx, debuggeeZones);
 }
 
 // An EdgeRange concrete class that holds a pre-existing vector of SimpleEdges.
 class PreComputedEdgeRange : public EdgeRange {
     SimpleEdgeVector &edges;
     size_t           i;
 
     void settle() {