bool RootList::init(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::WeakGlobalObjectSet::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 (js::WeakGlobalObjectSet::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; }
// If we are only taking a snapshot of the heap affected by the given set of // globals, find the set of zones the globals are allocated within. Returns // false on OOM failure. static bool PopulateZonesWithGlobals(ZoneSet& zones, AutoObjectVector& globals) { if (!zones.init()) return false; unsigned length = globals.length(); for (unsigned i = 0; i < length; i++) { if (!zones.put(GetObjectZone(globals[i]))) return false; } return true; }
bool RootList::init(CompartmentSet& debuggees) { EdgeVector allRootEdges; EdgeVectorTracer tracer(rt, &allRootEdges, wantNames); ZoneSet debuggeeZones; if (!debuggeeZones.init()) return false; for (auto range = debuggees.all(); !range.empty(); range.popFront()) { if (!debuggeeZones.put(range.front()->zone())) return false; } js::TraceRuntime(&tracer); if (!tracer.okay) return false; TraceIncomingCCWs(&tracer, debuggees); if (!tracer.okay) return false; for (EdgeVector::Range r = allRootEdges.all(); !r.empty(); r.popFront()) { Edge& edge = r.front(); JSCompartment* compartment = edge.referent.compartment(); if (compartment && !debuggees.has(compartment)) continue; Zone* zone = edge.referent.zone(); if (zone && !debuggeeZones.has(zone)) continue; if (!edges.append(mozilla::Move(edge))) return false; } noGC.emplace(rt); return true; }