зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1580883 - Use TimeDuration for constants in nsJSEnvironment.cpp r=mccr8
Differential Revision: https://phabricator.services.mozilla.com/D45695 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
559e2c332d
Коммит
99e7fae124
|
@ -106,34 +106,40 @@ const size_t gStackSize = 8192;
|
||||||
|
|
||||||
// The amount of time we wait between a request to CC (after GC ran)
|
// The amount of time we wait between a request to CC (after GC ran)
|
||||||
// and doing the actual CC.
|
// and doing the actual CC.
|
||||||
static const uint32_t kCCDelay = 6000; // ms
|
static const TimeDuration kCCDelay = TimeDuration::FromSeconds(6);
|
||||||
|
|
||||||
static const int32_t kCCSkippableDelay = 250; // ms
|
static const TimeDuration kCCSkippableDelay =
|
||||||
|
TimeDuration::FromMilliseconds(250);
|
||||||
|
|
||||||
// In case the cycle collector isn't run at all, we don't want
|
// In case the cycle collector isn't run at all, we don't want forget skippables
|
||||||
// forget skippables to run too often. So limit the forget skippable cycle to
|
// to run too often. So limit the forget skippable cycle to start at earliest 2
|
||||||
// start at earliest 2000 ms after the end of the previous cycle.
|
// seconds after the end of the previous cycle.
|
||||||
static const uint32_t kTimeBetweenForgetSkippableCycles = 2000; // ms
|
static const TimeDuration kTimeBetweenForgetSkippableCycles =
|
||||||
|
TimeDuration::FromSeconds(2);
|
||||||
|
|
||||||
// ForgetSkippable is usually fast, so we can use small budgets.
|
// ForgetSkippable is usually fast, so we can use small budgets.
|
||||||
// This isn't a real budget but a hint to IdleTaskRunner whether there
|
// This isn't a real budget but a hint to IdleTaskRunner whether there
|
||||||
// is enough time to call ForgetSkippable.
|
// is enough time to call ForgetSkippable.
|
||||||
static const int64_t kForgetSkippableSliceDuration = 2;
|
static const TimeDuration kForgetSkippableSliceDuration =
|
||||||
|
TimeDuration::FromMilliseconds(2);
|
||||||
|
|
||||||
// Maximum amount of time that should elapse between incremental CC slices
|
// Maximum amount of time that should elapse between incremental CC slices
|
||||||
static const int64_t kICCIntersliceDelay = 64; // ms
|
static const TimeDuration kICCIntersliceDelay =
|
||||||
|
TimeDuration::FromMilliseconds(64);
|
||||||
|
|
||||||
// Time budget for an incremental CC slice when using timer to run it.
|
// Time budget for an incremental CC slice when using timer to run it.
|
||||||
static const int64_t kICCSliceBudget = 3; // ms
|
static const TimeDuration kICCSliceBudget = TimeDuration::FromMilliseconds(3);
|
||||||
// Minimum budget for an incremental CC slice when using idle time to run it.
|
// Minimum budget for an incremental CC slice when using idle time to run it.
|
||||||
static const int64_t kIdleICCSliceBudget = 2; // ms
|
static const TimeDuration kIdleICCSliceBudget =
|
||||||
|
TimeDuration::FromMilliseconds(2);
|
||||||
|
|
||||||
// Maximum total duration for an ICC
|
// Maximum total duration for an ICC
|
||||||
static const uint32_t kMaxICCDuration = 2000; // ms
|
static const TimeDuration kMaxICCDuration = TimeDuration::FromSeconds(2);
|
||||||
|
|
||||||
// Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
|
// Force a CC after this long if there's more than NS_CC_FORCED_PURPLE_LIMIT
|
||||||
// objects in the purple buffer.
|
// objects in the purple buffer.
|
||||||
static const uint32_t kCCForced = (2 * 60 * PR_USEC_PER_SEC); // 2 min
|
static const TimeDuration kCCForced =
|
||||||
|
TimeDuration::FromSeconds(2 * 60); // 2 min
|
||||||
static const uint32_t kCCForcedPurpleLimit = 10;
|
static const uint32_t kCCForcedPurpleLimit = 10;
|
||||||
|
|
||||||
// Don't allow an incremental GC to lock out the CC for too long.
|
// Don't allow an incremental GC to lock out the CC for too long.
|
||||||
|
@ -1138,6 +1144,10 @@ static void FinishAnyIncrementalGC() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline js::SliceBudget BudgetFromDuration(TimeDuration duration) {
|
||||||
|
return js::SliceBudget(js::TimeBudget(duration.ToMilliseconds()));
|
||||||
|
}
|
||||||
|
|
||||||
static void FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless,
|
static void FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless,
|
||||||
TimeStamp aDeadline) {
|
TimeStamp aDeadline) {
|
||||||
AUTO_PROFILER_TRACING(
|
AUTO_PROFILER_TRACING(
|
||||||
|
@ -1177,11 +1187,10 @@ static void FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless,
|
||||||
FinishAnyIncrementalGC();
|
FinishAnyIncrementalGC();
|
||||||
bool earlyForgetSkippable = sCleanupsSinceLastGC < kMajorForgetSkippableCalls;
|
bool earlyForgetSkippable = sCleanupsSinceLastGC < kMajorForgetSkippableCalls;
|
||||||
|
|
||||||
int64_t budgetMs =
|
TimeDuration budgetTime = aDeadline ? (aDeadline - TimeStamp::Now())
|
||||||
aDeadline.IsNull()
|
: kForgetSkippableSliceDuration;
|
||||||
? kForgetSkippableSliceDuration
|
|
||||||
: int64_t((aDeadline - TimeStamp::Now()).ToMilliseconds());
|
js::SliceBudget budget = BudgetFromDuration(budgetTime);
|
||||||
js::SliceBudget budget = js::SliceBudget(js::TimeBudget(budgetMs));
|
|
||||||
nsCycleCollector_forgetSkippable(budget, aRemoveChildless,
|
nsCycleCollector_forgetSkippable(budget, aRemoveChildless,
|
||||||
earlyForgetSkippable);
|
earlyForgetSkippable);
|
||||||
|
|
||||||
|
@ -1223,18 +1232,28 @@ static void FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless,
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ALWAYS_INLINE
|
MOZ_ALWAYS_INLINE
|
||||||
static uint32_t TimeBetween(TimeStamp start, TimeStamp end) {
|
static TimeDuration TimeBetween(TimeStamp start, TimeStamp end) {
|
||||||
MOZ_ASSERT(end >= start);
|
MOZ_ASSERT(end >= start);
|
||||||
return (uint32_t)((end - start).ToMilliseconds());
|
return end - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t TimeUntilNow(TimeStamp start) {
|
MOZ_ALWAYS_INLINE
|
||||||
|
static uint32_t TimeBetweenInMillis(TimeStamp start, TimeStamp end) {
|
||||||
|
return uint32_t(TimeBetween(start, end).ToMilliseconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
static TimeDuration TimeUntilNow(TimeStamp start) {
|
||||||
if (start.IsNull()) {
|
if (start.IsNull()) {
|
||||||
return 0;
|
return TimeDuration();
|
||||||
}
|
}
|
||||||
return TimeBetween(start, TimeStamp::Now());
|
return TimeBetween(start, TimeStamp::Now());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_ALWAYS_INLINE
|
||||||
|
static uint32_t TimeUntilNowInMillis(TimeStamp start) {
|
||||||
|
return uint32_t(TimeUntilNow(start).ToMilliseconds());
|
||||||
|
}
|
||||||
|
|
||||||
struct CycleCollectorStats {
|
struct CycleCollectorStats {
|
||||||
constexpr CycleCollectorStats()
|
constexpr CycleCollectorStats()
|
||||||
: mMaxGCDuration(0),
|
: mMaxGCDuration(0),
|
||||||
|
@ -1315,7 +1334,7 @@ struct CycleCollectorStats {
|
||||||
percent);
|
percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t sliceTime = TimeBetween(mBeginSliceTime, mEndSliceTime);
|
uint32_t sliceTime = TimeBetweenInMillis(mBeginSliceTime, mEndSliceTime);
|
||||||
mMaxSliceTime = std::max(mMaxSliceTime, sliceTime);
|
mMaxSliceTime = std::max(mMaxSliceTime, sliceTime);
|
||||||
mMaxSliceTimeSinceClear = std::max(mMaxSliceTimeSinceClear, sliceTime);
|
mMaxSliceTimeSinceClear = std::max(mMaxSliceTimeSinceClear, sliceTime);
|
||||||
mTotalSliceTime += sliceTime;
|
mTotalSliceTime += sliceTime;
|
||||||
|
@ -1376,7 +1395,7 @@ void CycleCollectorStats::PrepareForCycleCollectionSlice(TimeStamp aDeadline) {
|
||||||
if (sCCLockedOut) {
|
if (sCCLockedOut) {
|
||||||
mAnyLockedOut = true;
|
mAnyLockedOut = true;
|
||||||
FinishAnyIncrementalGC();
|
FinishAnyIncrementalGC();
|
||||||
uint32_t gcTime = TimeBetween(mBeginSliceTime, TimeStamp::Now());
|
uint32_t gcTime = TimeBetweenInMillis(mBeginSliceTime, TimeStamp::Now());
|
||||||
mMaxGCDuration = std::max(mMaxGCDuration, gcTime);
|
mMaxGCDuration = std::max(mMaxGCDuration, gcTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1392,8 +1411,8 @@ void CycleCollectorStats::RunForgetSkippable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ranSyncForgetSkippable) {
|
if (ranSyncForgetSkippable) {
|
||||||
mMaxSkippableDuration =
|
mMaxSkippableDuration = std::max(
|
||||||
std::max(mMaxSkippableDuration, TimeUntilNow(beginForgetSkippable));
|
mMaxSkippableDuration, TimeUntilNowInMillis(beginForgetSkippable));
|
||||||
mRanSyncForgetSkippable = true;
|
mRanSyncForgetSkippable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1429,44 +1448,44 @@ void nsJSContext::RunCycleCollectorSlice(TimeStamp aDeadline) {
|
||||||
js::SliceBudget budget = js::SliceBudget::unlimited();
|
js::SliceBudget budget = js::SliceBudget::unlimited();
|
||||||
|
|
||||||
if (sIncrementalCC) {
|
if (sIncrementalCC) {
|
||||||
int64_t baseBudget = kICCSliceBudget;
|
TimeDuration baseBudget = kICCSliceBudget;
|
||||||
if (!aDeadline.IsNull()) {
|
if (!aDeadline.IsNull()) {
|
||||||
baseBudget = int64_t((aDeadline - TimeStamp::Now()).ToMilliseconds());
|
baseBudget = aDeadline - TimeStamp::Now();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gCCStats.mBeginTime.IsNull()) {
|
if (gCCStats.mBeginTime.IsNull()) {
|
||||||
// If no CC is in progress, use the standard slice time.
|
// If no CC is in progress, use the standard slice time.
|
||||||
budget = js::SliceBudget(js::TimeBudget(baseBudget));
|
budget = BudgetFromDuration(baseBudget);
|
||||||
} else {
|
} else {
|
||||||
TimeStamp now = TimeStamp::Now();
|
TimeStamp now = TimeStamp::Now();
|
||||||
|
|
||||||
// Only run a limited slice if we're within the max running time.
|
// Only run a limited slice if we're within the max running time.
|
||||||
uint32_t runningTime = TimeBetween(gCCStats.mBeginTime, now);
|
TimeDuration runningTime = TimeBetween(gCCStats.mBeginTime, now);
|
||||||
if (runningTime < kMaxICCDuration) {
|
if (runningTime < kMaxICCDuration) {
|
||||||
const float maxSlice = MainThreadIdlePeriod::GetLongIdlePeriod();
|
const TimeDuration maxSlice = TimeDuration::FromMilliseconds(
|
||||||
|
MainThreadIdlePeriod::GetLongIdlePeriod());
|
||||||
|
|
||||||
// Try to make up for a delay in running this slice.
|
// Try to make up for a delay in running this slice.
|
||||||
float sliceDelayMultiplier = TimeBetween(gCCStats.mEndSliceTime, now) /
|
double sliceDelayMultiplier =
|
||||||
(float)kICCIntersliceDelay;
|
TimeBetween(gCCStats.mEndSliceTime, now) / kICCIntersliceDelay;
|
||||||
float delaySliceBudget =
|
TimeDuration delaySliceBudget =
|
||||||
std::min(baseBudget * sliceDelayMultiplier, maxSlice);
|
std::min(baseBudget.MultDouble(sliceDelayMultiplier), maxSlice);
|
||||||
|
|
||||||
// Increase slice budgets up to |maxSlice| as we approach
|
// Increase slice budgets up to |maxSlice| as we approach
|
||||||
// half way through the ICC, to avoid large sync CCs.
|
// half way through the ICC, to avoid large sync CCs.
|
||||||
float percentToHalfDone =
|
double percentToHalfDone =
|
||||||
std::min(2.0f * runningTime / kMaxICCDuration, 1.0f);
|
std::min(2.0 * (runningTime / kMaxICCDuration), 1.0);
|
||||||
float laterSliceBudget = maxSlice * percentToHalfDone;
|
TimeDuration laterSliceBudget = maxSlice.MultDouble(percentToHalfDone);
|
||||||
|
|
||||||
budget = js::SliceBudget(js::TimeBudget(
|
budget = BudgetFromDuration(
|
||||||
std::max({delaySliceBudget, laterSliceBudget, (float)baseBudget})));
|
std::max({delaySliceBudget, laterSliceBudget, baseBudget}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCycleCollector_collectSlice(
|
nsCycleCollector_collectSlice(
|
||||||
budget,
|
budget,
|
||||||
aDeadline.IsNull() ||
|
aDeadline.IsNull() || (aDeadline - TimeStamp::Now()) < kICCSliceBudget);
|
||||||
(aDeadline - TimeStamp::Now()).ToMilliseconds() < kICCSliceBudget);
|
|
||||||
|
|
||||||
gCCStats.FinishCycleCollectionSlice();
|
gCCStats.FinishCycleCollectionSlice();
|
||||||
}
|
}
|
||||||
|
@ -1543,8 +1562,9 @@ void nsJSContext::BeginCycleCollectionCallback() {
|
||||||
// finish it.
|
// finish it.
|
||||||
sICCRunner = IdleTaskRunner::Create(
|
sICCRunner = IdleTaskRunner::Create(
|
||||||
ICCRunnerFired, "BeginCycleCollectionCallback::ICCRunnerFired",
|
ICCRunnerFired, "BeginCycleCollectionCallback::ICCRunnerFired",
|
||||||
kICCIntersliceDelay, kIdleICCSliceBudget, true,
|
kICCIntersliceDelay.ToMilliseconds(),
|
||||||
[] { return sShuttingDown; }, TaskCategory::GarbageCollection);
|
kIdleICCSliceBudget.ToMilliseconds(), true, [] { return sShuttingDown; },
|
||||||
|
TaskCategory::GarbageCollection);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -1562,15 +1582,16 @@ void nsJSContext::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
|
||||||
sCCollectedZonesWaitingForGC += aResults.mFreedJSZones;
|
sCCollectedZonesWaitingForGC += aResults.mFreedJSZones;
|
||||||
|
|
||||||
TimeStamp endCCTimeStamp = TimeStamp::Now();
|
TimeStamp endCCTimeStamp = TimeStamp::Now();
|
||||||
uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp);
|
TimeDuration ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp);
|
||||||
|
|
||||||
if (NeedsGCAfterCC()) {
|
if (NeedsGCAfterCC()) {
|
||||||
MOZ_ASSERT(StaticPrefs::javascript_options_gc_delay() > kMaxICCDuration,
|
MOZ_ASSERT(StaticPrefs::javascript_options_gc_delay() >
|
||||||
|
kMaxICCDuration.ToMilliseconds(),
|
||||||
"A max duration ICC shouldn't reduce GC delay to 0");
|
"A max duration ICC shouldn't reduce GC delay to 0");
|
||||||
|
|
||||||
PokeGC(JS::GCReason::CC_WAITING, nullptr,
|
PokeGC(JS::GCReason::CC_WAITING, nullptr,
|
||||||
StaticPrefs::javascript_options_gc_delay() -
|
StaticPrefs::javascript_options_gc_delay() -
|
||||||
std::min(ccNowDuration, kMaxICCDuration));
|
std::min(ccNowDuration, kMaxICCDuration).ToMilliseconds());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log information about the CC via telemetry, JSON and the console.
|
// Log information about the CC via telemetry, JSON and the console.
|
||||||
|
@ -1578,15 +1599,15 @@ void nsJSContext::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
|
||||||
gCCStats.mAnyLockedOut);
|
gCCStats.mAnyLockedOut);
|
||||||
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_SYNC_SKIPPABLE,
|
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_SYNC_SKIPPABLE,
|
||||||
gCCStats.mRanSyncForgetSkippable);
|
gCCStats.mRanSyncForgetSkippable);
|
||||||
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FULL, ccNowDuration);
|
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_FULL,
|
||||||
|
ccNowDuration.ToMilliseconds());
|
||||||
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_MAX_PAUSE,
|
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_MAX_PAUSE,
|
||||||
gCCStats.mMaxSliceTime);
|
gCCStats.mMaxSliceTime);
|
||||||
|
|
||||||
if (!sLastCCEndTime.IsNull()) {
|
if (!sLastCCEndTime.IsNull()) {
|
||||||
// TimeBetween returns milliseconds, but we want to report seconds.
|
TimeDuration timeBetween = TimeBetween(sLastCCEndTime, gCCStats.mBeginTime);
|
||||||
uint32_t timeBetween =
|
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_TIME_BETWEEN,
|
||||||
TimeBetween(sLastCCEndTime, gCCStats.mBeginTime) / 1000;
|
timeBetween.ToSeconds());
|
||||||
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_TIME_BETWEEN, timeBetween);
|
|
||||||
}
|
}
|
||||||
sLastCCEndTime = endCCTimeStamp;
|
sLastCCEndTime = endCCTimeStamp;
|
||||||
|
|
||||||
|
@ -1643,7 +1664,7 @@ void nsJSContext::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
|
||||||
if (StaticPrefs::javascript_options_mem_notify()) {
|
if (StaticPrefs::javascript_options_mem_notify()) {
|
||||||
const char16_t* kJSONFmt =
|
const char16_t* kJSONFmt =
|
||||||
u"{ \"timestamp\": %llu, "
|
u"{ \"timestamp\": %llu, "
|
||||||
u"\"duration\": %lu, "
|
u"\"duration\": %.f, "
|
||||||
u"\"max_slice_pause\": %lu, "
|
u"\"max_slice_pause\": %lu, "
|
||||||
u"\"total_slice_pause\": %lu, "
|
u"\"total_slice_pause\": %lu, "
|
||||||
u"\"max_finish_gc_duration\": %lu, "
|
u"\"max_finish_gc_duration\": %lu, "
|
||||||
|
@ -1670,10 +1691,10 @@ void nsJSContext::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
|
||||||
|
|
||||||
nsString json;
|
nsString json;
|
||||||
nsTextFormatter::ssprintf(
|
nsTextFormatter::ssprintf(
|
||||||
json, kJSONFmt, PR_Now(), ccNowDuration, gCCStats.mMaxSliceTime,
|
json, kJSONFmt, PR_Now(), ccNowDuration.ToMilliseconds(),
|
||||||
gCCStats.mTotalSliceTime, gCCStats.mMaxGCDuration,
|
gCCStats.mMaxSliceTime, gCCStats.mTotalSliceTime,
|
||||||
gCCStats.mMaxSkippableDuration, gCCStats.mSuspected,
|
gCCStats.mMaxGCDuration, gCCStats.mMaxSkippableDuration,
|
||||||
aResults.mVisitedRefCounted, aResults.mVisitedGCed,
|
gCCStats.mSuspected, aResults.mVisitedRefCounted, aResults.mVisitedGCed,
|
||||||
aResults.mFreedRefCounted, aResults.mFreedGCed, sCCollectedWaitingForGC,
|
aResults.mFreedRefCounted, aResults.mFreedGCed, sCCollectedWaitingForGC,
|
||||||
sCCollectedZonesWaitingForGC, sLikelyShortLivingObjectsNeedingGC,
|
sCCollectedZonesWaitingForGC, sLikelyShortLivingObjectsNeedingGC,
|
||||||
aResults.mForcedGC, sForgetSkippableBeforeCC,
|
aResults.mForcedGC, sForgetSkippableBeforeCC,
|
||||||
|
@ -1798,9 +1819,9 @@ static bool CCRunnerFired(TimeStamp aDeadline) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t ccDelay = kCCDelay;
|
static TimeDuration ccDelay = kCCDelay;
|
||||||
if (sCCLockedOut) {
|
if (sCCLockedOut) {
|
||||||
ccDelay = kCCDelay / 3;
|
ccDelay = kCCDelay / int64_t(3);
|
||||||
|
|
||||||
TimeStamp now = TimeStamp::Now();
|
TimeStamp now = TimeStamp::Now();
|
||||||
if (!sCCLockedOutTime) {
|
if (!sCCLockedOutTime) {
|
||||||
|
@ -1827,7 +1848,7 @@ static bool CCRunnerFired(TimeStamp aDeadline) {
|
||||||
// late timer fire, where we may begin to run the CC. Should run at least one
|
// late timer fire, where we may begin to run the CC. Should run at least one
|
||||||
// early timer fire to allow cleanup before the CC.
|
// early timer fire to allow cleanup before the CC.
|
||||||
int32_t numEarlyTimerFires =
|
int32_t numEarlyTimerFires =
|
||||||
std::max((int32_t)ccDelay / kCCSkippableDelay - 2, 1);
|
std::max(int32_t(ccDelay / kCCSkippableDelay) - 2, 1);
|
||||||
bool isLateTimerFire = sCCRunnerFireCount > numEarlyTimerFires;
|
bool isLateTimerFire = sCCRunnerFireCount > numEarlyTimerFires;
|
||||||
uint32_t suspected = nsCycleCollector_suspectedCount();
|
uint32_t suspected = nsCycleCollector_suspectedCount();
|
||||||
if (isLateTimerFire && ShouldTriggerCC(suspected)) {
|
if (isLateTimerFire && ShouldTriggerCC(suspected)) {
|
||||||
|
@ -2055,7 +2076,7 @@ void nsJSContext::MaybePokeCC() {
|
||||||
|
|
||||||
// Don't run consecutive CCs too often.
|
// Don't run consecutive CCs too often.
|
||||||
if (sCleanupsSinceLastGC && !sLastCCEndTime.IsNull()) {
|
if (sCleanupsSinceLastGC && !sLastCCEndTime.IsNull()) {
|
||||||
uint32_t sinceLastCCEnd = TimeUntilNow(sLastCCEndTime);
|
TimeDuration sinceLastCCEnd = TimeUntilNow(sLastCCEndTime);
|
||||||
if (sinceLastCCEnd < kCCDelay) {
|
if (sinceLastCCEnd < kCCDelay) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2065,7 +2086,7 @@ void nsJSContext::MaybePokeCC() {
|
||||||
// don't start a new cycle too soon.
|
// don't start a new cycle too soon.
|
||||||
if ((sCleanupsSinceLastGC > kMajorForgetSkippableCalls) &&
|
if ((sCleanupsSinceLastGC > kMajorForgetSkippableCalls) &&
|
||||||
!sLastForgetSkippableCycleEndTime.IsNull()) {
|
!sLastForgetSkippableCycleEndTime.IsNull()) {
|
||||||
uint32_t sinceLastForgetSkippableCycle =
|
TimeDuration sinceLastForgetSkippableCycle =
|
||||||
TimeUntilNow(sLastForgetSkippableCycleEndTime);
|
TimeUntilNow(sLastForgetSkippableCycleEndTime);
|
||||||
if (sinceLastForgetSkippableCycle < kTimeBetweenForgetSkippableCycles) {
|
if (sinceLastForgetSkippableCycle < kTimeBetweenForgetSkippableCycles) {
|
||||||
return;
|
return;
|
||||||
|
@ -2079,9 +2100,10 @@ void nsJSContext::MaybePokeCC() {
|
||||||
nsCycleCollector_dispatchDeferredDeletion();
|
nsCycleCollector_dispatchDeferredDeletion();
|
||||||
|
|
||||||
sCCRunner = IdleTaskRunner::Create(
|
sCCRunner = IdleTaskRunner::Create(
|
||||||
CCRunnerFired, "MaybePokeCC::CCRunnerFired", kCCSkippableDelay,
|
CCRunnerFired, "MaybePokeCC::CCRunnerFired",
|
||||||
kForgetSkippableSliceDuration, true, [] { return sShuttingDown; },
|
kCCSkippableDelay.ToMilliseconds(),
|
||||||
TaskCategory::GarbageCollection);
|
kForgetSkippableSliceDuration.ToMilliseconds(), true,
|
||||||
|
[] { return sShuttingDown; }, TaskCategory::GarbageCollection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2240,7 +2262,7 @@ static void DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress,
|
||||||
}
|
}
|
||||||
|
|
||||||
Telemetry::Accumulate(Telemetry::GC_IN_PROGRESS_MS,
|
Telemetry::Accumulate(Telemetry::GC_IN_PROGRESS_MS,
|
||||||
TimeBetween(sCurrentGCStartTime, TimeStamp::Now()));
|
TimeUntilNow(sCurrentGCStartTime).ToMilliseconds());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче