зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1093307 - Part 2: Make OOM flushing paths more straightforward; r=jonco
--HG-- extra : rebase_source : 4634215f64ea96c2057f4ff609119b2a6cad008f
This commit is contained in:
Родитель
d6d15a2f78
Коммит
b0ef029ce6
|
@ -498,7 +498,7 @@ class GCRuntime
|
|||
* Must be called either during the GC or with the GC lock taken.
|
||||
*/
|
||||
Chunk *expireEmptyChunkPool(bool shrinkBuffers, const AutoLockGC &lock);
|
||||
void freeEmptyChunks(JSRuntime *rt);
|
||||
void freeEmptyChunks(JSRuntime *rt, const AutoLockGC &lock);
|
||||
void freeChunkList(Chunk *chunkListHead);
|
||||
void prepareToFreeChunk(ChunkInfo &info);
|
||||
void releaseChunk(Chunk *chunk);
|
||||
|
@ -543,6 +543,7 @@ class GCRuntime
|
|||
bool sweepPhase(SliceBudget &sliceBudget);
|
||||
void endSweepPhase(bool lastGC);
|
||||
void sweepZones(FreeOp *fop, bool lastGC);
|
||||
void decommitAllWithoutUnlocking(const AutoLockGC &lock);
|
||||
void decommitArenasFromAvailableList(Chunk **availableListHeadp);
|
||||
void decommitArenas();
|
||||
void expireChunksAndArenas(bool shouldShrink, const AutoLockGC &lock);
|
||||
|
|
|
@ -744,15 +744,22 @@ GCRuntime::expireEmptyChunkPool(bool shrinkBuffers, const AutoLockGC &lock)
|
|||
return freeList;
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::freeEmptyChunks(JSRuntime *rt)
|
||||
static void
|
||||
FreeChunkPool(JSRuntime *rt, ChunkPool &pool)
|
||||
{
|
||||
for (ChunkPool::Enum e(emptyChunks_); !e.empty();) {
|
||||
for (ChunkPool::Enum e(pool); !e.empty();) {
|
||||
Chunk *chunk = e.front();
|
||||
e.removeAndPopFront();
|
||||
MOZ_ASSERT(!chunk->info.numArenasFreeCommitted);
|
||||
FreeChunk(rt, chunk);
|
||||
}
|
||||
MOZ_ASSERT(pool.count() == 0);
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::freeEmptyChunks(JSRuntime *rt, const AutoLockGC &lock)
|
||||
{
|
||||
FreeChunkPool(rt, emptyChunks(lock));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1422,7 +1429,7 @@ GCRuntime::finish()
|
|||
chunkSet.clear();
|
||||
}
|
||||
|
||||
freeEmptyChunks(rt);
|
||||
FreeChunkPool(rt, emptyChunks_);
|
||||
|
||||
if (rootsHash.initialized())
|
||||
rootsHash.clear();
|
||||
|
@ -3122,6 +3129,25 @@ GCRuntime::maybePeriodicFullGC()
|
|||
#endif
|
||||
}
|
||||
|
||||
// Do all possible decommit immediately from the current thread without
|
||||
// releasing the GC lock or allocating any memory.
|
||||
void
|
||||
GCRuntime::decommitAllWithoutUnlocking(const AutoLockGC &lock)
|
||||
{
|
||||
MOZ_ASSERT(emptyChunks(lock).count() == 0);
|
||||
for (Chunk *chunk = *getAvailableChunkList(); chunk; chunk = chunk->info.next) {
|
||||
for (size_t i = 0; i < ArenasPerChunk; ++i) {
|
||||
if (chunk->decommittedArenas.get(i) || chunk->arenas[i].aheader.allocated())
|
||||
continue;
|
||||
|
||||
if (MarkPagesUnused(&chunk->arenas[i], ArenaSize)) {
|
||||
chunk->info.numArenasFreeCommitted--;
|
||||
chunk->decommittedArenas.set(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::decommitArenasFromAvailableList(Chunk **availableListHeadp)
|
||||
{
|
||||
|
@ -6216,7 +6242,12 @@ GCRuntime::onOutOfMallocMemory()
|
|||
|
||||
// Throw away any excess chunks we have lying around.
|
||||
AutoLockGC lock(rt);
|
||||
expireChunksAndArenas(true, lock);
|
||||
freeEmptyChunks(rt, lock);
|
||||
|
||||
// Immediately decommit as many arenas as possible in the hopes that this
|
||||
// might let the OS scrape together enough pages to satisfy the failing
|
||||
// malloc request.
|
||||
decommitAllWithoutUnlocking(lock);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Загрузка…
Ссылка в новой задаче