Bug 1497873 - Add a kind-of goal seeking herustic for nursery resizing r=jonco

Also allow the nursery to shrink up to half it's current size, previously
it'd be one chunk at a time.  Growing is still capped at twice the current
size.  These limits tend to prevent it changing too dramantically for small
changes in allocation patterns.

Differential Revision: https://phabricator.services.mozilla.com/D17594

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Paul Bone 2019-01-29 02:04:10 +00:00
Родитель 10b064b867
Коммит 362857a4e8
2 изменённых файлов: 27 добавлений и 7 удалений

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

@ -1120,8 +1120,10 @@ MOZ_ALWAYS_INLINE void js::Nursery::setStartPosition() {
}
void js::Nursery::maybeResizeNursery(JS::GCReason reason) {
static const double GrowThreshold = 0.03;
static const double ShrinkThreshold = 0.01;
static const float GrowThreshold = 0.03f;
static const float ShrinkThreshold = 0.01f;
static const float PromotionGoal = (GrowThreshold + ShrinkThreshold) / 2.0f;
unsigned newMaxNurseryChunks;
// Shrink the nursery to its minimum size of we ran out of memory or
@ -1157,15 +1159,33 @@ void js::Nursery::maybeResizeNursery(JS::GCReason reason) {
const float promotionRate =
float(previousGC.tenuredBytes) / float(previousGC.nurseryCapacity);
/*
* Object lifetimes arn't going to behave linearly, but a better
* relationship that works for all programs and can be predicted in
* advance doesn't exist.
*/
const float factor = promotionRate / PromotionGoal;
const unsigned newChunkCount = round(float(maxChunkCount()) * factor);
// If one of these conditions is true then we always shrink or grow the
// nursery. This way the thresholds still have an effect even if the goal
// seeking says the current size is ideal.
if (promotionRate > GrowThreshold) {
growAllocableSpace();
unsigned lowLimit = maxChunkCount() + 1;
unsigned highLimit = Min(chunkCountLimit(), maxChunkCount() * 2);
growAllocableSpace(Min(Max(newChunkCount, lowLimit), highLimit));
} else if (maxChunkCount() > 1 && promotionRate < ShrinkThreshold) {
shrinkAllocableSpace(maxChunkCount() - 1);
unsigned lowLimit = Max(1u, maxChunkCount() / 2);
unsigned highLimit = maxChunkCount() - 1u;
shrinkAllocableSpace(Max(Min(newChunkCount, highLimit), lowLimit));
}
}
void js::Nursery::growAllocableSpace() {
maxChunkCount_ = Min(maxChunkCount() * 2, chunkCountLimit());
void js::Nursery::growAllocableSpace(unsigned newCount) {
MOZ_ASSERT(newCount >= currentChunk_);
maxChunkCount_ = newCount;
}
void js::Nursery::freeChunksFrom(unsigned firstFreeChunk) {

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

@ -598,7 +598,7 @@ class Nursery {
/* Change the allocable space provided by the nursery. */
void maybeResizeNursery(JS::GCReason reason);
void growAllocableSpace();
void growAllocableSpace(unsigned newCount);
void shrinkAllocableSpace(unsigned newCount);
void minimizeAllocableSpace();