diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 4a8e8bd31e9f..d6f6e129771f 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -173,6 +173,7 @@ static uint32_t sPendingLoadCount; static bool sLoadingInProgress; static uint32_t sCCollectedWaitingForGC; +static uint32_t sCCollectedZonesWaitingForGC; static uint32_t sLikelyShortLivingObjectsNeedingGC; static bool sPostGCEventsToConsole; static bool sPostGCEventsToObserver; @@ -246,6 +247,7 @@ static bool NeedsGCAfterCC() { return sCCollectedWaitingForGC > 250 || + sCCollectedZonesWaitingForGC > 0 || sLikelyShortLivingObjectsNeedingGC > 2500 || sNeedsGCAfterCC; } @@ -1806,7 +1808,8 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults) // CCs, this won't happen. gCCStats.FinishCycleCollectionSlice(); - sCCollectedWaitingForGC += aResults.mFreedRefCounted + aResults.mFreedGCed; + sCCollectedWaitingForGC += aResults.mFreedGCed; + sCCollectedZonesWaitingForGC += aResults.mFreedJSZones; TimeStamp endCCTimeStamp = TimeStamp::Now(); uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp); @@ -1855,7 +1858,7 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults) } 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")); nsString msg; 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.mVisitedRefCounted, aResults.mVisitedGCed, mergeMsg.get(), aResults.mFreedRefCounted, aResults.mFreedGCed, - sCCollectedWaitingForGC, sLikelyShortLivingObjectsNeedingGC, + sCCollectedWaitingForGC, sCCollectedZonesWaitingForGC, sLikelyShortLivingObjectsNeedingGC, gcMsg.get(), sForgetSkippableBeforeCC, minForgetSkippableTime / PR_USEC_PER_MSEC, @@ -1895,6 +1898,7 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults) MOZ_UTF16("\"RCed\": %lu, ") MOZ_UTF16("\"GCed\": %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("\"forced_gc\": %d, ") MOZ_UTF16("\"forget_skippable\": { ") @@ -1915,6 +1919,7 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults) aResults.mVisitedRefCounted, aResults.mVisitedGCed, aResults.mFreedRefCounted, aResults.mFreedGCed, sCCollectedWaitingForGC, + sCCollectedZonesWaitingForGC, sLikelyShortLivingObjectsNeedingGC, aResults.mForcedGC, sForgetSkippableBeforeCC, @@ -2370,6 +2375,7 @@ DOMGCSliceCallback(JSRuntime *aRt, JS::GCProgress aProgress, const JS::GCDescrip nsJSContext::KillInterSliceGCTimer(); sCCollectedWaitingForGC = 0; + sCCollectedZonesWaitingForGC = 0; sLikelyShortLivingObjectsNeedingGC = 0; sCleanupsSinceLastGC = 0; sNeedsFullCC = true; @@ -2452,6 +2458,7 @@ mozilla::dom::StartupJSEnvironment() sPendingLoadCount = 0; sLoadingInProgress = false; sCCollectedWaitingForGC = 0; + sCCollectedZonesWaitingForGC = 0; sLikelyShortLivingObjectsNeedingGC = 0; sPostGCEventsToConsole = false; sNeedsFullCC = false; diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h index 5ae7bf6f9d07..4685bf5c742b 100644 --- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -93,6 +93,7 @@ struct CycleCollectorResults mVisitedGCed = 0; mFreedRefCounted = 0; mFreedGCed = 0; + mFreedJSZones = 0; mNumSlices = 1; // mNumSlices is initialized to one, because we call Init() after the // per-slice increment of mNumSlices has already occurred. @@ -104,6 +105,7 @@ struct CycleCollectorResults uint32_t mVisitedGCed; uint32_t mFreedRefCounted; uint32_t mFreedGCed; + uint32_t mFreedJSZones; uint32_t mNumSlices; }; diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index aecc0a265ff9..399b719758e5 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -3242,6 +3242,11 @@ nsCycleCollector::CollectWhite() whiteNodes.SetCapacity(mWhiteNodeCount); uint32_t numWhiteGCed = 0; + uint32_t numWhiteJSZones = 0; + + bool hasJSRuntime = !!mJSRuntime; + nsCycleCollectionParticipant* zoneParticipant = + hasJSRuntime ? mJSRuntime->ZoneParticipant() : nullptr; NodePool::Enumerator etor(mGraph.mNodes); while (!etor.IsDone()) { @@ -3251,6 +3256,9 @@ nsCycleCollector::CollectWhite() pinfo->mParticipant->Root(pinfo->mPointer); if (pinfo->IsGrayJS()) { ++numWhiteGCed; + if (MOZ_UNLIKELY(pinfo->mParticipant == zoneParticipant)) { + ++numWhiteJSZones; + } } } } @@ -3260,6 +3268,7 @@ nsCycleCollector::CollectWhite() "More freed GCed nodes than total freed nodes."); mResults.mFreedRefCounted += count - numWhiteGCed; mResults.mFreedGCed += numWhiteGCed; + mResults.mFreedJSZones += numWhiteJSZones; timeLog.Checkpoint("CollectWhite::Root");