Bug 1172193 - Also collect zones with cross zone pointers into the scheduled set r=terrence

This commit is contained in:
Jon Coppeard 2015-06-11 07:58:36 +01:00
Родитель 17b0069adc
Коммит 6d50fefdbc
3 изменённых файлов: 53 добавлений и 0 удалений

Просмотреть файл

@ -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;