Bug 1126865 - Use an enum to indicate GC phase finished / yield to mutator result r=sfink

This commit is contained in:
Jon Coppeard 2015-01-29 09:58:06 +00:00
Родитель 6d14a65c84
Коммит ac04492e87
2 изменённых файлов: 31 добавлений и 33 удалений

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

@ -820,6 +820,12 @@ class GCRuntime
void releaseHeldRelocatedArenas(); void releaseHeldRelocatedArenas();
private: private:
enum IncrementalProgress
{
NotFinished = 0,
Finished
};
void minorGCImpl(JS::gcreason::Reason reason, Nursery::TypeObjectList *pretenureTypes); void minorGCImpl(JS::gcreason::Reason reason, Nursery::TypeObjectList *pretenureTypes);
// For ArenaLists::allocateFromArena() // For ArenaLists::allocateFromArena()
@ -860,7 +866,7 @@ class GCRuntime
bool shouldPreserveJITCode(JSCompartment *comp, int64_t currentTime, bool shouldPreserveJITCode(JSCompartment *comp, int64_t currentTime,
JS::gcreason::Reason reason); JS::gcreason::Reason reason);
void bufferGrayRoots(); void bufferGrayRoots();
bool drainMarkStack(SliceBudget &sliceBudget, gcstats::Phase phase); IncrementalProgress drainMarkStack(SliceBudget &sliceBudget, gcstats::Phase phase);
template <class CompartmentIterT> void markWeakReferences(gcstats::Phase phase); template <class CompartmentIterT> void markWeakReferences(gcstats::Phase phase);
void markWeakReferencesInCurrentGroup(gcstats::Phase phase); void markWeakReferencesInCurrentGroup(gcstats::Phase phase);
template <class ZoneIterT, class CompartmentIterT> void markGrayReferences(gcstats::Phase phase); template <class ZoneIterT, class CompartmentIterT> void markGrayReferences(gcstats::Phase phase);
@ -876,7 +882,7 @@ class GCRuntime
void beginSweepingZoneGroup(); void beginSweepingZoneGroup();
bool shouldReleaseObservedTypes(); bool shouldReleaseObservedTypes();
void endSweepingZoneGroup(); void endSweepingZoneGroup();
bool sweepPhase(SliceBudget &sliceBudget); IncrementalProgress sweepPhase(SliceBudget &sliceBudget);
void endSweepPhase(bool lastGC); void endSweepPhase(bool lastGC);
void sweepZones(FreeOp *fop, bool lastGC); void sweepZones(FreeOp *fop, bool lastGC);
void decommitAllWithoutUnlocking(const AutoLockGC &lock); void decommitAllWithoutUnlocking(const AutoLockGC &lock);
@ -886,7 +892,7 @@ class GCRuntime
void sweepBackgroundThings(ZoneList &zones, LifoAlloc &freeBlocks, ThreadType threadType); void sweepBackgroundThings(ZoneList &zones, LifoAlloc &freeBlocks, ThreadType threadType);
void assertBackgroundSweepingFinished(); void assertBackgroundSweepingFinished();
bool shouldCompact(); bool shouldCompact();
bool compactPhase(bool lastGC); IncrementalProgress compactPhase(bool lastGC);
void sweepTypesAfterCompacting(Zone *zone); void sweepTypesAfterCompacting(Zone *zone);
void sweepZoneAfterCompacting(Zone *zone); void sweepZoneAfterCompacting(Zone *zone);
ArenaHeader *relocateArenas(); ArenaHeader *relocateArenas();

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

@ -5152,12 +5152,12 @@ ArenaLists::foregroundFinalize(FreeOp *fop, AllocKind thingKind, SliceBudget &sl
return true; return true;
} }
bool GCRuntime::IncrementalProgress
GCRuntime::drainMarkStack(SliceBudget &sliceBudget, gcstats::Phase phase) GCRuntime::drainMarkStack(SliceBudget &sliceBudget, gcstats::Phase phase)
{ {
/* Run a marking slice and return whether the stack is now empty. */ /* Run a marking slice and return whether the stack is now empty. */
gcstats::AutoPhase ap(stats, phase); gcstats::AutoPhase ap(stats, phase);
return marker.drainMarkStack(sliceBudget); return marker.drainMarkStack(sliceBudget) ? Finished : NotFinished;
} }
static void static void
@ -5197,15 +5197,15 @@ SweepArenaList(ArenaHeader **arenasToSweep, SliceBudget &sliceBudget, Args... ar
return true; return true;
} }
bool GCRuntime::IncrementalProgress
GCRuntime::sweepPhase(SliceBudget &sliceBudget) GCRuntime::sweepPhase(SliceBudget &sliceBudget)
{ {
gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP); gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP);
FreeOp fop(rt); FreeOp fop(rt);
bool finished = drainMarkStack(sliceBudget, gcstats::PHASE_SWEEP_MARK); if (drainMarkStack(sliceBudget, gcstats::PHASE_SWEEP_MARK) == NotFinished)
if (!finished) return NotFinished;
return false;
for (;;) { for (;;) {
// Sweep dead type information stored in scripts and type objects, but // Sweep dead type information stored in scripts and type objects, but
@ -5225,12 +5225,12 @@ GCRuntime::sweepPhase(SliceBudget &sliceBudget)
types::AutoClearTypeInferenceStateOnOOM oom(sweepZone); types::AutoClearTypeInferenceStateOnOOM oom(sweepZone);
if (!SweepArenaList<JSScript>(&al.gcScriptArenasToUpdate, sliceBudget, &oom)) if (!SweepArenaList<JSScript>(&al.gcScriptArenasToUpdate, sliceBudget, &oom))
return false; return NotFinished;
if (!SweepArenaList<types::TypeObject>( if (!SweepArenaList<types::TypeObject>(
&al.gcTypeObjectArenasToUpdate, sliceBudget, &oom)) &al.gcTypeObjectArenasToUpdate, sliceBudget, &oom))
{ {
return false; return NotFinished;
} }
// Finish sweeping type information in the zone. // Finish sweeping type information in the zone.
@ -5265,7 +5265,7 @@ GCRuntime::sweepPhase(SliceBudget &sliceBudget)
if (!zone->arenas.foregroundFinalize(&fop, kind, sliceBudget, if (!zone->arenas.foregroundFinalize(&fop, kind, sliceBudget,
incrementalSweepList)) incrementalSweepList))
return false; /* Yield to the mutator. */ return NotFinished;
/* Reset the slots of the sweep list that we used. */ /* Reset the slots of the sweep list that we used. */
incrementalSweepList.reset(thingsPerArena); incrementalSweepList.reset(thingsPerArena);
@ -5285,17 +5285,18 @@ GCRuntime::sweepPhase(SliceBudget &sliceBudget)
ArenaLists &al = sweepZone->arenas; ArenaLists &al = sweepZone->arenas;
if (!SweepArenaList<Shape>(&al.gcShapeArenasToUpdate, sliceBudget)) if (!SweepArenaList<Shape>(&al.gcShapeArenasToUpdate, sliceBudget))
return false; /* Yield to the mutator. */ return NotFinished;
if (!SweepArenaList<AccessorShape>(&al.gcAccessorShapeArenasToUpdate, sliceBudget)) if (!SweepArenaList<AccessorShape>(&al.gcAccessorShapeArenasToUpdate, sliceBudget))
return false; /* Yield to the mutator. */ return NotFinished;
} }
} }
endSweepingZoneGroup(); endSweepingZoneGroup();
getNextZoneGroup(); getNextZoneGroup();
if (!currentZoneGroup) if (!currentZoneGroup)
return true; /* We're finished. */ return Finished;
endMarkingZoneGroup(); endMarkingZoneGroup();
beginSweepingZoneGroup(); beginSweepingZoneGroup();
} }
@ -5415,7 +5416,7 @@ GCRuntime::endSweepPhase(bool lastGC)
#endif #endif
} }
bool GCRuntime::IncrementalProgress
GCRuntime::compactPhase(bool lastGC) GCRuntime::compactPhase(bool lastGC)
{ {
gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT); gcstats::AutoPhase ap(stats, gcstats::PHASE_COMPACT);
@ -5424,7 +5425,7 @@ GCRuntime::compactPhase(bool lastGC)
// Poll for end of background sweeping // Poll for end of background sweeping
AutoLockGC lock(rt); AutoLockGC lock(rt);
if (isBackgroundSweeping()) if (isBackgroundSweeping())
return false; return NotFinished;
} else { } else {
waitBackgroundSweepEnd(); waitBackgroundSweepEnd();
} }
@ -5482,7 +5483,7 @@ GCRuntime::compactPhase(bool lastGC)
} }
} }
#endif #endif
return true; return Finished;
} }
void void
@ -5801,15 +5802,14 @@ GCRuntime::incrementalCollectSlice(SliceBudget &budget, JS::gcreason::Reason rea
/* fall through */ /* fall through */
case MARK: { case MARK:
/* If we needed delayed marking for gray roots, then collect until done. */ /* If we needed delayed marking for gray roots, then collect until done. */
if (!marker.hasBufferedGrayRoots()) { if (!marker.hasBufferedGrayRoots()) {
budget.makeUnlimited(); budget.makeUnlimited();
isIncremental = false; isIncremental = false;
} }
bool finished = drainMarkStack(budget, gcstats::PHASE_MARK); if (drainMarkStack(budget, gcstats::PHASE_MARK) == NotFinished)
if (!finished)
break; break;
MOZ_ASSERT(marker.isDrained()); MOZ_ASSERT(marker.isDrained());
@ -5845,14 +5845,10 @@ GCRuntime::incrementalCollectSlice(SliceBudget &budget, JS::gcreason::Reason rea
break; break;
/* fall through */ /* fall through */
}
case SWEEP: case SWEEP:
{ if (sweepPhase(budget) == NotFinished)
bool finished = sweepPhase(budget);
if (!finished)
break; break;
}
endSweepPhase(lastGC); endSweepPhase(lastGC);
@ -5863,12 +5859,8 @@ GCRuntime::incrementalCollectSlice(SliceBudget &budget, JS::gcreason::Reason rea
break; break;
case COMPACT: case COMPACT:
if (shouldCompact()) { if (shouldCompact() && compactPhase(lastGC) == NotFinished)
bool finished = compactPhase(lastGC);
if (!finished)
break; break;
}
finishCollection(); finishCollection();
incrementalState = NO_INCREMENTAL; incrementalState = NO_INCREMENTAL;
break; break;