void JSCompartment::sweepBreakpoints(FreeOp *fop) { gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_TABLES_BREAKPOINT); if (rt->debuggerList.isEmpty()) return; for (CellIterUnderGC i(zone(), FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get<JSScript>(); if (script->compartment() != this || !script->hasAnyBreakpointsOrStepMode()) continue; bool scriptGone = IsScriptAboutToBeFinalized(&script); JS_ASSERT(script == i.get<JSScript>()); for (unsigned i = 0; i < script->length; i++) { BreakpointSite *site = script->getBreakpointSite(script->code + i); if (!site) continue; // nextbp is necessary here to avoid possibly reading *bp after // destroying it. Breakpoint *nextbp; for (Breakpoint *bp = site->firstBreakpoint(); bp; bp = nextbp) { nextbp = bp->nextInSite(); if (scriptGone || IsObjectAboutToBeFinalized(&bp->debugger->toJSObjectRef())) bp->destroy(fop); } } } }
void JSCompartment::sweepBreakpoints(JSContext *cx) { if (JS_CLIST_IS_EMPTY(&cx->runtime->debuggerList)) return; for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) { JSScript *script = i.get<JSScript>(); if (!script->hasAnyBreakpointsOrStepMode()) continue; bool scriptGone = IsAboutToBeFinalized(cx, script); for (unsigned i = 0; i < script->length; i++) { BreakpointSite *site = script->getBreakpointSite(script->code + i); if (!site) continue; // nextbp is necessary here to avoid possibly reading *bp after // destroying it. Breakpoint *nextbp; for (Breakpoint *bp = site->firstBreakpoint(); bp; bp = nextbp) { nextbp = bp->nextInSite(); if (scriptGone || IsAboutToBeFinalized(cx, bp->debugger->toJSObject())) bp->destroy(cx); } } } }