зеркало из https://github.com/mozilla/gecko-dev.git
Bug 999158 - Keep a spare chunk around to mitigate GGC OOM crashes on tenuring r=terrence
This commit is contained in:
Родитель
b59461402a
Коммит
81b32d0f45
|
@ -55,9 +55,6 @@ class ChunkPool
|
|||
/* Must be called either during the GC or with the GC lock taken. */
|
||||
inline void put(Chunk *chunk);
|
||||
|
||||
/* Must be called with the GC lock taken. */
|
||||
void expireAndFree(JSRuntime *rt, bool releaseAll);
|
||||
|
||||
class Enum {
|
||||
public:
|
||||
Enum(ChunkPool &pool) : pool(pool), chunkp(&pool.emptyChunkListHead) {}
|
||||
|
@ -358,7 +355,7 @@ class GCRuntime
|
|||
* Return the list of chunks that can be released outside the GC lock.
|
||||
* Must be called either during the GC or with the GC lock taken.
|
||||
*/
|
||||
Chunk *expireChunkPool(bool releaseAll);
|
||||
Chunk *expireChunkPool(bool shrinkBuffers, bool releaseAll);
|
||||
void expireAndFreeChunkPool(bool releaseAll);
|
||||
void freeChunkList(Chunk *chunkListHead);
|
||||
void prepareToFreeChunk(ChunkInfo &info);
|
||||
|
|
|
@ -239,10 +239,16 @@ 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;
|
||||
|
||||
#if defined(ANDROID) || defined(MOZ_B2G)
|
||||
static const int MAX_EMPTY_CHUNK_COUNT = 2;
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
static const unsigned MIN_EMPTY_CHUNK_COUNT = 1;
|
||||
#else
|
||||
static const int MAX_EMPTY_CHUNK_COUNT = 30;
|
||||
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[] = {
|
||||
|
@ -712,7 +718,7 @@ ChunkPool::Enum::removeAndPopFront()
|
|||
|
||||
/* Must be called either during the GC or with the GC lock taken. */
|
||||
Chunk *
|
||||
GCRuntime::expireChunkPool(bool releaseAll)
|
||||
GCRuntime::expireChunkPool(bool shrinkBuffers, bool releaseAll)
|
||||
{
|
||||
/*
|
||||
* Return old empty chunks to the system while preserving the order of
|
||||
|
@ -721,14 +727,14 @@ GCRuntime::expireChunkPool(bool releaseAll)
|
|||
* and are more likely to reach the max age.
|
||||
*/
|
||||
Chunk *freeList = nullptr;
|
||||
int freeChunkCount = 0;
|
||||
unsigned freeChunkCount = 0;
|
||||
for (ChunkPool::Enum e(chunkPool); !e.empty(); ) {
|
||||
Chunk *chunk = e.front();
|
||||
JS_ASSERT(chunk->unused());
|
||||
JS_ASSERT(!chunkSet.has(chunk));
|
||||
JS_ASSERT(chunk->info.age <= MAX_EMPTY_CHUNK_AGE);
|
||||
if (releaseAll || chunk->info.age == MAX_EMPTY_CHUNK_AGE ||
|
||||
freeChunkCount++ > MAX_EMPTY_CHUNK_COUNT)
|
||||
if (releaseAll || freeChunkCount >= MAX_EMPTY_CHUNK_COUNT ||
|
||||
(freeChunkCount >= MIN_EMPTY_CHUNK_COUNT &&
|
||||
(shrinkBuffers || chunk->info.age == MAX_EMPTY_CHUNK_AGE)))
|
||||
{
|
||||
e.removeAndPopFront();
|
||||
prepareToFreeChunk(chunk->info);
|
||||
|
@ -736,10 +742,12 @@ GCRuntime::expireChunkPool(bool releaseAll)
|
|||
freeList = chunk;
|
||||
} else {
|
||||
/* Keep the chunk but increase its age. */
|
||||
++freeChunkCount;
|
||||
++chunk->info.age;
|
||||
e.popFront();
|
||||
}
|
||||
}
|
||||
JS_ASSERT_IF(shrinkBuffers, chunkPool.getEmptyCount() <= MIN_EMPTY_CHUNK_COUNT);
|
||||
JS_ASSERT_IF(releaseAll, chunkPool.getEmptyCount() == 0);
|
||||
return freeList;
|
||||
}
|
||||
|
@ -757,7 +765,7 @@ GCRuntime::freeChunkList(Chunk *chunkListHead)
|
|||
void
|
||||
GCRuntime::expireAndFreeChunkPool(bool releaseAll)
|
||||
{
|
||||
freeChunkList(expireChunkPool(releaseAll));
|
||||
freeChunkList(expireChunkPool(true, releaseAll));
|
||||
}
|
||||
|
||||
/* static */ Chunk *
|
||||
|
@ -1056,7 +1064,7 @@ GCRuntime::wantBackgroundAllocation() const
|
|||
* of them.
|
||||
*/
|
||||
return helperState.canBackgroundAllocate() &&
|
||||
chunkPool.getEmptyCount() == 0 &&
|
||||
chunkPool.getEmptyCount() < MIN_EMPTY_CHUNK_COUNT &&
|
||||
chunkSet.count() >= 4;
|
||||
}
|
||||
|
||||
|
@ -2609,7 +2617,7 @@ GCRuntime::expireChunksAndArenas(bool shouldShrink)
|
|||
rt->threadPool.pruneChunkCache();
|
||||
#endif
|
||||
|
||||
if (Chunk *toFree = expireChunkPool(shouldShrink)) {
|
||||
if (Chunk *toFree = expireChunkPool(shouldShrink, false)) {
|
||||
AutoUnlockGC unlock(rt);
|
||||
freeChunkList(toFree);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче