зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1172193 - Also collect zones with cross zone pointers into the scheduled set r=terrence
This commit is contained in:
Родитель
17b0069adc
Коммит
6d50fefdbc
|
@ -893,6 +893,7 @@ class GCRuntime
|
|||
SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis);
|
||||
void collect(bool incremental, SliceBudget budget, JS::gcreason::Reason reason);
|
||||
bool gcCycle(bool incremental, SliceBudget& budget, JS::gcreason::Reason reason);
|
||||
void scheduleZonesWithIncomingCCWs();
|
||||
gcstats::ZoneGCStats scanZonesBeforeGC();
|
||||
void budgetIncrementalGC(SliceBudget& budget);
|
||||
void resetIncrementalGC(const char* reason);
|
||||
|
|
|
@ -418,10 +418,17 @@ js::gc::GCRuntime::markRuntime(JSTracer* trc,
|
|||
if (traceOrMark == MarkRuntime) {
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_MARK_CCWS);
|
||||
|
||||
/*
|
||||
* For the first collection that happens in GCRuntime::collect() there
|
||||
* should be no incoming edges from CCWs in uncollected zones, but for
|
||||
* subsequent collections (e.g. caused by resets) this may no longer be
|
||||
* true so we need to mark them here.
|
||||
*/
|
||||
for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) {
|
||||
if (!c->zone()->isCollecting())
|
||||
c->markCrossCompartmentWrappers(trc);
|
||||
}
|
||||
|
||||
Debugger::markIncomingCrossCompartmentEdges(trc);
|
||||
}
|
||||
|
||||
|
|
|
@ -6091,6 +6091,49 @@ IsDeterministicGCReason(JS::gcreason::Reason reason)
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
GCRuntime::scheduleZonesWithIncomingCCWs()
|
||||
{
|
||||
bool scheduledZones;
|
||||
do {
|
||||
scheduledZones = false;
|
||||
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
|
||||
if (zone->isGCScheduled())
|
||||
continue;
|
||||
for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
|
||||
for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) {
|
||||
const CrossCompartmentKey& key = e.front().key();
|
||||
if (key.kind == CrossCompartmentKey::ObjectWrapper) {
|
||||
Zone* dest = static_cast<JSObject*>(key.wrapped)->zone();
|
||||
if (dest->isGCScheduled()) {
|
||||
zone->scheduleGC();
|
||||
scheduledZones = true;
|
||||
goto nextZone;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nextZone:;
|
||||
}
|
||||
} while (scheduledZones);
|
||||
|
||||
#ifdef DEBUG
|
||||
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
|
||||
if (zone->isGCScheduled())
|
||||
continue;
|
||||
for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
|
||||
for (JSCompartment::WrapperEnum e(comp); !e.empty(); e.popFront()) {
|
||||
const CrossCompartmentKey& key = e.front().key();
|
||||
if (key.kind == CrossCompartmentKey::ObjectWrapper) {
|
||||
Zone* dest = static_cast<JSObject*>(key.wrapped)->zone();
|
||||
MOZ_ASSERT(!dest->isGCScheduled());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
gcstats::ZoneGCStats
|
||||
GCRuntime::scanZonesBeforeGC()
|
||||
{
|
||||
|
@ -6145,6 +6188,8 @@ GCRuntime::collect(bool incremental, SliceBudget budget, JS::gcreason::Reason re
|
|||
AutoStopVerifyingBarriers av(rt, reason == JS::gcreason::SHUTDOWN_CC ||
|
||||
reason == JS::gcreason::DESTROY_RUNTIME);
|
||||
|
||||
scheduleZonesWithIncomingCCWs();
|
||||
|
||||
gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind, budget, reason);
|
||||
|
||||
bool repeat = false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче