mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 956324 - Remove all breakpoints from a debugger when the last debuggee is removed r=billm
This commit is contained in:
parent
e41fdd7947
commit
e509557b22
@ -154,6 +154,9 @@ CheckMarkedThing(JSTracer *trc, T *thing)
|
||||
JS_ASSERT_IF(IS_GC_MARKING_TRACER(trc) && AsGCMarker(trc)->getMarkColor() == GRAY,
|
||||
!thing->zone()->isGCMarkingBlack() || rt->isAtomsZone(thing->zone()));
|
||||
|
||||
JS_ASSERT_IF(IS_GC_MARKING_TRACER(trc),
|
||||
!(thing->zone()->isGCSweeping() || thing->zone()->isGCFinished()));
|
||||
|
||||
/*
|
||||
* Try to assert that the thing is allocated. This is complicated by the
|
||||
* fact that allocated things may still contain the poison pattern if that
|
||||
|
@ -137,20 +137,28 @@ Zone::sweepBreakpoints(FreeOp *fop)
|
||||
gcstats::AutoPhase ap1(fop->runtime()->gcStats, gcstats::PHASE_SWEEP_TABLES);
|
||||
gcstats::AutoPhase ap2(fop->runtime()->gcStats, gcstats::PHASE_SWEEP_TABLES_BREAKPOINT);
|
||||
|
||||
JS_ASSERT(isGCSweeping());
|
||||
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
JS_ASSERT(script->zone()->isGCSweeping());
|
||||
if (!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->offsetToPC(i));
|
||||
if (!site)
|
||||
continue;
|
||||
|
||||
Breakpoint *nextbp;
|
||||
for (Breakpoint *bp = site->firstBreakpoint(); bp; bp = nextbp) {
|
||||
nextbp = bp->nextInSite();
|
||||
if (scriptGone || IsObjectAboutToBeFinalized(&bp->debugger->toJSObjectRef()))
|
||||
HeapPtrObject& dbgobj = bp->debugger->toJSObjectRef();
|
||||
JS_ASSERT(dbgobj->zone()->isGCSweeping());
|
||||
bool dying = scriptGone || IsObjectAboutToBeFinalized(&dbgobj);
|
||||
JS_ASSERT_IF(!dying, bp->getHandler()->isMarked());
|
||||
if (dying)
|
||||
bp->destroy(fop);
|
||||
}
|
||||
}
|
||||
|
28
js/src/jit-test/tests/gc/bug-956324.js
Normal file
28
js/src/jit-test/tests/gc/bug-956324.js
Normal file
@ -0,0 +1,28 @@
|
||||
var g = newGlobal();
|
||||
g.eval("function f() {\n" +
|
||||
" debugger;\n" +
|
||||
"}\n")
|
||||
|
||||
var dbg = new Debugger(g);
|
||||
var handler = {};
|
||||
dbg.onDebuggerStatement = function (frame) {
|
||||
frame.script.setBreakpoint(0, {});
|
||||
};
|
||||
|
||||
// create breakpoint
|
||||
g.f()
|
||||
|
||||
// drop our references to things
|
||||
handler = undefined;
|
||||
dbg.onDebuggerStatement = undefined;
|
||||
|
||||
dbg.removeAllDebuggees();
|
||||
|
||||
gc();
|
||||
|
||||
//create garbage to trigger a minor GC
|
||||
var x;
|
||||
for (var i = 0; i < 100; ++i)
|
||||
x = {};
|
||||
|
||||
gc();
|
@ -342,6 +342,7 @@ BreakpointSite::hasBreakpoint(Breakpoint *bp)
|
||||
Breakpoint::Breakpoint(Debugger *debugger, BreakpointSite *site, JSObject *handler)
|
||||
: debugger(debugger), site(site), handler(handler)
|
||||
{
|
||||
JS_ASSERT(handler->compartment() == debugger->object->compartment());
|
||||
JS_APPEND_LINK(&debuggerLinks, &debugger->breakpoints);
|
||||
JS_APPEND_LINK(&siteLinks, &site->breakpoints);
|
||||
}
|
||||
@ -2304,6 +2305,15 @@ Debugger::removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
|
||||
else
|
||||
debuggees.remove(global);
|
||||
|
||||
/* Remove all breakpoints for the debuggee. */
|
||||
Breakpoint *nextbp;
|
||||
for (Breakpoint *bp = firstBreakpoint(); bp; bp = nextbp) {
|
||||
nextbp = bp->nextInDebugger();
|
||||
if (bp->site->script->compartment() == global->compartment())
|
||||
bp->destroy(fop);
|
||||
}
|
||||
JS_ASSERT_IF(debuggees.empty(), !firstBreakpoint());
|
||||
|
||||
/*
|
||||
* The debuggee needs to be removed from the compartment last, as this can
|
||||
* trigger GCs if the compartment's debug mode is being changed, and the
|
||||
|
Loading…
Reference in New Issue
Block a user