From 3c56bb4f01933210785c48e5b28bcc0ec0382a3e Mon Sep 17 00:00:00 2001 From: Paul Bone Date: Fri, 28 Jul 2017 15:49:32 +1000 Subject: [PATCH] Bug 1384010 - Create prefs for allocation threshold factors. r=jonco --HG-- extra : rebase_source : 61ad2bd2ef8c07be5ffafb8518800f50126a4383 --- dom/base/nsJSEnvironment.cpp | 6 ++++++ js/src/gc/GCRuntime.h | 13 +++++++++++-- js/src/jsapi.h | 17 +++++++++++++++++ js/src/jsgc.cpp | 29 +++++++++++++++++++++++++++++ modules/libpref/init/all.js | 6 ++++++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 7262fef9aa77..843e9e9b768d 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -2682,6 +2682,12 @@ nsJSContext::EnsureStatics() Preferences::RegisterCallbackAndCall(SetMemoryPrefChangedCallbackInt, "javascript.options.mem.gc_allocation_threshold_mb", (void *)JSGC_ALLOCATION_THRESHOLD); + Preferences::RegisterCallbackAndCall(SetMemoryPrefChangedCallbackInt, + "javascript.options.mem.gc_allocation_threshold_factor", + (void *)JSGC_ALLOCATION_THRESHOLD_FACTOR); + Preferences::RegisterCallbackAndCall(SetMemoryPrefChangedCallbackInt, + "javascript.options.mem.gc_allocation_threshold_factor_avoid_interrupt", + (void *)JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT); Preferences::RegisterCallbackAndCall(SetIncrementalCCPrefChangedCallback, "dom.cycle_collector.incremental"); diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index 647a8d2b867f..23ac1d65a3a3 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -162,9 +162,18 @@ class GCSchedulingTunables */ ActiveThreadOrGCTaskData gcZoneAllocThresholdBase_; - /* Fraction of threshold.gcBytes() which triggers an incremental GC. */ + /* + * JSGC_ALLOCATION_THRESHOLD_FACTOR + * + * Fraction of threshold.gcBytes() which triggers an incremental GC. + */ UnprotectedData zoneAllocThresholdFactor_; - /* The same except when doing so would interrupt an already running GC. */ + + /* + * JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT + * + * The same except when doing so would interrupt an already running GC. + */ UnprotectedData zoneAllocThresholdFactorAvoidInterrupt_; /* diff --git a/js/src/jsapi.h b/js/src/jsapi.h index e64876f8ce79..8e81ec596c91 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1973,6 +1973,23 @@ typedef enum JSGCParamKey { * Default: RefreshFrameSlicesEnabled */ JSGC_REFRESH_FRAME_SLICES_ENABLED = 24, + + /** + * Factor for triggering a GC based on JSGC_ALLOCATION_THRESHOLD + * + * Default: ZoneAllocThresholdFactorDefault + * Pref: None + */ + JSGC_ALLOCATION_THRESHOLD_FACTOR = 25, + + /** + * Factor for triggering a GC based on JSGC_ALLOCATION_THRESHOLD. + * Used if another GC (in different zones) is already running. + * + * Default: ZoneAllocThresholdFactorAvoidInterruptDefault + * Pref: None + */ + JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT = 26, } JSGCParamKey; extern JS_PUBLIC_API(void) diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index b0927803ef7b..a9947570d31d 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -278,7 +278,11 @@ namespace TuningDefaults { /* JSGC_ALLOCATION_THRESHOLD */ static const size_t GCZoneAllocThresholdBase = 30 * 1024 * 1024; + + /* JSGC_ALLOCATION_THRESHOLD_FACTOR */ static const float ZoneAllocThresholdFactor = 0.9f; + + /* JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT */ static const float ZoneAllocThresholdFactorAvoidInterrupt = 0.9f; /* no parameter */ @@ -1342,6 +1346,20 @@ GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value, const AutoL case JSGC_ALLOCATION_THRESHOLD: gcZoneAllocThresholdBase_ = value * 1024 * 1024; break; + case JSGC_ALLOCATION_THRESHOLD_FACTOR: { + float newFactor = value / 100.0; + if (newFactor <= 0.1 || newFactor > 1.0) + return false; + zoneAllocThresholdFactor_ = newFactor; + break; + } + case JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT: { + float newFactor = value / 100.0; + if (newFactor <= 0.1 || newFactor > 1.0) + return false; + zoneAllocThresholdFactorAvoidInterrupt_ = newFactor; + break; + } case JSGC_MIN_EMPTY_CHUNK_COUNT: setMinEmptyChunkCount(value); break; @@ -1488,6 +1506,13 @@ GCSchedulingTunables::resetParameter(JSGCParamKey key, const AutoLockGC& lock) case JSGC_ALLOCATION_THRESHOLD: gcZoneAllocThresholdBase_ = TuningDefaults::GCZoneAllocThresholdBase; break; + case JSGC_ALLOCATION_THRESHOLD_FACTOR: + zoneAllocThresholdFactor_ = TuningDefaults::ZoneAllocThresholdFactor; + break; + case JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT: + zoneAllocThresholdFactorAvoidInterrupt_ = + TuningDefaults::ZoneAllocThresholdFactorAvoidInterrupt; + break; case JSGC_MIN_EMPTY_CHUNK_COUNT: setMinEmptyChunkCount(TuningDefaults::MinEmptyChunkCount); break; @@ -1548,6 +1573,10 @@ GCRuntime::getParameter(JSGCParamKey key, const AutoLockGC& lock) return tunables.isDynamicMarkSliceEnabled(); case JSGC_ALLOCATION_THRESHOLD: return tunables.gcZoneAllocThresholdBase() / 1024 / 1024; + case JSGC_ALLOCATION_THRESHOLD_FACTOR: + return uint32_t(tunables.zoneAllocThresholdFactor() * 100); + case JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT: + return uint32_t(tunables.zoneAllocThresholdFactorAvoidInterrupt() * 100); case JSGC_MIN_EMPTY_CHUNK_COUNT: return tunables.minEmptyChunkCount(lock); case JSGC_MAX_EMPTY_CHUNK_COUNT: diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 73e42388b7f2..28fa6762686b 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1520,6 +1520,12 @@ pref("javascript.options.mem.gc_refresh_frame_slices_enabled", true); // JSGC_ALLOCATION_THRESHOLD pref("javascript.options.mem.gc_allocation_threshold_mb", 30); +// JSGC_ALLOCATION_THRESHOLD_FACTOR +pref("javascript.options.mem.gc_allocation_threshold_factor", 90); + +// JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT +pref("javascript.options.mem.gc_allocation_threshold_factor_avoid_interrupt", 90); + // JSGC_MIN_EMPTY_CHUNK_COUNT pref("javascript.options.mem.gc_min_empty_chunk_count", 1);