mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 787905 - GC: SweepBackgroundThings can be called with freed compartments in list r=billm
This commit is contained in:
parent
5a2eb2a9cd
commit
fb88cce090
@ -3204,10 +3204,10 @@ ReleaseObservedTypes(JSRuntime *rt)
|
||||
}
|
||||
|
||||
static void
|
||||
SweepCompartments(FreeOp *fop, gcreason::Reason gcReason)
|
||||
SweepCompartments(FreeOp *fop, bool lastGC)
|
||||
{
|
||||
JSRuntime *rt = fop->runtime();
|
||||
JS_ASSERT_IF(gcReason == gcreason::LAST_CONTEXT, !rt->hasContexts());
|
||||
JS_ASSERT_IF(lastGC, !rt->hasContexts());
|
||||
|
||||
JSDestroyCompartmentCallback callback = rt->destroyCompartmentCallback;
|
||||
|
||||
@ -3222,7 +3222,7 @@ SweepCompartments(FreeOp *fop, gcreason::Reason gcReason)
|
||||
JSCompartment *compartment = *read++;
|
||||
|
||||
if (!compartment->hold && compartment->wasGCStarted() &&
|
||||
(compartment->arenas.arenaListsAreEmpty() || gcReason == gcreason::LAST_CONTEXT))
|
||||
(compartment->arenas.arenaListsAreEmpty() || lastGC))
|
||||
{
|
||||
compartment->arenas.checkEmptyFreeLists();
|
||||
if (callback)
|
||||
@ -3899,11 +3899,13 @@ SweepAtomsCompartment(JSRuntime *rt)
|
||||
}
|
||||
|
||||
static void
|
||||
EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason gcReason)
|
||||
EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool lastGC)
|
||||
{
|
||||
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP);
|
||||
FreeOp fop(rt, rt->gcSweepOnBackgroundThread);
|
||||
|
||||
JS_ASSERT_IF(lastGC, !rt->gcSweepOnBackgroundThread);
|
||||
|
||||
JS_ASSERT(rt->gcMarker.isDrained());
|
||||
rt->gcMarker.stop();
|
||||
|
||||
@ -3911,23 +3913,9 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason gcReaso
|
||||
PropertyTree::dumpShapes(rt);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up list of compartments for sweeping of background things.
|
||||
*/
|
||||
JS_ASSERT(!rt->gcSweepingCompartments);
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
c->gcNextCompartment = rt->gcSweepingCompartments;
|
||||
rt->gcSweepingCompartments = c;
|
||||
}
|
||||
|
||||
{
|
||||
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_DESTROY);
|
||||
|
||||
if (!rt->gcSweepOnBackgroundThread) {
|
||||
rt->freeLifoAlloc.freeAll();
|
||||
SweepBackgroundThings(rt, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sweep script filenames after sweeping functions in the generic loop
|
||||
* above. In this way when a scripted function's finalizer destroys the
|
||||
@ -3941,7 +3929,8 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason gcReaso
|
||||
* This removes compartments from rt->compartment, so we do it last to make
|
||||
* sure we don't miss sweeping any compartments.
|
||||
*/
|
||||
SweepCompartments(&fop, gcReason);
|
||||
if (!lastGC)
|
||||
SweepCompartments(&fop, lastGC);
|
||||
|
||||
#ifndef JS_THREADSAFE
|
||||
/*
|
||||
@ -3961,6 +3950,26 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason gcReaso
|
||||
arena->unsetAllocDuringSweep();
|
||||
}
|
||||
|
||||
/* Set up list of compartments for sweeping of background things. */
|
||||
JS_ASSERT(!rt->gcSweepingCompartments);
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
c->gcNextCompartment = rt->gcSweepingCompartments;
|
||||
rt->gcSweepingCompartments = c;
|
||||
}
|
||||
|
||||
/* If not sweeping on background thread then we must do it here. */
|
||||
if (!rt->gcSweepOnBackgroundThread) {
|
||||
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_DESTROY);
|
||||
|
||||
SweepBackgroundThings(rt, false);
|
||||
|
||||
rt->freeLifoAlloc.freeAll();
|
||||
|
||||
/* Ensure the compartments get swept if it's the last GC. */
|
||||
if (lastGC)
|
||||
SweepCompartments(&fop, lastGC);
|
||||
}
|
||||
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
c->setGCLastBytes(c->gcBytes, c->gcMallocAndFreeBytes, gckind);
|
||||
if (c->wasGCStarted())
|
||||
@ -4305,7 +4314,7 @@ IncrementalCollectSlice(JSRuntime *rt,
|
||||
break;
|
||||
}
|
||||
|
||||
EndSweepPhase(rt, gckind, reason);
|
||||
EndSweepPhase(rt, gckind, reason == gcreason::LAST_CONTEXT);
|
||||
|
||||
if (rt->gcSweepOnBackgroundThread)
|
||||
rt->gcHelperThread.startBackgroundSweep(gckind == GC_SHRINK);
|
||||
|
Loading…
Reference in New Issue
Block a user