зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1566859 - Update memory accounting information for held relocated arenas sooner r=sfink?
Differential Revision: https://phabricator.services.mozilla.com/D38373 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
b6b88ec85d
Коммит
e15efe8db1
|
@ -908,10 +908,6 @@ void Chunk::recycleArena(Arena* arena, SortedArenaList& dest,
|
|||
}
|
||||
|
||||
void Chunk::releaseArena(JSRuntime* rt, Arena* arena, const AutoLockGC& lock) {
|
||||
MOZ_ASSERT(arena->allocated());
|
||||
MOZ_ASSERT(!arena->onDelayedMarkingList());
|
||||
|
||||
arena->release(lock);
|
||||
addArenaToFreeList(rt, arena);
|
||||
updateChunkListAfterFree(rt, lock);
|
||||
}
|
||||
|
@ -973,10 +969,14 @@ void Chunk::updateChunkListAfterFree(JSRuntime* rt, const AutoLockGC& lock) {
|
|||
}
|
||||
|
||||
void GCRuntime::releaseArena(Arena* arena, const AutoLockGC& lock) {
|
||||
MOZ_ASSERT(arena->allocated());
|
||||
MOZ_ASSERT(!arena->onDelayedMarkingList());
|
||||
|
||||
arena->zone->zoneSize.removeGCArena();
|
||||
if (arena->zone->wasGCStarted()) {
|
||||
stats().recordFreedArena();
|
||||
}
|
||||
arena->release(lock);
|
||||
arena->chunk()->releaseArena(rt, arena, lock);
|
||||
}
|
||||
|
||||
|
@ -3079,36 +3079,15 @@ void GCRuntime::updateRuntimePointersToRelocatedCells(AutoGCSession& session) {
|
|||
callWeakPointerZonesCallbacks();
|
||||
}
|
||||
|
||||
void GCRuntime::protectAndHoldArenas(Arena* arenaList) {
|
||||
for (Arena* arena = arenaList; arena;) {
|
||||
MOZ_ASSERT(arena->allocated());
|
||||
Arena* next = arena->next;
|
||||
if (!next) {
|
||||
// Prepend to hold list before we protect the memory.
|
||||
arena->next = relocatedArenasToRelease;
|
||||
relocatedArenasToRelease = arenaList;
|
||||
}
|
||||
ProtectPages(arena, ArenaSize);
|
||||
arena = next;
|
||||
}
|
||||
}
|
||||
|
||||
void GCRuntime::unprotectHeldRelocatedArenas() {
|
||||
for (Arena* arena = relocatedArenasToRelease; arena; arena = arena->next) {
|
||||
UnprotectPages(arena, ArenaSize);
|
||||
MOZ_ASSERT(arena->allocated());
|
||||
}
|
||||
}
|
||||
|
||||
void GCRuntime::releaseRelocatedArenas(Arena* arenaList) {
|
||||
void GCRuntime::clearRelocatedArenas(Arena* arenaList, JS::GCReason reason) {
|
||||
AutoLockGC lock(rt);
|
||||
releaseRelocatedArenasWithoutUnlocking(arenaList, lock);
|
||||
clearRelocatedArenasWithoutUnlocking(arenaList, reason, lock);
|
||||
}
|
||||
|
||||
void GCRuntime::releaseRelocatedArenasWithoutUnlocking(Arena* arenaList,
|
||||
const AutoLockGC& lock) {
|
||||
// Release the relocated arenas, now containing only forwarding pointers
|
||||
unsigned count = 0;
|
||||
void GCRuntime::clearRelocatedArenasWithoutUnlocking(Arena* arenaList,
|
||||
JS::GCReason reason,
|
||||
const AutoLockGC& lock) {
|
||||
// Clear the relocated arenas, now containing only forwarding pointers
|
||||
while (arenaList) {
|
||||
Arena* arena = arenaList;
|
||||
arenaList = arenaList->next;
|
||||
|
@ -3123,8 +3102,55 @@ void GCRuntime::releaseRelocatedArenasWithoutUnlocking(Arena* arenaList,
|
|||
JS_MOVED_TENURED_PATTERN, arena->getThingsSpan(),
|
||||
MemCheckKind::MakeNoAccess);
|
||||
|
||||
releaseArena(arena, lock);
|
||||
++count;
|
||||
arena->zone->zoneSize.removeGCArena();
|
||||
|
||||
// Don't count arenas as freed if we purposely moved everything to new
|
||||
// arenas.
|
||||
if (!ShouldRelocateAllArenas(reason) && arena->zone->wasGCStarted()) {
|
||||
stats().recordFreedArena();
|
||||
}
|
||||
|
||||
// Release the arena but don't return it to the chunk yet.
|
||||
arena->release(lock);
|
||||
}
|
||||
}
|
||||
|
||||
void GCRuntime::protectAndHoldArenas(Arena* arenaList) {
|
||||
for (Arena* arena = arenaList; arena;) {
|
||||
MOZ_ASSERT(!arena->allocated());
|
||||
Arena* next = arena->next;
|
||||
if (!next) {
|
||||
// Prepend to hold list before we protect the memory.
|
||||
arena->next = relocatedArenasToRelease;
|
||||
relocatedArenasToRelease = arenaList;
|
||||
}
|
||||
ProtectPages(arena, ArenaSize);
|
||||
arena = next;
|
||||
}
|
||||
}
|
||||
|
||||
void GCRuntime::unprotectHeldRelocatedArenas() {
|
||||
for (Arena* arena = relocatedArenasToRelease; arena; arena = arena->next) {
|
||||
UnprotectPages(arena, ArenaSize);
|
||||
MOZ_ASSERT(!arena->allocated());
|
||||
}
|
||||
}
|
||||
|
||||
void GCRuntime::releaseRelocatedArenas(Arena* arenaList) {
|
||||
AutoLockGC lock(rt);
|
||||
releaseRelocatedArenasWithoutUnlocking(arenaList, lock);
|
||||
}
|
||||
|
||||
void GCRuntime::releaseRelocatedArenasWithoutUnlocking(Arena* arenaList,
|
||||
const AutoLockGC& lock) {
|
||||
// Release relocated arenas previously cleared with clearRelocatedArenas().
|
||||
while (arenaList) {
|
||||
Arena* arena = arenaList;
|
||||
arenaList = arenaList->next;
|
||||
|
||||
// We already updated the memory accounting so just call
|
||||
// Chunk::releaseArena.
|
||||
arena->chunk()->releaseArena(rt, arena, lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6862,6 +6888,8 @@ IncrementalProgress GCRuntime::compactPhase(JS::GCReason reason,
|
|||
} while (!relocatedZones.isEmpty());
|
||||
}
|
||||
|
||||
clearRelocatedArenas(relocatedArenas, reason);
|
||||
|
||||
if (ShouldProtectRelocatedArenas(reason)) {
|
||||
protectAndHoldArenas(relocatedArenas);
|
||||
} else {
|
||||
|
|
|
@ -690,6 +690,10 @@ class GCRuntime {
|
|||
void updateRuntimePointersToRelocatedCells(AutoGCSession& session);
|
||||
void protectAndHoldArenas(Arena* arenaList);
|
||||
void unprotectHeldRelocatedArenas();
|
||||
void clearRelocatedArenas(Arena* arenaList, JS::GCReason reason);
|
||||
void clearRelocatedArenasWithoutUnlocking(Arena* arenaList,
|
||||
JS::GCReason reason,
|
||||
const AutoLockGC& lock);
|
||||
void releaseRelocatedArenas(Arena* arenaList);
|
||||
void releaseRelocatedArenasWithoutUnlocking(Arena* arenaList,
|
||||
const AutoLockGC& lock);
|
||||
|
|
Загрузка…
Ссылка в новой задаче