зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1827621 - Add a mininum heap size threashold at which to use parallel marking r=sfink
Benchmark results show that using parallel marking is not always a win for small heaps, so add a threshold for its use. This is set to 10MB, which will result in using parallel marking ~70% of the time. This parameter is set to zero for jit-tests and shell js tests so we get test coverage where heap sizes are expected to be small (and maximum performance is not a goal). Differential Revision: https://phabricator.services.mozilla.com/D175249
This commit is contained in:
Родитель
f77fa8f135
Коммит
66adc8077b
|
@ -482,6 +482,13 @@ typedef enum JSGCParamKey {
|
|||
* Default: 0 (no effect).
|
||||
*/
|
||||
JSGC_MARKING_THREAD_COUNT = 49,
|
||||
|
||||
/**
|
||||
* The heap size above which to use parallel marking.
|
||||
*
|
||||
* Default: ParallelMarkingThresholdKB
|
||||
*/
|
||||
JSGC_PARALLEL_MARKING_THRESHOLD_KB = 50,
|
||||
} JSGCParamKey;
|
||||
|
||||
/*
|
||||
|
|
|
@ -1274,6 +1274,8 @@ uint32_t GCRuntime::getParameter(JSGCParamKey key, const AutoLockGC& lock) {
|
|||
return tunables.mallocThresholdBase() / 1024 / 1024;
|
||||
case JSGC_URGENT_THRESHOLD_MB:
|
||||
return tunables.urgentThresholdBytes() / 1024 / 1024;
|
||||
case JSGC_PARALLEL_MARKING_THRESHOLD_KB:
|
||||
return tunables.parallelMarkingThresholdBytes() / 1024;
|
||||
case JSGC_CHUNK_BYTES:
|
||||
return ChunkSize;
|
||||
case JSGC_HELPER_THREAD_RATIO:
|
||||
|
@ -2987,7 +2989,8 @@ inline bool GCRuntime::canMarkInParallel() const {
|
|||
}
|
||||
#endif
|
||||
|
||||
return markers.length() > 1;
|
||||
return markers.length() > 1 && stats().initialCollectedBytes() >=
|
||||
tunables.parallelMarkingThresholdBytes();
|
||||
}
|
||||
|
||||
IncrementalProgress GCRuntime::markUntilBudgetExhausted(
|
||||
|
|
|
@ -35,54 +35,55 @@ class TenuredChunk;
|
|||
} /* namespace gc */
|
||||
|
||||
// Define name, key and writability for the GC parameters.
|
||||
#define FOR_EACH_GC_PARAM(_) \
|
||||
_("maxBytes", JSGC_MAX_BYTES, true) \
|
||||
_("minNurseryBytes", JSGC_MIN_NURSERY_BYTES, true) \
|
||||
_("maxNurseryBytes", JSGC_MAX_NURSERY_BYTES, true) \
|
||||
_("gcBytes", JSGC_BYTES, false) \
|
||||
_("nurseryBytes", JSGC_NURSERY_BYTES, false) \
|
||||
_("gcNumber", JSGC_NUMBER, false) \
|
||||
_("majorGCNumber", JSGC_MAJOR_GC_NUMBER, false) \
|
||||
_("minorGCNumber", JSGC_MINOR_GC_NUMBER, false) \
|
||||
_("incrementalGCEnabled", JSGC_INCREMENTAL_GC_ENABLED, true) \
|
||||
_("perZoneGCEnabled", JSGC_PER_ZONE_GC_ENABLED, true) \
|
||||
_("unusedChunks", JSGC_UNUSED_CHUNKS, false) \
|
||||
_("totalChunks", JSGC_TOTAL_CHUNKS, false) \
|
||||
_("sliceTimeBudgetMS", JSGC_SLICE_TIME_BUDGET_MS, true) \
|
||||
_("highFrequencyTimeLimit", JSGC_HIGH_FREQUENCY_TIME_LIMIT, true) \
|
||||
_("smallHeapSizeMax", JSGC_SMALL_HEAP_SIZE_MAX, true) \
|
||||
_("largeHeapSizeMin", JSGC_LARGE_HEAP_SIZE_MIN, true) \
|
||||
_("highFrequencySmallHeapGrowth", JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH, \
|
||||
true) \
|
||||
_("highFrequencyLargeHeapGrowth", JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH, \
|
||||
true) \
|
||||
_("lowFrequencyHeapGrowth", JSGC_LOW_FREQUENCY_HEAP_GROWTH, true) \
|
||||
_("balancedHeapLimitsEnabled", JSGC_BALANCED_HEAP_LIMITS_ENABLED, true) \
|
||||
_("heapGrowthFactor", JSGC_HEAP_GROWTH_FACTOR, true) \
|
||||
_("allocationThreshold", JSGC_ALLOCATION_THRESHOLD, true) \
|
||||
_("smallHeapIncrementalLimit", JSGC_SMALL_HEAP_INCREMENTAL_LIMIT, true) \
|
||||
_("largeHeapIncrementalLimit", JSGC_LARGE_HEAP_INCREMENTAL_LIMIT, true) \
|
||||
_("minEmptyChunkCount", JSGC_MIN_EMPTY_CHUNK_COUNT, true) \
|
||||
_("maxEmptyChunkCount", JSGC_MAX_EMPTY_CHUNK_COUNT, true) \
|
||||
_("compactingEnabled", JSGC_COMPACTING_ENABLED, true) \
|
||||
_("parallelMarkingEnabled", JSGC_PARALLEL_MARKING_ENABLED, true) \
|
||||
_("minLastDitchGCPeriod", JSGC_MIN_LAST_DITCH_GC_PERIOD, true) \
|
||||
_("nurseryFreeThresholdForIdleCollection", \
|
||||
JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION, true) \
|
||||
_("nurseryFreeThresholdForIdleCollectionPercent", \
|
||||
JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_PERCENT, true) \
|
||||
_("nurseryTimeoutForIdleCollectionMS", \
|
||||
JSGC_NURSERY_TIMEOUT_FOR_IDLE_COLLECTION_MS, true) \
|
||||
_("pretenureThreshold", JSGC_PRETENURE_THRESHOLD, true) \
|
||||
_("pretenureGroupThreshold", JSGC_PRETENURE_GROUP_THRESHOLD, true) \
|
||||
_("zoneAllocDelayKB", JSGC_ZONE_ALLOC_DELAY_KB, true) \
|
||||
_("mallocThresholdBase", JSGC_MALLOC_THRESHOLD_BASE, true) \
|
||||
_("urgentThreshold", JSGC_URGENT_THRESHOLD_MB, true) \
|
||||
_("chunkBytes", JSGC_CHUNK_BYTES, false) \
|
||||
_("helperThreadRatio", JSGC_HELPER_THREAD_RATIO, true) \
|
||||
_("maxHelperThreads", JSGC_MAX_HELPER_THREADS, true) \
|
||||
_("helperThreadCount", JSGC_HELPER_THREAD_COUNT, false) \
|
||||
_("markingThreadCount", JSGC_MARKING_THREAD_COUNT, true) \
|
||||
#define FOR_EACH_GC_PARAM(_) \
|
||||
_("maxBytes", JSGC_MAX_BYTES, true) \
|
||||
_("minNurseryBytes", JSGC_MIN_NURSERY_BYTES, true) \
|
||||
_("maxNurseryBytes", JSGC_MAX_NURSERY_BYTES, true) \
|
||||
_("gcBytes", JSGC_BYTES, false) \
|
||||
_("nurseryBytes", JSGC_NURSERY_BYTES, false) \
|
||||
_("gcNumber", JSGC_NUMBER, false) \
|
||||
_("majorGCNumber", JSGC_MAJOR_GC_NUMBER, false) \
|
||||
_("minorGCNumber", JSGC_MINOR_GC_NUMBER, false) \
|
||||
_("incrementalGCEnabled", JSGC_INCREMENTAL_GC_ENABLED, true) \
|
||||
_("perZoneGCEnabled", JSGC_PER_ZONE_GC_ENABLED, true) \
|
||||
_("unusedChunks", JSGC_UNUSED_CHUNKS, false) \
|
||||
_("totalChunks", JSGC_TOTAL_CHUNKS, false) \
|
||||
_("sliceTimeBudgetMS", JSGC_SLICE_TIME_BUDGET_MS, true) \
|
||||
_("highFrequencyTimeLimit", JSGC_HIGH_FREQUENCY_TIME_LIMIT, true) \
|
||||
_("smallHeapSizeMax", JSGC_SMALL_HEAP_SIZE_MAX, true) \
|
||||
_("largeHeapSizeMin", JSGC_LARGE_HEAP_SIZE_MIN, true) \
|
||||
_("highFrequencySmallHeapGrowth", JSGC_HIGH_FREQUENCY_SMALL_HEAP_GROWTH, \
|
||||
true) \
|
||||
_("highFrequencyLargeHeapGrowth", JSGC_HIGH_FREQUENCY_LARGE_HEAP_GROWTH, \
|
||||
true) \
|
||||
_("lowFrequencyHeapGrowth", JSGC_LOW_FREQUENCY_HEAP_GROWTH, true) \
|
||||
_("balancedHeapLimitsEnabled", JSGC_BALANCED_HEAP_LIMITS_ENABLED, true) \
|
||||
_("heapGrowthFactor", JSGC_HEAP_GROWTH_FACTOR, true) \
|
||||
_("allocationThreshold", JSGC_ALLOCATION_THRESHOLD, true) \
|
||||
_("smallHeapIncrementalLimit", JSGC_SMALL_HEAP_INCREMENTAL_LIMIT, true) \
|
||||
_("largeHeapIncrementalLimit", JSGC_LARGE_HEAP_INCREMENTAL_LIMIT, true) \
|
||||
_("minEmptyChunkCount", JSGC_MIN_EMPTY_CHUNK_COUNT, true) \
|
||||
_("maxEmptyChunkCount", JSGC_MAX_EMPTY_CHUNK_COUNT, true) \
|
||||
_("compactingEnabled", JSGC_COMPACTING_ENABLED, true) \
|
||||
_("parallelMarkingEnabled", JSGC_PARALLEL_MARKING_ENABLED, true) \
|
||||
_("parallelMarkingThresholdKB", JSGC_PARALLEL_MARKING_THRESHOLD_KB, true) \
|
||||
_("minLastDitchGCPeriod", JSGC_MIN_LAST_DITCH_GC_PERIOD, true) \
|
||||
_("nurseryFreeThresholdForIdleCollection", \
|
||||
JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION, true) \
|
||||
_("nurseryFreeThresholdForIdleCollectionPercent", \
|
||||
JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION_PERCENT, true) \
|
||||
_("nurseryTimeoutForIdleCollectionMS", \
|
||||
JSGC_NURSERY_TIMEOUT_FOR_IDLE_COLLECTION_MS, true) \
|
||||
_("pretenureThreshold", JSGC_PRETENURE_THRESHOLD, true) \
|
||||
_("pretenureGroupThreshold", JSGC_PRETENURE_GROUP_THRESHOLD, true) \
|
||||
_("zoneAllocDelayKB", JSGC_ZONE_ALLOC_DELAY_KB, true) \
|
||||
_("mallocThresholdBase", JSGC_MALLOC_THRESHOLD_BASE, true) \
|
||||
_("urgentThreshold", JSGC_URGENT_THRESHOLD_MB, true) \
|
||||
_("chunkBytes", JSGC_CHUNK_BYTES, false) \
|
||||
_("helperThreadRatio", JSGC_HELPER_THREAD_RATIO, true) \
|
||||
_("maxHelperThreads", JSGC_MAX_HELPER_THREADS, true) \
|
||||
_("helperThreadCount", JSGC_HELPER_THREAD_COUNT, false) \
|
||||
_("markingThreadCount", JSGC_MARKING_THREAD_COUNT, true) \
|
||||
_("systemPageSizeKB", JSGC_SYSTEM_PAGE_SIZE_KB, false)
|
||||
|
||||
// Get the key and writability give a GC parameter name.
|
||||
|
|
|
@ -413,6 +413,7 @@ class GCRuntime {
|
|||
// Internal public interface
|
||||
ZoneVector& zones() { return zones_.ref(); }
|
||||
gcstats::Statistics& stats() { return stats_.ref(); }
|
||||
const gcstats::Statistics& stats() const { return stats_.ref(); }
|
||||
State state() const { return incrementalState; }
|
||||
bool isHeapCompacting() const { return state() == State::Compact; }
|
||||
bool isForegroundSweeping() const { return state() == State::Sweep; }
|
||||
|
|
|
@ -76,7 +76,9 @@ GCSchedulingTunables::GCSchedulingTunables()
|
|||
minLastDitchGCPeriod_(
|
||||
TimeDuration::FromSeconds(TuningDefaults::MinLastDitchGCPeriod)),
|
||||
mallocThresholdBase_(TuningDefaults::MallocThresholdBase),
|
||||
urgentThresholdBytes_(TuningDefaults::UrgentThresholdBytes) {}
|
||||
urgentThresholdBytes_(TuningDefaults::UrgentThresholdBytes),
|
||||
parallelMarkingThresholdBytes_(
|
||||
TuningDefaults::ParallelMarkingThresholdBytes) {}
|
||||
|
||||
bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
|
||||
// Limit various parameters to reasonable levels to catch errors.
|
||||
|
@ -251,6 +253,14 @@ bool GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value) {
|
|||
urgentThresholdBytes_ = threshold;
|
||||
break;
|
||||
}
|
||||
case JSGC_PARALLEL_MARKING_THRESHOLD_KB: {
|
||||
size_t threshold;
|
||||
if (!kilobytesToBytes(value, &threshold)) {
|
||||
return false;
|
||||
}
|
||||
parallelMarkingThresholdBytes_ = threshold;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unknown GC parameter.");
|
||||
}
|
||||
|
@ -406,6 +416,10 @@ void GCSchedulingTunables::resetParameter(JSGCParamKey key) {
|
|||
case JSGC_URGENT_THRESHOLD_MB:
|
||||
urgentThresholdBytes_ = TuningDefaults::UrgentThresholdBytes;
|
||||
break;
|
||||
case JSGC_PARALLEL_MARKING_THRESHOLD_KB:
|
||||
parallelMarkingThresholdBytes_ =
|
||||
TuningDefaults::ParallelMarkingThresholdBytes;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unknown GC parameter.");
|
||||
}
|
||||
|
|
|
@ -452,6 +452,9 @@ static const size_t MaxHelperThreads = 8;
|
|||
/* JSGC_URGENT_THRESHOLD_MB */
|
||||
static const size_t UrgentThresholdBytes = 16 * 1024 * 1024;
|
||||
|
||||
/* JSGC_PARALLEL_MARKING_THRESHOLD_KB */
|
||||
static const size_t ParallelMarkingThresholdBytes = 10 * 1024 * 1024;
|
||||
|
||||
} // namespace TuningDefaults
|
||||
|
||||
/*
|
||||
|
@ -617,6 +620,11 @@ class GCSchedulingTunables {
|
|||
*/
|
||||
MainThreadData<size_t> urgentThresholdBytes_;
|
||||
|
||||
/*
|
||||
* JSGC_PARALLEL_MARKING_THRESHOLD_KB
|
||||
*/
|
||||
MainThreadData<size_t> parallelMarkingThresholdBytes_;
|
||||
|
||||
public:
|
||||
GCSchedulingTunables();
|
||||
|
||||
|
@ -671,6 +679,10 @@ class GCSchedulingTunables {
|
|||
|
||||
size_t urgentThresholdBytes() const { return urgentThresholdBytes_; }
|
||||
|
||||
size_t parallelMarkingThresholdBytes() const {
|
||||
return parallelMarkingThresholdBytes_;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool setParameter(JSGCParamKey key, uint32_t value);
|
||||
void resetParameter(JSGCParamKey key);
|
||||
|
||||
|
|
|
@ -24,3 +24,6 @@ for (const name of ["gczeal",
|
|||
}
|
||||
hasFunction[name] = present;
|
||||
}
|
||||
|
||||
// Set the minimum heap size for parallel marking to zero for testing purposes.
|
||||
gcparam('parallelMarkingThresholdKB', 0);
|
||||
|
|
|
@ -55,6 +55,7 @@ testChangeParam("compactingEnabled");
|
|||
testChangeParam("mallocThresholdBase");
|
||||
testChangeParam("urgentThreshold");
|
||||
testChangeParam("nurseryTimeoutForIdleCollectionMS");
|
||||
testChangeParam("parallelMarkingThresholdKB");
|
||||
|
||||
testMBParamValue("smallHeapSizeMax");
|
||||
testMBParamValue("largeHeapSizeMin");
|
||||
|
|
|
@ -578,4 +578,7 @@
|
|||
shellOptionsClear();
|
||||
})(this);
|
||||
|
||||
// Set the minimum heap size for parallel marking to zero for testing purposes.
|
||||
gcparam('parallelMarkingThresholdKB', 0);
|
||||
|
||||
var DESCRIPTION;
|
||||
|
|
Загрузка…
Ссылка в новой задаче