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:
Paul Bone 2019-02-27 03:36:54 +00:00
Родитель 4b869d9db6
Коммит 1913e73f45
4 изменённых файлов: 61 добавлений и 3 удалений

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

@ -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_; }