Bug 1108149 - Make ObjectQuery::findObjects use JS::ubi::RootList; r=shu

This commit is contained in:
Nick Fitzgerald 2014-12-10 09:47:21 -08:00
parent 4b22f0e0a0
commit af52943e44

View File

@ -3560,43 +3560,35 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery
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.
*/
JS::AutoCheckCannotGC autoCannotGC;
Maybe<JS::AutoCheckCannotGC> maybeNoGC;
RootedObject dbgObj(cx, dbg->object);
JS::ubi::RootList rootList(cx, maybeNoGC);
if (!rootList.init(cx, dbgObj))
return false;
Traversal traversal(cx, *this, autoCannotGC);
Traversal traversal(cx, *this, maybeNoGC.ref());
if (!traversal.init())
return false;
traversal.wantNames = false;
/* Add each debuggee global as a start point of our traversal. */
for (GlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront()) {
if (!traversal.addStartVisited(JS::ubi::Node(static_cast<JSObject *>(r.front()))))
return false;
}
/*
* Iterate over all compartments and add traversal start points at
* objects that have CCWs in other compartments keeping them alive.
*/
for (CompartmentsIter c(cx->runtime(), SkipAtoms); !c.done(); c.next()) {
JSCompartment *comp = c.get();
if (!comp)
continue;
for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) {
const CrossCompartmentKey &key = e.front().key();
if (key.kind != CrossCompartmentKey::ObjectWrapper)
continue;
JSObject *obj = static_cast<JSObject *>(key.wrapped);
if (!traversal.addStartVisited(JS::ubi::Node(obj)))
return false;
}
}
if (!traversal.traverse())
if (!traversal.addStart(JS::ubi::Node(&rootList)) ||
!traversal.traverse())
{
return false;
}
/*
* Iterate over the visited set of nodes and accumulate all
@ -3604,8 +3596,9 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery
*/
for (Traversal::NodeMap::Range r = traversal.visited.all(); !r.empty(); r.popFront()) {
JS::ubi::Node node = r.front().key();
if (!node.is<JSObject>() || !dbg->isDebuggee(node.compartment()))
if (!node.is<JSObject>())
continue;
MOZ_ASSERT(dbg->isDebuggee(node.compartment()));
JSObject *obj = node.as<JSObject>();
@ -3625,15 +3618,17 @@ class MOZ_STACK_CLASS Debugger::ObjectQuery
/*
* |ubi::Node::BreadthFirst| interface.
*
* We use an empty traversal function and just iterate over the traversal's
* visited set post-facto in |findObjects|.
*/
class NodeData {};
typedef JS::ubi::BreadthFirst<ObjectQuery> Traversal;
bool operator() (Traversal &, JS::ubi::Node, const JS::ubi::Edge &, NodeData *, bool)
bool operator() (Traversal &traversal, JS::ubi::Node origin, const JS::ubi::Edge &edge,
NodeData *, bool first)
{
/* Only follow edges within our set of debuggee compartments. */
JSCompartment *comp = edge.referent.compartment();
if (first && comp && !dbg->isDebuggee(edge.referent.compartment()))
traversal.abandonReferent();
return true;
}