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); int32_t pref = Preferences::GetInt(aPrefName, -1);
// handle overflow and negative pref values // handle overflow and negative pref values
uint32_t max = (pref <= 0 || pref >= 0x1000) ? -1 : (uint32_t)pref * 1024 * 1024; CheckedInt<uint32_t> max = CheckedInt<uint32_t>(pref) * 1024 * 1024;
SetGCParameter(JSGC_MAX_BYTES, max); 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 static void
@ -2792,6 +2802,8 @@ nsJSContext::EnsureStatics()
Preferences::RegisterCallbackAndCall(SetMemoryMaxPrefChangedCallback, Preferences::RegisterCallbackAndCall(SetMemoryMaxPrefChangedCallback,
"javascript.options.mem.max"); "javascript.options.mem.max");
Preferences::RegisterCallbackAndCall(SetMemoryNurseryMaxPrefChangedCallback,
"javascript.options.mem.nursery.max_kb");
Preferences::RegisterCallbackAndCall(SetMemoryGCModePrefChangedCallback, Preferences::RegisterCallbackAndCall(SetMemoryGCModePrefChangedCallback,
"javascript.options.mem.gc_per_zone"); "javascript.options.mem.gc_per_zone");

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

@ -101,7 +101,11 @@ MOZ_ALWAYS_INLINE bool IsInsideNursery(const js::gc::Cell* cell);
namespace JS { namespace JS {
struct Zone; 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; const uint32_t DefaultNurseryBytes = 16 * js::gc::ChunkSize;
/* Default maximum heap size in bytes to pass to JS_NewContext(). */ /* Default maximum heap size in bytes to pass to JS_NewContext(). */

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

@ -140,7 +140,11 @@ class GCSchedulingTunables
*/ */
UnprotectedData<size_t> gcMaxBytes_; 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_; ActiveThreadData<size_t> gcMaxNurseryBytes_;
/* /*

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

@ -646,6 +646,11 @@ js::Nursery::collect(JS::gcreason::Reason reason)
// because gcBytes >= gcMaxBytes. // because gcBytes >= gcMaxBytes.
if (rt->gc.usage.gcBytes() >= rt->gc.tunables.gcMaxBytes()) if (rt->gc.usage.gcBytes() >= rt->gc.tunables.gcMaxBytes())
disable(); 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); endProfile(ProfileKey::Total);
minorGcCount_++; minorGcCount_++;
@ -924,6 +929,7 @@ js::Nursery::maybeResizeNursery(JS::gcreason::Reason reason, double promotionRat
{ {
static const double GrowThreshold = 0.05; static const double GrowThreshold = 0.05;
static const double ShrinkThreshold = 0.01; static const double ShrinkThreshold = 0.01;
unsigned newMaxNurseryChunks;
// Shrink the nursery to its minimum size of we ran out of memory or // Shrink the nursery to its minimum size of we ran out of memory or
// received a memory pressure event. // received a memory pressure event.
@ -932,10 +938,30 @@ js::Nursery::maybeResizeNursery(JS::gcreason::Reason reason, double promotionRat
return; 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) if (promotionRate > GrowThreshold)
growAllocableSpace(); growAllocableSpace();
else if (promotionRate < ShrinkThreshold && previousPromotionRate_ < ShrinkThreshold) else if (promotionRate < ShrinkThreshold && previousPromotionRate_ < ShrinkThreshold)
shrinkAllocableSpace(); shrinkAllocableSpace(1);
previousPromotionRate_ = promotionRate; previousPromotionRate_ = promotionRate;
} }
@ -947,13 +973,13 @@ js::Nursery::growAllocableSpace()
} }
void void
js::Nursery::shrinkAllocableSpace() js::Nursery::shrinkAllocableSpace(unsigned removeNumChunks)
{ {
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
if (runtime()->hasZealMode(ZealMode::GenerationalGC)) if (runtime()->hasZealMode(ZealMode::GenerationalGC))
return; return;
#endif #endif
updateNumChunks(Max(numChunks() - 1, 1u)); updateNumChunks(Max(numChunks() - removeNumChunks, 1u));
} }
void void

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

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

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

@ -1436,6 +1436,7 @@ pref("javascript.options.discardSystemSource", false);
// Comment 32 and Bug 613551. // Comment 32 and Bug 613551.
pref("javascript.options.mem.high_water_mark", 128); pref("javascript.options.mem.high_water_mark", 128);
pref("javascript.options.mem.max", -1); 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_per_zone", true);
pref("javascript.options.mem.gc_incremental", true); pref("javascript.options.mem.gc_incremental", true);
pref("javascript.options.mem.gc_incremental_slice_ms", 5); pref("javascript.options.mem.gc_incremental_slice_ms", 5);