Bug 1449833 - Use StaticPrefs in nsJSEnvironment.cpp. r=sfink
MozReview-Commit-ID: GELa2l1ZonV
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -50,16 +50,17 @@
#include "js/SliceBudget.h"
#include "nsIArray.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "WrapperFactory.h"
#include "nsGlobalWindow.h"
#include "mozilla/AutoRestore.h"
#include "mozilla/MainThreadIdlePeriod.h"
+#include "mozilla/StaticPrefs.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/DOMException.h"
#include "mozilla/dom/DOMExceptionBinding.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ErrorEvent.h"
#include "mozilla/dom/FetchUtil.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/CycleCollectedJSRuntime.h"
@@ -105,20 +106,16 @@ const size_t gStackSize = 8192;
#define NS_SHRINK_GC_BUFFERS_DELAY 4000 // ms
// The amount of time we wait from the first request to GC to actually
// doing the first GC.
#define NS_FIRST_GC_DELAY 10000 // ms
#define NS_FULL_GC_DELAY 60000 // ms
-// The default amount of time to wait from the user being idle to starting a
-// shrinking GC.
-#define NS_DEAULT_INACTIVE_GC_DELAY 300000 // ms
-
// Maximum amount of time that should elapse between incremental GC slices
#define NS_INTERSLICE_GC_DELAY 100 // ms
// The amount of time we wait between a request to CC (after GC ran)
// and doing the actual CC.
#define NS_CC_DELAY 6000 // ms
#define NS_CC_SKIPPABLE_DELAY 250 // ms
@@ -178,18 +175,16 @@ static bool sHasRunGC;
// we're waiting for a slow page to load. IOW, this count may be 0
// even when there are pending loads.
static uint32_t sPendingLoadCount;
static bool sLoadingInProgress;
static uint32_t sCCollectedWaitingForGC;
static uint32_t sCCollectedZonesWaitingForGC;
static uint32_t sLikelyShortLivingObjectsNeedingGC;
-static bool sPostGCEventsToConsole;
-static bool sPostGCEventsToObserver;
static int32_t sCCRunnerFireCount = 0;
static uint32_t sMinForgetSkippableTime = UINT32_MAX;
static uint32_t sMaxForgetSkippableTime = 0;
static uint32_t sTotalForgetSkippableTime = 0;
static uint32_t sRemovedPurples = 0;
static uint32_t sForgetSkippableBeforeCC = 0;
static uint32_t sPreviousSuspectedCount = 0;
static uint32_t sCleanupsSinceLastGC = UINT32_MAX;
@@ -200,28 +195,20 @@ static bool sIncrementalCC = false;
static int32_t sActiveIntersliceGCBudget = 5; // ms;
static PRTime sFirstCollectionTime;
static bool sIsInitialized;
static bool sDidShutdown;
static bool sShuttingDown;
-// nsJSEnvironmentObserver observes the memory-pressure notifications
-// and forces a garbage collection and cycle collection when it happens, if
-// the appropriate pref is set.
-
-static bool sGCOnMemoryPressure;
-
// nsJSEnvironmentObserver observes the user-interaction-inactive notifications
// and triggers a shrinking a garbage collection if the user is still inactive
// after NS_SHRINKING_GC_DELAY ms later, if the appropriate pref is set.
-static bool sCompactOnUserInactive;
-static uint32_t sCompactOnUserInactiveDelay = NS_DEAULT_INACTIVE_GC_DELAY;
static bool sIsCompactingOnUserInactive = false;
static TimeDuration sGCUnnotifiedTotalTime;
static const char*
ProcessNameForCollectorLog()
{
return XRE_GetProcessType() == GeckoProcessType_Default ?
@@ -324,35 +311,35 @@ public:
NS_IMPL_ISUPPORTS(nsJSEnvironmentObserver, nsIObserver)
NS_IMETHODIMP
nsJSEnvironmentObserver::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
if (!nsCRT::strcmp(aTopic, "memory-pressure")) {
- if (sGCOnMemoryPressure) {
- if(StringBeginsWith(nsDependentString(aData),
- NS_LITERAL_STRING("low-memory-ongoing"))) {
+ if (StaticPrefs::javascript_options_gc_on_memory_pressure()) {
+ if (StringBeginsWith(nsDependentString(aData),
+ NS_LITERAL_STRING("low-memory-ongoing"))) {
// Don't GC/CC if we are in an ongoing low-memory state since its very
// slow and it likely won't help us anyway.
return NS_OK;
}
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
nsJSContext::NonIncrementalGC,
nsJSContext::ShrinkingGC);
nsJSContext::CycleCollectNow();
if (NeedsGCAfterCC()) {
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE,
nsJSContext::NonIncrementalGC,
nsJSContext::ShrinkingGC);
}
}
} else if (!nsCRT::strcmp(aTopic, "user-interaction-inactive")) {
- if (sCompactOnUserInactive) {
+ if (StaticPrefs::javascript_options_compact_on_user_inactive()) {
nsJSContext::PokeShrinkingGC();
}
} else if (!nsCRT::strcmp(aTopic, "user-interaction-active")) {
nsJSContext::KillShrinkingGCTimer();
if (sIsCompactingOnUserInactive) {
AutoJSAPI jsapi;
jsapi.Init();
JS::AbortIncrementalGC(jsapi.cx());
@@ -593,18 +580,16 @@ PrintWinCodebaseOuter(nsGlobalWindowOute
void
DumpString(const nsAString &str)
{
printf("%s\n", NS_ConvertUTF16toUTF8(str).get());
}
#endif
-#define JS_OPTIONS_DOT_STR "javascript.options."
-
nsJSContext::nsJSContext(bool aGCOnDestruction,
nsIScriptGlobalObject* aGlobalObject)
: mWindowProxy(nullptr)
, mGCOnDestruction(aGCOnDestruction)
, mGlobalObjectRef(aGlobalObject)
{
EnsureStatics();
@@ -1692,17 +1677,17 @@ nsJSContext::EndCycleCollectionCallback(
sMaxForgetSkippableTime / PR_USEC_PER_MSEC);
PRTime delta = GetCollectionTimeDelta();
uint32_t cleanups = sForgetSkippableBeforeCC ? sForgetSkippableBeforeCC : 1;
uint32_t minForgetSkippableTime = (sMinForgetSkippableTime == UINT32_MAX)
? 0 : sMinForgetSkippableTime;
- if (sPostGCEventsToConsole || gCCStats.mFile) {
+ if (StaticPrefs::javascript_options_mem_log() || gCCStats.mFile) {
nsCString mergeMsg;
if (aResults.mMergedZones) {
mergeMsg.AssignLiteral(" merged");
}
nsCString gcMsg;
if (aResults.mForcedGC) {
gcMsg.AssignLiteral(", forced a GC");
@@ -1722,29 +1707,29 @@ nsJSContext::EndCycleCollectionCallback(
gcMsg.get(),
sForgetSkippableBeforeCC,
minForgetSkippableTime / PR_USEC_PER_MSEC,
sMaxForgetSkippableTime / PR_USEC_PER_MSEC,
(sTotalForgetSkippableTime / cleanups) /
PR_USEC_PER_MSEC,
sTotalForgetSkippableTime / PR_USEC_PER_MSEC,
gCCStats.mMaxSkippableDuration, sRemovedPurples);
- if (sPostGCEventsToConsole) {
+ if (StaticPrefs::javascript_options_mem_log()) {
nsCOMPtr<nsIConsoleService> cs =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (cs) {
cs->LogStringMessage(msg.get());
}
}
if (gCCStats.mFile) {
fprintf(gCCStats.mFile, "%s\n", NS_ConvertUTF16toUTF8(msg).get());
}
}
- if (sPostGCEventsToObserver) {
+ if (StaticPrefs::javascript_options_mem_notify()) {
const char16_t* kJSONFmt =
u"{ \"timestamp\": %llu, "
u"\"duration\": %lu, "
u"\"max_slice_pause\": %lu, "
u"\"total_slice_pause\": %lu, "
u"\"max_finish_gc_duration\": %lu, "
u"\"max_sync_skippable_duration\": %lu, "
u"\"suspected\": %lu, "
@@ -2170,17 +2155,17 @@ void
nsJSContext::PokeShrinkingGC()
{
if (sShrinkingGCTimer || sShuttingDown) {
return;
}
NS_NewTimerWithFuncCallback(&sShrinkingGCTimer,
ShrinkingGCTimerFired, nullptr,
- sCompactOnUserInactiveDelay,
+ StaticPrefs::javascript_options_compact_on_user_inactive_delay(),
nsITimer::TYPE_ONE_SHOT_LOW_PRIORITY,
"ShrinkingGCTimerFired",
SystemGroup::EventTargetFor(TaskCategory::GarbageCollection));
}
// static
void
nsJSContext::MaybePokeCC()
@@ -2312,32 +2297,33 @@ DOMGCSliceCallback(JSContext* aCx, JS::G
// Prevent cycle collections and shrinking during incremental GC.
sCCLockedOut = true;
break;
}
case JS::GC_CYCLE_END: {
PRTime delta = GetCollectionTimeDelta();
- if (sPostGCEventsToConsole) {
+ if (StaticPrefs::javascript_options_mem_log()) {
nsString gcstats;
gcstats.Adopt(aDesc.formatSummaryMessage(aCx));
nsAutoString prefix;
nsTextFormatter::ssprintf(prefix, u"GC(T+%.1f)[%s-%i] ",
double(delta) / PR_USEC_PER_SEC,
ProcessNameForCollectorLog(), getpid());
nsString msg = prefix + gcstats;
nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (cs) {
cs->LogStringMessage(msg.get());
}
}
if (!sShuttingDown) {
- if (sPostGCEventsToObserver || Telemetry::CanRecordExtended()) {
+ if (StaticPrefs::javascript_options_mem_notify() ||
+ Telemetry::CanRecordExtended()) {
nsString json;
json.Adopt(aDesc.formatJSON(aCx, PR_Now()));
RefPtr<NotifyGCEndRunnable> notify = new NotifyGCEndRunnable(json);
SystemGroup::Dispatch(TaskCategory::GarbageCollection, notify.forget());
}
}
sCCLockedOut = false;
@@ -2399,17 +2385,17 @@ DOMGCSliceCallback(JSContext* aCx, JS::G
[]{ return sShuttingDown; },
TaskCategory::GarbageCollection);
}
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
nsCycleCollector_dispatchDeferredDeletion();
}
- if (sPostGCEventsToConsole) {
+ if (StaticPrefs::javascript_options_mem_log()) {
nsString gcstats;
gcstats.Adopt(aDesc.formatSliceMessage(aCx));
nsAutoString prefix;
nsTextFormatter::ssprintf(prefix, u"[%s-%i] ",
ProcessNameForCollectorLog(), getpid());
nsString msg = prefix + gcstats;
nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (cs) {
@@ -2456,17 +2442,16 @@ mozilla::dom::StartupJSEnvironment()
sCCLockedOutTime = 0;
sLastCCEndTime = TimeStamp();
sHasRunGC = false;
sPendingLoadCount = 0;
sLoadingInProgress = false;
sCCollectedWaitingForGC = 0;
sCCollectedZonesWaitingForGC = 0;
sLikelyShortLivingObjectsNeedingGC = 0;
- sPostGCEventsToConsole = false;
sNeedsFullCC = false;
sNeedsFullGC = true;
sNeedsGCAfterCC = false;
sIsInitialized = false;
sDidShutdown = false;
sShuttingDown = false;
gCCStats.Init();
}
@@ -2770,33 +2755,16 @@ nsJSContext::EnsureStatics()
"javascript.options.mem.gc_max_empty_chunk_count",
(void *)JSGC_MAX_EMPTY_CHUNK_COUNT);
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs) {
MOZ_CRASH();
}
- Preferences::AddBoolVarCache(&sGCOnMemoryPressure,
- "javascript.options.gc_on_memory_pressure",
- true);
-
- Preferences::AddBoolVarCache(&sCompactOnUserInactive,
- "javascript.options.compact_on_user_inactive",
- true);
-
- Preferences::AddUintVarCache(&sCompactOnUserInactiveDelay,
- "javascript.options.compact_on_user_inactive_delay",
- NS_DEAULT_INACTIVE_GC_DELAY);
-
- Preferences::AddBoolVarCache(&sPostGCEventsToConsole,
- JS_OPTIONS_DOT_STR "mem.log");
- Preferences::AddBoolVarCache(&sPostGCEventsToObserver,
- JS_OPTIONS_DOT_STR "mem.notify");
-
nsIObserver* observer = new nsJSEnvironmentObserver();
obs->AddObserver(observer, "memory-pressure", false);
obs->AddObserver(observer, "user-interaction-inactive", false);
obs->AddObserver(observer, "user-interaction-active", false);
obs->AddObserver(observer, "quit-application", false);
obs->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
sIsInitialized = true;
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -363,20 +363,16 @@ pref("geo.enabled", true);
// content sink control -- controls responsiveness during page load
// see https://bugzilla.mozilla.org/show_bug.cgi?id=481566#c9
//pref("content.sink.enable_perf_mode", 2); // 0 - switch, 1 - interactive, 2 - perf
//pref("content.sink.pending_event_mode", 0);
//pref("content.sink.perf_deflect_count", 1000000);
//pref("content.sink.perf_parse_time", 50000000);
-// Disable the JS engine's gc on memory pressure, since we do one in the mobile
-// browser (bug 669346).
-pref("javascript.options.gc_on_memory_pressure", false);
-
pref("javascript.options.mem.high_water_mark", 32);
pref("dom.max_chrome_script_run_time", 0); // disable slow script dialog for chrome
pref("dom.max_script_run_time", 20);
// Absolute path to the devtools unix domain socket file used
// to communicate with a usb cable via adb forward.
pref("devtools.debugger.unix-domain-socket", "/data/data/@ANDROID_PACKAGE_NAME@/firefox-debugger-socket");
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -101,16 +101,71 @@ VARCACHE_PREF(
// firing when the timer has already fired previously in this parse.
VARCACHE_PREF(
"html5.flushtimer.subsequentdelay",
html5_flushtimer_subsequentdelay,
int32_t, 120
)
//---------------------------------------------------------------------------
+// JavaScript prefs
+//---------------------------------------------------------------------------
+
+// nsJSEnvironmentObserver observes the memory-pressure notifications and
+// forces a garbage collection and cycle collection when it happens, if the
+// appropriate pref is set.
+#ifdef ANDROID
+ // Disable the JS engine's GC on memory pressure, since we do one in the
+ // mobile browser (bug 669346).
+ // XXX: this value possibly should be changed, or the pref removed entirely.
+ // See bug 1450787.
+# define PREF_VALUE false
+#else
+# define PREF_VALUE true
+#endif
+VARCACHE_PREF(
+ "javascript.options.gc_on_memory_pressure",
+ javascript_options_gc_on_memory_pressure,
+ bool, PREF_VALUE
+)
+#undef PREF_VALUE
+
+VARCACHE_PREF(
+ "javascript.options.compact_on_user_inactive",
+ javascript_options_compact_on_user_inactive,
+ bool, true
+)
+
+// The default amount of time to wait from the user being idle to starting a
+// shrinking GC.
+#ifdef NIGHTLY_BUILD
+# define PREF_VALUE 15000 // ms
+#else
+# define PREF_VALUE 300000 // ms
+#endif
+VARCACHE_PREF(
+ "javascript.options.compact_on_user_inactive_delay",
+ javascript_options_compact_on_user_inactive_delay,
+ uint32_t, PREF_VALUE
+)
+#undef PREF_VALUE
+
+VARCACHE_PREF(
+ "javascript.options.mem.log",
+ javascript_options_mem_log,
+ bool, false
+)
+
+VARCACHE_PREF(
+ "javascript.options.mem.notify",
+ javascript_options_mem_notify,
+ bool, false
+)
+
+//---------------------------------------------------------------------------
// Network prefs
//---------------------------------------------------------------------------
// Sub-resources HTTP-authentication:
// 0 - don't allow sub-resources to open HTTP authentication credentials
// dialogs
// 1 - allow sub-resources to open HTTP authentication credentials dialogs,
// but don't allow it for cross-origin sub-resources
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1517,26 +1517,16 @@ pref("javascript.options.mem.gc_incremen
// JSGC_SLICE_TIME_BUDGET
// Override the shell's default of unlimited slice time.
pref("javascript.options.mem.gc_incremental_slice_ms", 5);
// JSGC_COMPACTING_ENABLED
pref("javascript.options.mem.gc_compacting", true);
-pref("javascript.options.mem.log", false);
-pref("javascript.options.mem.notify", false);
-pref("javascript.options.gc_on_memory_pressure", true);
-pref("javascript.options.compact_on_user_inactive", true);
-#ifdef NIGHTLY_BUILD
-pref("javascript.options.compact_on_user_inactive_delay", 15000); // ms
-#else
-pref("javascript.options.compact_on_user_inactive_delay", 300000); // ms
-#endif
-
// JSGC_HIGH_FREQUENCY_TIME_LIMIT
pref("javascript.options.mem.gc_high_frequency_time_limit_ms", 1000);
// JSGC_HIGH_FREQUENCY_LOW_LIMIT
pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 100);
// JSGC_HIGH_FREQUENCY_HIGH_LIMIT
pref("javascript.options.mem.gc_high_frequency_high_limit_mb", 500);