зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1506761 - Add a fraction threshold for collecting the nursery r=sfink
We collect the nursery in idle time if there is less than 256KB of space remaining. However when the nursery is small this doesn't make sense, so add a percentage-based threshold to be used when the nursery is small. Differential Revision: https://phabricator.services.mozilla.com/D20247 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
4b869d9db6
Коммит
1913e73f45
|
@ -283,6 +283,16 @@ typedef enum JSGCParamKey {
|
|||
* Pref: None
|
||||
*/
|
||||
JSGC_PRETENURE_GROUP_THRESHOLD = 29,
|
||||
|
||||
/**
|
||||
* Attempt to run a minor GC in the idle time if the free space falls
|
||||
* below this percentage (from 0 to 99).
|
||||
*
|
||||
* Default: 25
|
||||
* Pref: None
|
||||
*/
|
||||
JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_PERCENT = 30,
|
||||
|
||||
} JSGCParamKey;
|
||||
|
||||
/*
|
||||
|
|
|
@ -347,6 +347,9 @@ static const bool CompactingEnabled = true;
|
|||
static const uint32_t NurseryFreeThresholdForIdleCollection =
|
||||
Nursery::NurseryChunkUsableSize / 4;
|
||||
|
||||
/* JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_PERCENT */
|
||||
static const float NurseryFreeThresholdForIdleCollectionFraction = 0.25f;
|
||||
|
||||
/* JSGC_PRETENURE_THRESHOLD */
|
||||
static const float PretenureThreashold = 0.6f;
|
||||
|
||||
|
@ -1476,6 +1479,12 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value,
|
|||
}
|
||||
nurseryFreeThresholdForIdleCollection_ = value;
|
||||
break;
|
||||
case JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_PERCENT:
|
||||
if (value == 0 || value > 100) {
|
||||
return false;
|
||||
}
|
||||
nurseryFreeThresholdForIdleCollectionFraction_ = value / 100.0f;
|
||||
break;
|
||||
case JSGC_PRETENURE_THRESHOLD: {
|
||||
// 100 disables pretenuring
|
||||
if (value == 0 || value > 100) {
|
||||
|
@ -1578,6 +1587,8 @@ GCSchedulingTunables::GCSchedulingTunables()
|
|||
maxEmptyChunkCount_(TuningDefaults::MaxEmptyChunkCount),
|
||||
nurseryFreeThresholdForIdleCollection_(
|
||||
TuningDefaults::NurseryFreeThresholdForIdleCollection),
|
||||
nurseryFreeThresholdForIdleCollectionFraction_(
|
||||
TuningDefaults::NurseryFreeThresholdForIdleCollectionFraction),
|
||||
pretenureThreshold_(TuningDefaults::PretenureThreashold),
|
||||
pretenureGroupThreshold_(TuningDefaults::PretenureGroupThreshold) {}
|
||||
|
||||
|
@ -1661,6 +1672,10 @@ void GCSchedulingTunables::resetParameter(JSGCParamKey key,
|
|||
nurseryFreeThresholdForIdleCollection_ =
|
||||
TuningDefaults::NurseryFreeThresholdForIdleCollection;
|
||||
break;
|
||||
case JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_PERCENT:
|
||||
nurseryFreeThresholdForIdleCollectionFraction_ =
|
||||
TuningDefaults::NurseryFreeThresholdForIdleCollectionFraction;
|
||||
break;
|
||||
case JSGC_PRETENURE_THRESHOLD:
|
||||
pretenureThreshold_ = TuningDefaults::PretenureThreashold;
|
||||
break;
|
||||
|
|
|
@ -698,8 +698,35 @@ inline void js::Nursery::endProfile(ProfileKey key) {
|
|||
}
|
||||
|
||||
bool js::Nursery::shouldCollect() const {
|
||||
uint32_t threshold = tunables().nurseryFreeThresholdForIdleCollection();
|
||||
return !isEmpty() && (minorGCRequested() || freeSpace() < threshold);
|
||||
if (minorGCRequested()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool belowBytesThreshold =
|
||||
freeSpace() < tunables().nurseryFreeThresholdForIdleCollection();
|
||||
bool belowFractionThreshold =
|
||||
float(freeSpace()) / float(capacity()) <
|
||||
tunables().nurseryFreeThresholdForIdleCollectionFraction();
|
||||
|
||||
// We want to use belowBytesThreshold when the nursery is sufficiently large,
|
||||
// and belowFractionThreshold when it's small.
|
||||
//
|
||||
// When the nursery is small then belowBytesThreshold is a lower threshold
|
||||
// (triggered earlier) than belowFractionThreshold. So if the fraction
|
||||
// threshold is true, the bytes one will be true also. The opposite is true
|
||||
// when the nursery is large.
|
||||
//
|
||||
// Therefore, by the time we cross the threshold we care about, we've already
|
||||
// crossed the other one, and we can boolean AND to use either condition
|
||||
// without encoding any "is the nursery big/small" test/threshold. The point
|
||||
// at which they cross is when the nursery is: BytesThreshold /
|
||||
// FractionThreshold large.
|
||||
//
|
||||
// With defaults that's:
|
||||
//
|
||||
// 1MB = 256KB / 0.25
|
||||
//
|
||||
return belowBytesThreshold && belowFractionThreshold;
|
||||
}
|
||||
|
||||
static inline bool IsFullStoreBufferReason(JS::GCReason reason) {
|
||||
|
|
|
@ -427,11 +427,14 @@ class GCSchedulingTunables {
|
|||
|
||||
/*
|
||||
* JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION
|
||||
* JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_FRACTION
|
||||
*
|
||||
* Attempt to run a minor GC in the idle time if the free space falls
|
||||
* below this threshold.
|
||||
* below this threshold. The absolute threshold is used when the nursery is
|
||||
* large and the percentage when it is small. See Nursery::shouldCollect()
|
||||
*/
|
||||
UnprotectedData<uint32_t> nurseryFreeThresholdForIdleCollection_;
|
||||
UnprotectedData<float> nurseryFreeThresholdForIdleCollectionFraction_;
|
||||
|
||||
/*
|
||||
* JSGC_PRETENURE_THRESHOLD
|
||||
|
@ -488,6 +491,9 @@ class GCSchedulingTunables {
|
|||
uint32_t nurseryFreeThresholdForIdleCollection() const {
|
||||
return nurseryFreeThresholdForIdleCollection_;
|
||||
}
|
||||
float nurseryFreeThresholdForIdleCollectionFraction() const {
|
||||
return nurseryFreeThresholdForIdleCollectionFraction_;
|
||||
}
|
||||
|
||||
bool attemptPretenuring() const { return pretenureThreshold_ < 1.0f; }
|
||||
float pretenureThreshold() const { return pretenureThreshold_; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче