Bug 1380768 (part 2) - Add a pref for nursery size, r=sfink.

This commit is contained in:
Paul Bone 2017-07-21 14:34:46 +10:00
Родитель 07ea7264d8
Коммит 70b304d94b
6 изменённых файлов: 55 добавлений и 8 удалений

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

@ -2598,8 +2598,18 @@ SetMemoryMaxPrefChangedCallback(const char* aPrefName, void* aClosure)
{
int32_t pref = Preferences::GetInt(aPrefName, -1);
// handle overflow and negative pref values
uint32_t max = (pref <= 0 || pref >= 0x1000) ? -1 : (uint32_t)pref * 1024 * 1024;
SetGCParameter(JSGC_MAX_BYTES, max);
CheckedInt<uint32_t> max = CheckedInt<uint32_t>(pref) * 1024 * 1024;
SetGCParameter(JSGC_MAX_BYTES, max.isValid() ? max.value() : -1);
}
static void
SetMemoryNurseryMaxPrefChangedCallback(const char* aPrefName, void* aClosure)
{
int32_t pref = Preferences::GetInt(aPrefName, -1);
// handle overflow and negative pref values
CheckedInt<uint32_t> max = CheckedInt<uint32_t>(pref) * 1024;
SetGCParameter(JSGC_MAX_NURSERY_BYTES,
max.isValid() ? max.value() : JS::DefaultNurseryBytes);
}
static void
@ -2792,6 +2802,8 @@ nsJSContext::EnsureStatics()
Preferences::RegisterCallbackAndCall(SetMemoryMaxPrefChangedCallback,
"javascript.options.mem.max");
Preferences::RegisterCallbackAndCall(SetMemoryNurseryMaxPrefChangedCallback,
"javascript.options.mem.nursery.max_kb");
Preferences::RegisterCallbackAndCall(SetMemoryGCModePrefChangedCallback,
"javascript.options.mem.gc_per_zone");

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

@ -101,7 +101,11 @@ MOZ_ALWAYS_INLINE bool IsInsideNursery(const js::gc::Cell* cell);
namespace JS {
struct Zone;
/* Default size for the generational nursery in bytes. */
/*
* Default size for the generational nursery in bytes.
* This is the initial nursery size, when running in the browser this is
* updated by JS_SetGCParameter().
*/
const uint32_t DefaultNurseryBytes = 16 * js::gc::ChunkSize;
/* Default maximum heap size in bytes to pass to JS_NewContext(). */

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

@ -140,7 +140,11 @@ class GCSchedulingTunables
*/
UnprotectedData<size_t> gcMaxBytes_;
/* Maximum nursery size for each zone group. */
/*
* Maximum nursery size for each zone group.
* Initially DefaultNurseryBytes and can be set by
* javascript.options.mem.nursery.max_kb
*/
ActiveThreadData<size_t> gcMaxNurseryBytes_;
/*

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

@ -646,6 +646,11 @@ js::Nursery::collect(JS::gcreason::Reason reason)
// because gcBytes >= gcMaxBytes.
if (rt->gc.usage.gcBytes() >= rt->gc.tunables.gcMaxBytes())
disable();
// Disable the nursery if the user changed the configuration setting. The
// nursery can only be re-enabled by resetting the configurationa and
// restarting firefox.
if (maxNurseryChunks_ == 0)
disable();
endProfile(ProfileKey::Total);
minorGcCount_++;
@ -924,6 +929,7 @@ js::Nursery::maybeResizeNursery(JS::gcreason::Reason reason, double promotionRat
{
static const double GrowThreshold = 0.05;
static const double ShrinkThreshold = 0.01;
unsigned newMaxNurseryChunks;
// Shrink the nursery to its minimum size of we ran out of memory or
// received a memory pressure event.
@ -932,10 +938,30 @@ js::Nursery::maybeResizeNursery(JS::gcreason::Reason reason, double promotionRat
return;
}
#ifdef JS_GC_ZEAL
// This zeal mode disabled nursery resizing.
if (runtime()->hasZealMode(ZealMode::GenerationalGC))
return;
#endif
newMaxNurseryChunks = runtime()->gc.tunables.gcMaxNurseryBytes() >> ChunkShift;
if (newMaxNurseryChunks != maxNurseryChunks_) {
maxNurseryChunks_ = newMaxNurseryChunks;
/* The configured maximum nursery size is changing */
int extraChunks = numChunks() - newMaxNurseryChunks;
if (extraChunks > 0) {
/* We need to shrink the nursery */
shrinkAllocableSpace(extraChunks);
previousPromotionRate_ = promotionRate;
return;
}
}
if (promotionRate > GrowThreshold)
growAllocableSpace();
else if (promotionRate < ShrinkThreshold && previousPromotionRate_ < ShrinkThreshold)
shrinkAllocableSpace();
shrinkAllocableSpace(1);
previousPromotionRate_ = promotionRate;
}
@ -947,13 +973,13 @@ js::Nursery::growAllocableSpace()
}
void
js::Nursery::shrinkAllocableSpace()
js::Nursery::shrinkAllocableSpace(unsigned removeNumChunks)
{
#ifdef JS_GC_ZEAL
if (runtime()->hasZealMode(ZealMode::GenerationalGC))
return;
#endif
updateNumChunks(Max(numChunks() - 1, 1u));
updateNumChunks(Max(numChunks() - removeNumChunks, 1u));
}
void

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

@ -468,7 +468,7 @@ class Nursery
/* Change the allocable space provided by the nursery. */
void maybeResizeNursery(JS::gcreason::Reason reason, double promotionRate);
void growAllocableSpace();
void shrinkAllocableSpace();
void shrinkAllocableSpace(unsigned removeNumChunks);
void minimizeAllocableSpace();
/* Profile recording and printing. */

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

@ -1436,6 +1436,7 @@ pref("javascript.options.discardSystemSource", false);
// Comment 32 and Bug 613551.
pref("javascript.options.mem.high_water_mark", 128);
pref("javascript.options.mem.max", -1);
pref("javascript.options.mem.nursery.max_kb", -1);
pref("javascript.options.mem.gc_per_zone", true);
pref("javascript.options.mem.gc_incremental", true);
pref("javascript.options.mem.gc_incremental_slice_ms", 5);