Bug 1644258 - Simplify nursery size rounding r=sfink

Previously there was a quirk of nursery size rounding where requesting a nursery size of just less than a chunk resulted in a smaller size than a chunk being used even if one chunk was the nearest valid size.

This was to avoid having a sub-chunk size greater than the amount of usable space in a chunk, but that is not possible anyway as long as the sub-chunk step is greater than the chunk trailer size.

The patch simplifies the rounding code and updates the test code to add a size that will give different results depending on chunk size.  I had to add a gcparam to get the chunk size to make this work.

Differential Revision: https://phabricator.services.mozilla.com/D79148
This commit is contained in:
Jon Coppeard 2020-06-10 15:44:07 +00:00
Родитель 0fcab2f5a1
Коммит 00f99e1d69
5 изменённых файлов: 27 добавлений и 16 удалений

Просмотреть файл

@ -323,7 +323,7 @@ typedef enum JSGCParamKey {
/*
* The current size of the nursery.
*
* read-only.
* This parameter is read-only.
*/
JSGC_NURSERY_BYTES = 34,
@ -348,6 +348,13 @@ typedef enum JSGCParamKey {
* Default: IncrementalWeakMarkEnabled
*/
JSGC_INCREMENTAL_WEAKMAP_ENABLED = 37,
/**
* The chunk size in bytes for this system.
*
* This parameter is read-only.
*/
JSGC_CHUNK_BYTES = 38,
} JSGCParamKey;
/*

Просмотреть файл

@ -585,7 +585,8 @@ static bool MinorGC(JSContext* cx, unsigned argc, Value* vp) {
_("pretenureGroupThreshold", JSGC_PRETENURE_GROUP_THRESHOLD, true) \
_("zoneAllocDelayKB", JSGC_ZONE_ALLOC_DELAY_KB, true) \
_("mallocThresholdBase", JSGC_MALLOC_THRESHOLD_BASE, true) \
_("mallocGrowthFactor", JSGC_MALLOC_GROWTH_FACTOR, true)
_("mallocGrowthFactor", JSGC_MALLOC_GROWTH_FACTOR, true) \
_("chunkBytes", JSGC_CHUNK_BYTES, false)
static const struct ParamInfo {
const char* name;

Просмотреть файл

@ -1502,6 +1502,8 @@ uint32_t GCRuntime::getParameter(JSGCParamKey key, const AutoLockGC& lock) {
return tunables.mallocThresholdBase() / 1024 / 1024;
case JSGC_MALLOC_GROWTH_FACTOR:
return uint32_t(tunables.mallocGrowthFactor() * 100);
case JSGC_CHUNK_BYTES:
return ChunkSize;
default:
MOZ_CRASH("Unknown parameter key");
}

Просмотреть файл

@ -1543,13 +1543,15 @@ size_t js::Nursery::targetSize(JS::GCReason reason) {
/* static */
size_t js::Nursery::roundSize(size_t size) {
if (size >= ChunkSize) {
size = Round(size, ChunkSize);
} else {
size = std::min(Round(size, SubChunkStep),
RoundDown(NurseryChunkUsableSize, SubChunkStep));
}
static_assert(SubChunkStep > gc::ChunkTrailerSize,
"Don't allow the nursery to overwrite the trailer when using "
"less than a chunk");
size_t step = size >= ChunkSize ? ChunkSize : SubChunkStep;
size = Round(size, step);
MOZ_ASSERT(size >= ArenaSize);
return size;
}

Просмотреть файл

@ -6,7 +6,9 @@
load(libdir + "asserts.js");
var testSizesKB = [128, 129, 255, 256, 1023, 1024, 3*1024, 4*1024+1, 16*1024];
const chunkSizeKB = gcparam('chunkBytes') / 1024;
var testSizesKB = [128, 129, 255, 256, 516, 1023, 1024, 3*1024, 4*1024+1, 16*1024];
// Valid maximum sizes must be >= 1MB.
var testMaxSizesKB = testSizesKB.filter(x => x >= 1024);
@ -33,8 +35,8 @@ function setMinMax(min, max) {
// Set the maximum first so that we don't hit a case where max < min.
gcparam('maxNurseryBytes', max * 1024);
gcparam('minNurseryBytes', min * 1024);
assertEq(nearestLegalSize(max) * 1024, gcparam('maxNurseryBytes'));
assertEq(nearestLegalSize(min) * 1024, gcparam('minNurseryBytes'));
assertEq(gcparam('maxNurseryBytes'), nearestLegalSize(max) * 1024);
assertEq(gcparam('minNurseryBytes'), nearestLegalSize(min) * 1024);
allocateSomeThings();
gc();
}
@ -46,11 +48,8 @@ function allocateSomeThings() {
}
function nearestLegalSize(sizeKB) {
if (sizeKB >= 1024) {
return round(sizeKB, 1024);
}
return Math.min(round(sizeKB, 4), 1020);
let step = sizeKB >= chunkSizeKB ? chunkSizeKB : 4;
return round(sizeKB, step);
}
function round(x, y) {