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:
Jon Coppeard 2019-07-18 22:35:17 +00:00
Родитель b6b88ec85d
Коммит e15efe8db1
2 изменённых файлов: 65 добавлений и 33 удалений

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

@ -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);