Bug 1127792 - Add a pref to globally disable compacting GC r=terrence r=mccr8 r=bent

This commit is contained in:
Jon Coppeard
2015-02-02 14:39:34 +00:00
parent 6bb7df67c2
commit 46adfcf343
7 changed files with 52 additions and 45 deletions

View File

@@ -2354,6 +2354,13 @@ SetMemoryGCSliceTimePrefChangedCallback(const char* aPrefName, void* aClosure)
JS_SetGCParameter(sRuntime, JSGC_SLICE_TIME_BUDGET, pref);
}
static void
SetMemoryGCCompactingPrefChangedCallback(const char* aPrefName, void* aClosure)
{
bool pref = Preferences::GetBool(aPrefName);
JS_SetGCParameter(sRuntime, JSGC_COMPACTING_ENABLED, pref);
}
static void
SetMemoryGCPrefChangedCallback(const char* aPrefName, void* aClosure)
{
@@ -2616,6 +2623,9 @@ nsJSContext::EnsureStatics()
Preferences::RegisterCallbackAndCall(SetMemoryGCSliceTimePrefChangedCallback,
"javascript.options.mem.gc_incremental_slice_ms");
Preferences::RegisterCallbackAndCall(SetMemoryGCCompactingPrefChangedCallback,
"javascript.options.mem.gc_compacting");
Preferences::RegisterCallbackAndCall(SetMemoryGCPrefChangedCallback,
"javascript.options.mem.gc_high_frequency_time_limit_ms",
(void *)JSGC_HIGH_FREQUENCY_TIME_LIMIT);

View File

@@ -400,8 +400,8 @@ UpdateCommonJSGCMemoryOption(RuntimeService* aRuntimeService,
}
void
UpdatOtherJSGCMemoryOption(RuntimeService* aRuntimeService,
JSGCParamKey aKey, uint32_t aValue)
UpdateOtherJSGCMemoryOption(RuntimeService* aRuntimeService,
JSGCParamKey aKey, uint32_t aValue)
{
AssertIsOnMainThread();
@@ -466,14 +466,14 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
uint32_t value = (prefValue <= 0 || prefValue >= 0x1000) ?
uint32_t(-1) :
uint32_t(prefValue) * 1024 * 1024;
UpdatOtherJSGCMemoryOption(rts, JSGC_MAX_BYTES, value);
UpdateOtherJSGCMemoryOption(rts, JSGC_MAX_BYTES, value);
continue;
}
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "high_water_mark");
if (memPrefName == matchName || (gRuntimeServiceDuringInit && index == 1)) {
int32_t prefValue = GetWorkerPref(matchName, 128);
UpdatOtherJSGCMemoryOption(rts, JSGC_MAX_MALLOC_BYTES,
UpdateOtherJSGCMemoryOption(rts, JSGC_MAX_MALLOC_BYTES,
uint32_t(prefValue) * 1024 * 1024);
continue;
}
@@ -538,7 +538,7 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
int32_t prefValue = GetWorkerPref(matchName, -1);
uint32_t value =
(prefValue <= 0 || prefValue >= 100000) ? 0 : uint32_t(prefValue);
UpdatOtherJSGCMemoryOption(rts, JSGC_SLICE_TIME_BUDGET, value);
UpdateOtherJSGCMemoryOption(rts, JSGC_SLICE_TIME_BUDGET, value);
continue;
}
@@ -546,7 +546,7 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
if (memPrefName == matchName ||
(gRuntimeServiceDuringInit && index == 10)) {
bool prefValue = GetWorkerPref(matchName, false);
UpdatOtherJSGCMemoryOption(rts, JSGC_DYNAMIC_HEAP_GROWTH,
UpdateOtherJSGCMemoryOption(rts, JSGC_DYNAMIC_HEAP_GROWTH,
prefValue ? 0 : 1);
continue;
}
@@ -555,7 +555,7 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
if (memPrefName == matchName ||
(gRuntimeServiceDuringInit && index == 11)) {
bool prefValue = GetWorkerPref(matchName, false);
UpdatOtherJSGCMemoryOption(rts, JSGC_DYNAMIC_MARK_SLICE,
UpdateOtherJSGCMemoryOption(rts, JSGC_DYNAMIC_MARK_SLICE,
prefValue ? 0 : 1);
continue;
}
@@ -574,6 +574,15 @@ LoadJSGCMemoryOptions(const char* aPrefName, void* /* aClosure */)
continue;
}
matchName.RebindLiteral(PREF_MEM_OPTIONS_PREFIX "gc_compacting");
if (memPrefName == matchName ||
(gRuntimeServiceDuringInit && index == 14)) {
bool prefValue = GetWorkerPref(matchName, false);
UpdateOtherJSGCMemoryOption(rts, JSGC_COMPACTING_ENABLED,
prefValue ? 0 : 1);
continue;
}
#ifdef DEBUG
nsAutoCString message("Workers don't support the 'mem.");
message.Append(memPrefName);

View File

@@ -302,21 +302,6 @@ DisableIncrementalGC(JSRuntime *rt);
extern JS_PUBLIC_API(bool)
IsIncrementalGCEnabled(JSRuntime *rt);
/*
* Compacting GC defaults to enabled, but may be disabled for testing or in
* embeddings that have not implemented the necessary object moved hooks or weak
* pointer callbacks. There is not currently a way to re-enable compacting GC
* once it has been disabled on the runtime.
*/
extern JS_PUBLIC_API(void)
DisableCompactingGC(JSRuntime *rt);
/*
* Returns true if compacting GC is enabled.
*/
extern JS_PUBLIC_API(bool)
IsCompactingGCEnabled(JSRuntime *rt);
/*
* Returns true while an incremental GC is ongoing, both when actively
* collecting and between slices.

View File

@@ -1097,10 +1097,15 @@ class GCRuntime
unsigned generationalDisabled;
/*
* Some code cannot tolerate compacting GC so it can be disabled with this
* counter.
* Whether compacting GC can is enabled globally.
*/
unsigned compactingDisabled;
bool compactingEnabled;
/*
* Some code cannot tolerate compacting GC so it can be disabled temporarily
* with AutoDisableCompactingGC which uses this counter.
*/
unsigned compactingDisabledCount;
/*
* This is true if we are in the middle of a brain transplant (e.g.,

View File

@@ -1957,7 +1957,10 @@ typedef enum JSGCParamKey {
JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
/* We never keep more than this many unused chunks in the free chunk pool. */
JSGC_MAX_EMPTY_CHUNK_COUNT = 22
JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
/* Whether compacting GC is enabled. */
JSGC_COMPACTING_ENABLED = 23
} JSGCParamKey;
extern JS_PUBLIC_API(void)

View File

@@ -1112,7 +1112,8 @@ GCRuntime::GCRuntime(JSRuntime *rt) :
sliceBudget(SliceBudget::Unlimited),
incrementalAllowed(true),
generationalDisabled(0),
compactingDisabled(0),
compactingEnabled(true),
compactingDisabledCount(0),
manipulatingDeadZones(false),
objectsMarkedInDeadZones(0),
poked(false),
@@ -1373,6 +1374,9 @@ GCRuntime::setParameter(JSGCParamKey key, uint32_t value)
mode == JSGC_MODE_COMPARTMENT ||
mode == JSGC_MODE_INCREMENTAL);
break;
case JSGC_COMPACTING_ENABLED:
compactingEnabled = value != 0;
break;
default:
tunables.setParameter(key, value);
}
@@ -1414,10 +1418,10 @@ GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value)
MOZ_ASSERT(lowFrequencyHeapGrowth_ / 0.9 > 1.0);
break;
case JSGC_DYNAMIC_HEAP_GROWTH:
dynamicHeapGrowthEnabled_ = value;
dynamicHeapGrowthEnabled_ = value != 0;
break;
case JSGC_DYNAMIC_MARK_SLICE:
dynamicMarkSliceEnabled_ = value;
dynamicMarkSliceEnabled_ = value != 0;
break;
case JSGC_ALLOCATION_THRESHOLD:
gcZoneAllocThresholdBase_ = value * 1024 * 1024;
@@ -1483,6 +1487,8 @@ GCRuntime::getParameter(JSGCParamKey key, const AutoLockGC &lock)
return tunables.minEmptyChunkCount();
case JSGC_MAX_EMPTY_CHUNK_COUNT:
return tunables.maxEmptyChunkCount();
case JSGC_COMPACTING_ENABLED:
return compactingEnabled;
default:
MOZ_ASSERT(key == JSGC_NUMBER);
return uint32_t(number);
@@ -1888,22 +1894,22 @@ void
GCRuntime::disableCompactingGC()
{
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
++rt->gc.compactingDisabled;
++compactingDisabledCount;
}
void
GCRuntime::enableCompactingGC()
{
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
MOZ_ASSERT(compactingDisabled > 0);
--compactingDisabled;
MOZ_ASSERT(compactingDisabledCount > 0);
--compactingDisabledCount;
}
bool
GCRuntime::isCompactingGCEnabled()
{
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
return rt->gc.compactingDisabled == 0;
return compactingEnabled && compactingDisabledCount == 0;
}
AutoDisableCompactingGC::AutoDisableCompactingGC(JSRuntime *rt)
@@ -7067,18 +7073,6 @@ JS::IsIncrementalGCEnabled(JSRuntime *rt)
return rt->gc.isIncrementalGCEnabled();
}
JS_PUBLIC_API(void)
JS::DisableCompactingGC(JSRuntime *rt)
{
rt->gc.disableCompactingGC();
}
JS_PUBLIC_API(bool)
JS::IsCompactingGCEnabled(JSRuntime *rt)
{
return rt->gc.isCompactingGCEnabled();
}
JS_PUBLIC_API(bool)
JS::IsIncrementalGCInProgress(JSRuntime *rt)
{

View File

@@ -1064,6 +1064,7 @@ pref("javascript.options.mem.max", -1);
pref("javascript.options.mem.gc_per_compartment", true);
pref("javascript.options.mem.gc_incremental", true);
pref("javascript.options.mem.gc_incremental_slice_ms", 10);
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);