зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1380768 (part 2) - Add a pref for nursery size, r=sfink.
This commit is contained in:
Родитель
07ea7264d8
Коммит
70b304d94b
|
@ -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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче