зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1850746 - Part 5: Factor out conversion between arena and page indexes r=sfink
This also adds an assertion that the first arena is on a page boundary which is required for decommit to work correctly. Differential Revision: https://phabricator.services.mozilla.com/D220414
This commit is contained in:
Родитель
049c5b2513
Коммит
ee9156bab2
|
@ -524,7 +524,7 @@ void ArenaChunk::commitOnePage(GCRuntime* gc) {
|
|||
decommittedPages[pageIndex] = false;
|
||||
|
||||
for (size_t i = 0; i < ArenasPerPage; i++) {
|
||||
size_t arenaIndex = pageIndex * ArenasPerPage + i;
|
||||
size_t arenaIndex = pageToArenaIndex(pageIndex) + i;
|
||||
MOZ_ASSERT(!freeCommittedArenas[arenaIndex]);
|
||||
freeCommittedArenas[arenaIndex] = true;
|
||||
++info.numArenasFreeCommitted;
|
||||
|
|
|
@ -94,7 +94,7 @@ const uint8_t Arena::ThingsPerArena[] = {
|
|||
|
||||
bool Arena::allocated() const {
|
||||
size_t arenaIndex = ArenaChunk::arenaIndex(this);
|
||||
size_t pageIndex = arenaIndex / ArenasPerPage;
|
||||
size_t pageIndex = ArenaChunk::arenaToPageIndex(arenaIndex);
|
||||
bool result = !chunk()->decommittedPages[pageIndex] &&
|
||||
!chunk()->freeCommittedArenas[arenaIndex] &&
|
||||
IsValidAllocKind(allocKind);
|
||||
|
@ -321,7 +321,7 @@ inline bool ArenaChunk::canDecommitPage(size_t pageIndex) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t arenaIndex = pageIndex * ArenasPerPage;
|
||||
size_t arenaIndex = pageToArenaIndex(pageIndex);
|
||||
for (size_t i = 0; i < ArenasPerPage; i++) {
|
||||
if (!freeCommittedArenas[arenaIndex + i]) {
|
||||
return false;
|
||||
|
@ -374,7 +374,7 @@ bool ArenaChunk::decommitOneFreePage(GCRuntime* gc, size_t pageIndex,
|
|||
|
||||
// Temporarily mark the page as allocated while we decommit.
|
||||
for (size_t i = 0; i < ArenasPerPage; i++) {
|
||||
size_t arenaIndex = pageIndex * ArenasPerPage + i;
|
||||
size_t arenaIndex = pageToArenaIndex(pageIndex) + i;
|
||||
MOZ_ASSERT(freeCommittedArenas[arenaIndex]);
|
||||
freeCommittedArenas[arenaIndex] = false;
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ bool ArenaChunk::decommitOneFreePage(GCRuntime* gc, size_t pageIndex,
|
|||
decommittedPages[pageIndex] = true;
|
||||
} else {
|
||||
for (size_t i = 0; i < ArenasPerPage; i++) {
|
||||
size_t arenaIndex = pageIndex * ArenasPerPage + i;
|
||||
size_t arenaIndex = pageToArenaIndex(pageIndex) + i;
|
||||
MOZ_ASSERT(!freeCommittedArenas[arenaIndex]);
|
||||
freeCommittedArenas[arenaIndex] = true;
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ void ArenaChunk::decommitFreeArenasWithoutUnlocking(const AutoLockGC& lock) {
|
|||
|
||||
decommittedPages[i] = true;
|
||||
for (size_t j = 0; j < ArenasPerPage; ++j) {
|
||||
size_t arenaIndex = i * ArenasPerPage + j;
|
||||
size_t arenaIndex = pageToArenaIndex(i) + j;
|
||||
MOZ_ASSERT(freeCommittedArenas[arenaIndex]);
|
||||
freeCommittedArenas[arenaIndex] = false;
|
||||
}
|
||||
|
@ -636,7 +636,8 @@ void ArenaChunk::verify() const {
|
|||
MOZ_ASSERT(freeCommittedCount == info.numArenasFreeCommitted);
|
||||
|
||||
for (size_t i = 0; i < ArenasPerChunk; ++i) {
|
||||
MOZ_ASSERT(!(decommittedPages[pageIndex(i)] && freeCommittedArenas[i]));
|
||||
MOZ_ASSERT(
|
||||
!(decommittedPages[arenaToPageIndex(i)] && freeCommittedArenas[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -491,6 +491,20 @@ class ArenaChunk : public ArenaChunkBase {
|
|||
return (offset - offsetof(ArenaChunk, arenas)) >> ArenaShift;
|
||||
}
|
||||
|
||||
static size_t pageIndex(const Arena* arena) {
|
||||
return arenaToPageIndex(arenaIndex(arena));
|
||||
}
|
||||
|
||||
static size_t arenaToPageIndex(size_t arenaIndex) {
|
||||
static_assert((offsetof(ArenaChunk, arenas) % PageSize) == 0,
|
||||
"First arena should be on a page boundary");
|
||||
return arenaIndex / ArenasPerPage;
|
||||
}
|
||||
|
||||
static size_t pageToArenaIndex(size_t pageIndex) {
|
||||
return pageIndex * ArenasPerPage;
|
||||
}
|
||||
|
||||
explicit ArenaChunk(JSRuntime* runtime) : ArenaChunkBase(runtime) {}
|
||||
|
||||
uintptr_t address() const {
|
||||
|
@ -549,16 +563,8 @@ class ArenaChunk : public ArenaChunkBase {
|
|||
// build.
|
||||
bool isPageFree(const Arena* arena) const;
|
||||
|
||||
// Get the page index of the arena.
|
||||
size_t pageIndex(const Arena* arena) const {
|
||||
return pageIndex(arenaIndex(arena));
|
||||
}
|
||||
size_t pageIndex(size_t arenaIndex) const {
|
||||
return arenaIndex / ArenasPerPage;
|
||||
}
|
||||
|
||||
Arena* pageAddress(size_t pageIndex) {
|
||||
return &arenas[pageIndex * ArenasPerPage];
|
||||
void* pageAddress(size_t pageIndex) {
|
||||
return &arenas[pageToArenaIndex(pageIndex)];
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -692,7 +692,8 @@ void js::gc::MarkingValidator::validate() {
|
|||
ChunkMarkBitmap* incBitmap = &chunk->markBits;
|
||||
|
||||
for (size_t i = 0; i < ArenasPerChunk; i++) {
|
||||
if (chunk->decommittedPages[chunk->pageIndex(i)]) {
|
||||
size_t pageIndex = ArenaChunk::arenaToPageIndex(i);
|
||||
if (chunk->decommittedPages[pageIndex]) {
|
||||
continue;
|
||||
}
|
||||
Arena* arena = &chunk->arenas[i];
|
||||
|
|
Загрузка…
Ссылка в новой задаче