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); } } } }
bool DebugState::clearBreakpointsIn(JSContext* cx, WasmInstanceObject* instance, js::Debugger* dbg, JSObject* handler) { MOZ_ASSERT(instance); if (!breakpointSites_.initialized()) return true; // Make copy of all sites list, so breakpointSites_ can be modified by // destroyBreakpointSite calls. Vector<WasmBreakpointSite*> sites(cx); if (!sites.resize(breakpointSites_.count())) return false; size_t i = 0; for (WasmBreakpointSiteMap::Range r = breakpointSites_.all(); !r.empty(); r.popFront()) sites[i++] = r.front().value(); for (WasmBreakpointSite* site : sites) { Breakpoint* nextbp; for (Breakpoint* bp = site->firstBreakpoint(); bp; bp = nextbp) { nextbp = bp->nextInSite(); if (bp->asWasm()->wasmInstance == instance && (!dbg || bp->debugger == dbg) && (!handler || bp->getHandler() == handler)) { bp->destroy(cx->runtime()->defaultFreeOp()); } } } return true; }
void JSCompartment::clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSScript *script, JSObject *handler) { JS_ASSERT_IF(script, script->compartment() == this); for (BreakpointSiteMap::Enum e(breakpointSites); !e.empty(); e.popFront()) { BreakpointSite *site = e.front().value; if (!script || site->script == script) { Breakpoint *nextbp; for (Breakpoint *bp = site->firstBreakpoint(); bp; bp = nextbp) { nextbp = bp->nextInSite(); if ((!dbg || bp->debugger == dbg) && (!handler || bp->getHandler() == handler)) bp->destroy(cx, &e); } } } }
void JSCompartment::sweepBreakpoints(JSContext *cx) { for (BreakpointSiteMap::Enum e(breakpointSites); !e.empty(); e.popFront()) { BreakpointSite *site = e.front().value; // clearTrap and nextbp are necessary here to avoid possibly // reading *site or *bp after destroying it. bool scriptGone = IsAboutToBeFinalized(cx, site->script); bool clearTrap = scriptGone && site->hasTrap(); Breakpoint *nextbp; for (Breakpoint *bp = site->firstBreakpoint(); bp; bp = nextbp) { nextbp = bp->nextInSite(); if (scriptGone || IsAboutToBeFinalized(cx, bp->debugger->toJSObject())) bp->destroy(cx, &e); } if (clearTrap) site->clearTrap(cx, &e); } }