зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1017141 - Make empty chunk count constants GC params r=terrence
This commit is contained in:
Родитель
bf7bbdfd29
Коммит
1aa9dc0f8f
|
@ -291,7 +291,9 @@ static const struct ParamPair {
|
|||
{"gcBytes", JSGC_BYTES},
|
||||
{"gcNumber", JSGC_NUMBER},
|
||||
{"sliceTimeBudget", JSGC_SLICE_TIME_BUDGET},
|
||||
{"markStackLimit", JSGC_MARK_STACK_LIMIT}
|
||||
{"markStackLimit", JSGC_MARK_STACK_LIMIT},
|
||||
{"minEmptyChunkCount", JSGC_MIN_EMPTY_CHUNK_COUNT},
|
||||
{"maxEmptyChunkCount", JSGC_MAX_EMPTY_CHUNK_COUNT}
|
||||
};
|
||||
|
||||
// Keep this in sync with above params.
|
||||
|
|
|
@ -480,6 +480,8 @@ class GCRuntime
|
|||
bool dynamicHeapGrowth;
|
||||
bool dynamicMarkSlice;
|
||||
uint64_t decommitThreshold;
|
||||
unsigned minEmptyChunkCount;
|
||||
unsigned maxEmptyChunkCount;
|
||||
|
||||
/* During shutdown, the GC needs to clean up every possible object. */
|
||||
bool cleanUpEverything;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
var min = gcparam('minEmptyChunkCount');
|
||||
var max = gcparam('maxEmptyChunkCount');
|
||||
|
||||
gcparam('minEmptyChunkCount', 10);
|
||||
gcparam('maxEmptyChunkCount', 20);
|
||||
assertEq(gcparam('minEmptyChunkCount'), 10);
|
||||
assertEq(gcparam('maxEmptyChunkCount'), 20);
|
||||
gc();
|
||||
|
||||
/* We maintain the invariant that maxEmptyChunkCount >= minEmptyChunkCount. */
|
||||
gcparam('minEmptyChunkCount', 30);
|
||||
assertEq(gcparam('minEmptyChunkCount'), 30);
|
||||
assertEq(gcparam('maxEmptyChunkCount'), 30);
|
||||
gc();
|
||||
|
||||
gcparam('maxEmptyChunkCount', 5);
|
||||
assertEq(gcparam('minEmptyChunkCount'), 5);
|
||||
assertEq(gcparam('maxEmptyChunkCount'), 5);
|
||||
gc();
|
||||
|
||||
gcparam('minEmptyChunkCount', min);
|
||||
gcparam('maxEmptyChunkCount', max);
|
||||
assertEq(gcparam('minEmptyChunkCount'), min);
|
||||
assertEq(gcparam('maxEmptyChunkCount'), max);
|
||||
gc();
|
|
@ -2145,7 +2145,16 @@ typedef enum JSGCParamKey {
|
|||
* available to be decommitted, then JS_MaybeGC will trigger a shrinking GC
|
||||
* to decommit it.
|
||||
*/
|
||||
JSGC_DECOMMIT_THRESHOLD = 20
|
||||
JSGC_DECOMMIT_THRESHOLD = 20,
|
||||
|
||||
/*
|
||||
* We try to keep at least this many unused chunks in the free chunk pool at
|
||||
* all times, even after a shrinking GC.
|
||||
*/
|
||||
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
|
||||
} JSGCParamKey;
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
|
|
|
@ -238,18 +238,6 @@ static const uint64_t GC_IDLE_FULL_SPAN = 20 * 1000 * 1000;
|
|||
/* Increase the IGC marking slice time if we are in highFrequencyGC mode. */
|
||||
static const int IGC_MARK_SLICE_MULTIPLIER = 2;
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
static const unsigned MIN_EMPTY_CHUNK_COUNT = 1;
|
||||
#else
|
||||
static const unsigned MIN_EMPTY_CHUNK_COUNT = 0;
|
||||
#endif
|
||||
|
||||
#if defined(ANDROID) || defined(MOZ_B2G)
|
||||
static const unsigned MAX_EMPTY_CHUNK_COUNT = 2;
|
||||
#else
|
||||
static const unsigned MAX_EMPTY_CHUNK_COUNT = 30;
|
||||
#endif
|
||||
|
||||
const AllocKind gc::slotsToThingKind[] = {
|
||||
/* 0 */ FINALIZE_OBJECT0, FINALIZE_OBJECT2, FINALIZE_OBJECT2, FINALIZE_OBJECT4,
|
||||
/* 4 */ FINALIZE_OBJECT4, FINALIZE_OBJECT8, FINALIZE_OBJECT8, FINALIZE_OBJECT8,
|
||||
|
@ -695,14 +683,15 @@ GCRuntime::expireChunkPool(bool shrinkBuffers, bool releaseAll)
|
|||
* without emptying the list, the older chunks will stay at the tail
|
||||
* and are more likely to reach the max age.
|
||||
*/
|
||||
JS_ASSERT(maxEmptyChunkCount >= minEmptyChunkCount);
|
||||
Chunk *freeList = nullptr;
|
||||
unsigned freeChunkCount = 0;
|
||||
for (ChunkPool::Enum e(chunkPool); !e.empty(); ) {
|
||||
Chunk *chunk = e.front();
|
||||
JS_ASSERT(chunk->unused());
|
||||
JS_ASSERT(!chunkSet.has(chunk));
|
||||
if (releaseAll || freeChunkCount >= MAX_EMPTY_CHUNK_COUNT ||
|
||||
(freeChunkCount >= MIN_EMPTY_CHUNK_COUNT &&
|
||||
if (releaseAll || freeChunkCount >= maxEmptyChunkCount ||
|
||||
(freeChunkCount >= minEmptyChunkCount &&
|
||||
(shrinkBuffers || chunk->info.age == MAX_EMPTY_CHUNK_AGE)))
|
||||
{
|
||||
e.removeAndPopFront();
|
||||
|
@ -716,7 +705,8 @@ GCRuntime::expireChunkPool(bool shrinkBuffers, bool releaseAll)
|
|||
e.popFront();
|
||||
}
|
||||
}
|
||||
JS_ASSERT_IF(shrinkBuffers, chunkPool.getEmptyCount() <= MIN_EMPTY_CHUNK_COUNT);
|
||||
JS_ASSERT(chunkPool.getEmptyCount() <= maxEmptyChunkCount);
|
||||
JS_ASSERT_IF(shrinkBuffers, chunkPool.getEmptyCount() <= minEmptyChunkCount);
|
||||
JS_ASSERT_IF(releaseAll, chunkPool.getEmptyCount() == 0);
|
||||
return freeList;
|
||||
}
|
||||
|
@ -1032,7 +1022,7 @@ GCRuntime::wantBackgroundAllocation() const
|
|||
* of them.
|
||||
*/
|
||||
return helperState.canBackgroundAllocate() &&
|
||||
chunkPool.getEmptyCount() < MIN_EMPTY_CHUNK_COUNT &&
|
||||
chunkPool.getEmptyCount() < minEmptyChunkCount &&
|
||||
chunkSet.count() >= 4;
|
||||
}
|
||||
|
||||
|
@ -1137,6 +1127,8 @@ GCRuntime::GCRuntime(JSRuntime *rt) :
|
|||
dynamicHeapGrowth(false),
|
||||
dynamicMarkSlice(false),
|
||||
decommitThreshold(32 * 1024 * 1024),
|
||||
minEmptyChunkCount(1),
|
||||
maxEmptyChunkCount(30),
|
||||
cleanUpEverything(false),
|
||||
grayBitsValid(false),
|
||||
isNeeded(0),
|
||||
|
@ -1456,6 +1448,16 @@ GCRuntime::setParameter(JSGCParamKey key, uint32_t value)
|
|||
case JSGC_DECOMMIT_THRESHOLD:
|
||||
decommitThreshold = value * 1024 * 1024;
|
||||
break;
|
||||
case JSGC_MIN_EMPTY_CHUNK_COUNT:
|
||||
minEmptyChunkCount = value;
|
||||
if (minEmptyChunkCount > maxEmptyChunkCount)
|
||||
maxEmptyChunkCount = minEmptyChunkCount;
|
||||
break;
|
||||
case JSGC_MAX_EMPTY_CHUNK_COUNT:
|
||||
maxEmptyChunkCount = value;
|
||||
if (minEmptyChunkCount > maxEmptyChunkCount)
|
||||
minEmptyChunkCount = maxEmptyChunkCount;
|
||||
break;
|
||||
default:
|
||||
JS_ASSERT(key == JSGC_MODE);
|
||||
mode = JSGCMode(value);
|
||||
|
@ -1504,6 +1506,10 @@ GCRuntime::getParameter(JSGCParamKey key)
|
|||
return dynamicMarkSlice;
|
||||
case JSGC_ALLOCATION_THRESHOLD:
|
||||
return allocThreshold / 1024 / 1024;
|
||||
case JSGC_MIN_EMPTY_CHUNK_COUNT:
|
||||
return minEmptyChunkCount;
|
||||
case JSGC_MAX_EMPTY_CHUNK_COUNT:
|
||||
return maxEmptyChunkCount;
|
||||
default:
|
||||
JS_ASSERT(key == JSGC_NUMBER);
|
||||
return uint32_t(number);
|
||||
|
|
Загрузка…
Ссылка в новой задаче