From 93420d0a2a9232e24cbd598f4341c23230a8e2c7 Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Tue, 19 Jan 2021 15:20:25 +0000 Subject: [PATCH] Bug 1687002 - Fix incremental marking validator r=sfink This patch makes ChunkBitmap::getMarkWordAndMask into an instance method so that the uses in MarkingValidator access the correct bitmap. Depends on D101778 Differential Revision: https://phabricator.services.mozilla.com/D102207 --- js/public/HeapAPI.h | 25 ++++++++++++++----------- js/src/gc/Heap.h | 21 +++++++++++---------- js/src/gc/Marking.cpp | 8 +++++--- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h index 667db4bb1a7b..51f80e0192fb 100644 --- a/js/public/HeapAPI.h +++ b/js/public/HeapAPI.h @@ -220,10 +220,8 @@ struct ChunkBitmap { static constexpr size_t WordCount = ArenaBitmapWords * ArenasPerChunk; MarkBitmapWord bitmap[WordCount]; - static inline void GetMarkWordAndMask(const TenuredCell* cell, - ColorBit colorBit, - MarkBitmapWord** wordp, - uintptr_t* maskp); + inline void getMarkWordAndMask(const TenuredCell* cell, ColorBit colorBit, + MarkBitmapWord** wordp, uintptr_t* maskp); // The following are not exported and are defined in gc/Heap.h: inline bool markBit(const TenuredCell* cell, ColorBit colorBit); @@ -518,7 +516,7 @@ namespace js { namespace gc { /* static */ -MOZ_ALWAYS_INLINE void ChunkBitmap::GetMarkWordAndMask(const TenuredCell* cell, +MOZ_ALWAYS_INLINE void ChunkBitmap::getMarkWordAndMask(const TenuredCell* cell, ColorBit colorBit, MarkBitmapWord** wordp, uintptr_t* maskp) { @@ -527,12 +525,11 @@ MOZ_ALWAYS_INLINE void ChunkBitmap::GetMarkWordAndMask(const TenuredCell* cell, MOZ_ASSERT(size_t(colorBit) < MarkBitsPerCell); - auto* chunk = reinterpret_cast(uintptr_t(cell) & ~ChunkMask); size_t offset = uintptr_t(cell) & ChunkMask; const size_t bit = offset / CellBytesPerMarkBit + size_t(colorBit); size_t word = bit / MarkBitmapWordBits - FirstArenaAdjustmentWords; MOZ_ASSERT(word < WordCount); - *wordp = &chunk->bitmap.bitmap[word]; + *wordp = &bitmap[word]; *maskp = uintptr_t(1) << (bit % MarkBitmapWordBits); } @@ -543,6 +540,11 @@ static MOZ_ALWAYS_INLINE ChunkHeader* GetCellChunkHeader(const Cell* cell) { return reinterpret_cast(uintptr_t(cell) & ~ChunkMask); } +static MOZ_ALWAYS_INLINE ChunkBase* GetCellChunkBase(const TenuredCell* cell) { + MOZ_ASSERT(cell); + return reinterpret_cast(uintptr_t(cell) & ~ChunkMask); +} + static MOZ_ALWAYS_INLINE JS::Zone* GetTenuredGCThingZone(const uintptr_t addr) { MOZ_ASSERT(addr); const uintptr_t zone_addr = (addr & ~ArenaMask) | ArenaZoneOffset; @@ -556,16 +558,17 @@ static MOZ_ALWAYS_INLINE bool TenuredCellIsMarkedGray(const TenuredCell* cell) { MarkBitmapWord* grayWord; uintptr_t grayMask; - ChunkBitmap::GetMarkWordAndMask(cell, js::gc::ColorBit::GrayOrBlackBit, - &grayWord, &grayMask); + ChunkBase* chunk = GetCellChunkBase(cell); + chunk->bitmap.getMarkWordAndMask(cell, js::gc::ColorBit::GrayOrBlackBit, + &grayWord, &grayMask); if (!(*grayWord & grayMask)) { return false; } MarkBitmapWord* blackWord; uintptr_t blackMask; - ChunkBitmap::GetMarkWordAndMask(cell, js::gc::ColorBit::BlackBit, &blackWord, - &blackMask); + chunk->bitmap.getMarkWordAndMask(cell, js::gc::ColorBit::BlackBit, &blackWord, + &blackMask); return !(*blackWord & blackMask); } diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index cbef9012eff1..13bb881c0693 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -491,7 +491,7 @@ MOZ_ALWAYS_INLINE bool ChunkBitmap::markBit(const TenuredCell* cell, ColorBit colorBit) { MarkBitmapWord* word; uintptr_t mask; - GetMarkWordAndMask(cell, colorBit, &word, &mask); + getMarkWordAndMask(cell, colorBit, &word, &mask); return *word & mask; } @@ -514,7 +514,7 @@ MOZ_ALWAYS_INLINE bool ChunkBitmap::markIfUnmarked(const TenuredCell* cell, MarkColor color) { MarkBitmapWord* word; uintptr_t mask; - GetMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); + getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); if (*word & mask) { return false; } @@ -522,10 +522,10 @@ MOZ_ALWAYS_INLINE bool ChunkBitmap::markIfUnmarked(const TenuredCell* cell, *word |= mask; } else { /* - * We use GetMarkWordAndMask to recalculate both mask and word as + * We use getMarkWordAndMask to recalculate both mask and word as * doing just mask << color may overflow the mask. */ - GetMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask); + getMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask); if (*word & mask) { return false; } @@ -537,20 +537,21 @@ MOZ_ALWAYS_INLINE bool ChunkBitmap::markIfUnmarked(const TenuredCell* cell, MOZ_ALWAYS_INLINE void ChunkBitmap::markBlack(const TenuredCell* cell) { MarkBitmapWord* word; uintptr_t mask; - GetMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); + getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); *word |= mask; } MOZ_ALWAYS_INLINE void ChunkBitmap::copyMarkBit(TenuredCell* dst, const TenuredCell* src, ColorBit colorBit) { + ChunkBase* srcChunk = detail::GetCellChunkBase(src); MarkBitmapWord* srcWord; uintptr_t srcMask; - GetMarkWordAndMask(src, colorBit, &srcWord, &srcMask); + srcChunk->bitmap.getMarkWordAndMask(src, colorBit, &srcWord, &srcMask); MarkBitmapWord* dstWord; uintptr_t dstMask; - GetMarkWordAndMask(dst, colorBit, &dstWord, &dstMask); + getMarkWordAndMask(dst, colorBit, &dstWord, &dstMask); *dstWord &= ~dstMask; if (*srcWord & srcMask) { @@ -561,9 +562,9 @@ MOZ_ALWAYS_INLINE void ChunkBitmap::copyMarkBit(TenuredCell* dst, MOZ_ALWAYS_INLINE void ChunkBitmap::unmark(const TenuredCell* cell) { MarkBitmapWord* word; uintptr_t mask; - GetMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); + getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask); *word &= ~mask; - GetMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask); + getMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask); *word &= ~mask; } @@ -582,7 +583,7 @@ inline MarkBitmapWord* ChunkBitmap::arenaBits(Arena* arena) { MarkBitmapWord* word; uintptr_t unused; - GetMarkWordAndMask(reinterpret_cast(arena->address()), + getMarkWordAndMask(reinterpret_cast(arena->address()), ColorBit::BlackBit, &word, &unused); return word; } diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 66d82ced5040..f44e2df6cead 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -4106,8 +4106,9 @@ uintptr_t* GetMarkWordAddress(Cell* cell) { MarkBitmapWord* wordp; uintptr_t mask; - ChunkBitmap::GetMarkWordAndMask(&cell->asTenured(), ColorBit::BlackBit, - &wordp, &mask); + ChunkBase* chunk = gc::detail::GetCellChunkBase(&cell->asTenured()); + chunk->bitmap.getMarkWordAndMask(&cell->asTenured(), ColorBit::BlackBit, + &wordp, &mask); return reinterpret_cast(wordp); } @@ -4121,7 +4122,8 @@ uintptr_t GetMarkMask(Cell* cell, uint32_t colorBit) { ColorBit bit = colorBit == 0 ? ColorBit::BlackBit : ColorBit::GrayOrBlackBit; MarkBitmapWord* wordp; uintptr_t mask; - ChunkBitmap::GetMarkWordAndMask(&cell->asTenured(), bit, &wordp, &mask); + ChunkBase* chunk = gc::detail::GetCellChunkBase(&cell->asTenured()); + chunk->bitmap.getMarkWordAndMask(&cell->asTenured(), bit, &wordp, &mask); return mask; }