Bug 727965 - Trigger CC_WAITING GCs based on number of freed JS objects and zones. r=smaug

This commit is contained in:
Andrew McCreight 2014-10-20 10:07:52 -07:00
Родитель 28c94f57f0
Коммит cc506c4751
3 изменённых файлов: 21 добавлений и 3 удалений

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

@ -173,6 +173,7 @@ static uint32_t sPendingLoadCount;
static bool sLoadingInProgress; static bool sLoadingInProgress;
static uint32_t sCCollectedWaitingForGC; static uint32_t sCCollectedWaitingForGC;
static uint32_t sCCollectedZonesWaitingForGC;
static uint32_t sLikelyShortLivingObjectsNeedingGC; static uint32_t sLikelyShortLivingObjectsNeedingGC;
static bool sPostGCEventsToConsole; static bool sPostGCEventsToConsole;
static bool sPostGCEventsToObserver; static bool sPostGCEventsToObserver;
@ -246,6 +247,7 @@ static bool
NeedsGCAfterCC() NeedsGCAfterCC()
{ {
return sCCollectedWaitingForGC > 250 || return sCCollectedWaitingForGC > 250 ||
sCCollectedZonesWaitingForGC > 0 ||
sLikelyShortLivingObjectsNeedingGC > 2500 || sLikelyShortLivingObjectsNeedingGC > 2500 ||
sNeedsGCAfterCC; sNeedsGCAfterCC;
} }
@ -1806,7 +1808,8 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
// CCs, this won't happen. // CCs, this won't happen.
gCCStats.FinishCycleCollectionSlice(); gCCStats.FinishCycleCollectionSlice();
sCCollectedWaitingForGC += aResults.mFreedRefCounted + aResults.mFreedGCed; sCCollectedWaitingForGC += aResults.mFreedGCed;
sCCollectedZonesWaitingForGC += aResults.mFreedJSZones;
TimeStamp endCCTimeStamp = TimeStamp::Now(); TimeStamp endCCTimeStamp = TimeStamp::Now();
uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp); uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp);
@ -1855,7 +1858,7 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
} }
NS_NAMED_MULTILINE_LITERAL_STRING(kFmt, NS_NAMED_MULTILINE_LITERAL_STRING(kFmt,
MOZ_UTF16("CC(T+%.1f) max pause: %lums, total time: %lums, slices: %lu, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu waiting for GC)%s\n") MOZ_UTF16("CC(T+%.1f) max pause: %lums, total time: %lums, slices: %lu, suspected: %lu, visited: %lu RCed and %lu%s GCed, collected: %lu RCed and %lu GCed (%lu|%lu|%lu waiting for GC)%s\n")
MOZ_UTF16("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, max sync: %lu ms, removed: %lu")); MOZ_UTF16("ForgetSkippable %lu times before CC, min: %lu ms, max: %lu ms, avg: %lu ms, total: %lu ms, max sync: %lu ms, removed: %lu"));
nsString msg; nsString msg;
msg.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC, msg.Adopt(nsTextFormatter::smprintf(kFmt.get(), double(delta) / PR_USEC_PER_SEC,
@ -1863,7 +1866,7 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
aResults.mNumSlices, gCCStats.mSuspected, aResults.mNumSlices, gCCStats.mSuspected,
aResults.mVisitedRefCounted, aResults.mVisitedGCed, mergeMsg.get(), aResults.mVisitedRefCounted, aResults.mVisitedGCed, mergeMsg.get(),
aResults.mFreedRefCounted, aResults.mFreedGCed, aResults.mFreedRefCounted, aResults.mFreedGCed,
sCCollectedWaitingForGC, sLikelyShortLivingObjectsNeedingGC, sCCollectedWaitingForGC, sCCollectedZonesWaitingForGC, sLikelyShortLivingObjectsNeedingGC,
gcMsg.get(), gcMsg.get(),
sForgetSkippableBeforeCC, sForgetSkippableBeforeCC,
minForgetSkippableTime / PR_USEC_PER_MSEC, minForgetSkippableTime / PR_USEC_PER_MSEC,
@ -1895,6 +1898,7 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
MOZ_UTF16("\"RCed\": %lu, ") MOZ_UTF16("\"RCed\": %lu, ")
MOZ_UTF16("\"GCed\": %lu }, ") MOZ_UTF16("\"GCed\": %lu }, ")
MOZ_UTF16("\"waiting_for_gc\": %lu, ") MOZ_UTF16("\"waiting_for_gc\": %lu, ")
MOZ_UTF16("\"zones_waiting_for_gc\": %lu, ")
MOZ_UTF16("\"short_living_objects_waiting_for_gc\": %lu, ") MOZ_UTF16("\"short_living_objects_waiting_for_gc\": %lu, ")
MOZ_UTF16("\"forced_gc\": %d, ") MOZ_UTF16("\"forced_gc\": %d, ")
MOZ_UTF16("\"forget_skippable\": { ") MOZ_UTF16("\"forget_skippable\": { ")
@ -1915,6 +1919,7 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
aResults.mVisitedRefCounted, aResults.mVisitedGCed, aResults.mVisitedRefCounted, aResults.mVisitedGCed,
aResults.mFreedRefCounted, aResults.mFreedGCed, aResults.mFreedRefCounted, aResults.mFreedGCed,
sCCollectedWaitingForGC, sCCollectedWaitingForGC,
sCCollectedZonesWaitingForGC,
sLikelyShortLivingObjectsNeedingGC, sLikelyShortLivingObjectsNeedingGC,
aResults.mForcedGC, aResults.mForcedGC,
sForgetSkippableBeforeCC, sForgetSkippableBeforeCC,
@ -2370,6 +2375,7 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::GCProgress aProgress, const JS::GCDescrip
nsJSContext::KillInterSliceGCTimer(); nsJSContext::KillInterSliceGCTimer();
sCCollectedWaitingForGC = 0; sCCollectedWaitingForGC = 0;
sCCollectedZonesWaitingForGC = 0;
sLikelyShortLivingObjectsNeedingGC = 0; sLikelyShortLivingObjectsNeedingGC = 0;
sCleanupsSinceLastGC = 0; sCleanupsSinceLastGC = 0;
sNeedsFullCC = true; sNeedsFullCC = true;
@ -2452,6 +2458,7 @@ mozilla::dom::StartupJSEnvironment()
sPendingLoadCount = 0; sPendingLoadCount = 0;
sLoadingInProgress = false; sLoadingInProgress = false;
sCCollectedWaitingForGC = 0; sCCollectedWaitingForGC = 0;
sCCollectedZonesWaitingForGC = 0;
sLikelyShortLivingObjectsNeedingGC = 0; sLikelyShortLivingObjectsNeedingGC = 0;
sPostGCEventsToConsole = false; sPostGCEventsToConsole = false;
sNeedsFullCC = false; sNeedsFullCC = false;

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

@ -93,6 +93,7 @@ struct CycleCollectorResults
mVisitedGCed = 0; mVisitedGCed = 0;
mFreedRefCounted = 0; mFreedRefCounted = 0;
mFreedGCed = 0; mFreedGCed = 0;
mFreedJSZones = 0;
mNumSlices = 1; mNumSlices = 1;
// mNumSlices is initialized to one, because we call Init() after the // mNumSlices is initialized to one, because we call Init() after the
// per-slice increment of mNumSlices has already occurred. // per-slice increment of mNumSlices has already occurred.
@ -104,6 +105,7 @@ struct CycleCollectorResults
uint32_t mVisitedGCed; uint32_t mVisitedGCed;
uint32_t mFreedRefCounted; uint32_t mFreedRefCounted;
uint32_t mFreedGCed; uint32_t mFreedGCed;
uint32_t mFreedJSZones;
uint32_t mNumSlices; uint32_t mNumSlices;
}; };

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

@ -3242,6 +3242,11 @@ nsCycleCollector::CollectWhite()
whiteNodes.SetCapacity(mWhiteNodeCount); whiteNodes.SetCapacity(mWhiteNodeCount);
uint32_t numWhiteGCed = 0; uint32_t numWhiteGCed = 0;
uint32_t numWhiteJSZones = 0;
bool hasJSRuntime = !!mJSRuntime;
nsCycleCollectionParticipant* zoneParticipant =
hasJSRuntime ? mJSRuntime->ZoneParticipant() : nullptr;
NodePool::Enumerator etor(mGraph.mNodes); NodePool::Enumerator etor(mGraph.mNodes);
while (!etor.IsDone()) { while (!etor.IsDone()) {
@ -3251,6 +3256,9 @@ nsCycleCollector::CollectWhite()
pinfo->mParticipant->Root(pinfo->mPointer); pinfo->mParticipant->Root(pinfo->mPointer);
if (pinfo->IsGrayJS()) { if (pinfo->IsGrayJS()) {
++numWhiteGCed; ++numWhiteGCed;
if (MOZ_UNLIKELY(pinfo->mParticipant == zoneParticipant)) {
++numWhiteJSZones;
}
} }
} }
} }
@ -3260,6 +3268,7 @@ nsCycleCollector::CollectWhite()
"More freed GCed nodes than total freed nodes."); "More freed GCed nodes than total freed nodes.");
mResults.mFreedRefCounted += count - numWhiteGCed; mResults.mFreedRefCounted += count - numWhiteGCed;
mResults.mFreedGCed += numWhiteGCed; mResults.mFreedGCed += numWhiteGCed;
mResults.mFreedJSZones += numWhiteJSZones;
timeLog.Checkpoint("CollectWhite::Root"); timeLog.Checkpoint("CollectWhite::Root");