зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1799446 - Don't use atomic update operations when updating the mark bitmap r=jandem
The Atomic class supports operations such as |&=| that perform atomic updates on shared memory that are correct when performed concurrently with other such updates. This is unnecessary for the mark bitmap and results in sub-optimal code generation. Instead, updates can be done with separate read and write operations. Differential Revision: https://phabricator.services.mozilla.com/D161473
This commit is contained in:
Родитель
d84a6fb3b9
Коммит
f15a4185f4
|
@ -513,6 +513,16 @@ MOZ_ALWAYS_INLINE bool MarkBitmap::isMarkedGray(const TenuredCell* cell) {
|
|||
markBit(cell, ColorBit::GrayOrBlackBit);
|
||||
}
|
||||
|
||||
// The following methods that update the mark bits are not thread safe and must
|
||||
// not be called in parallel with each other.
|
||||
//
|
||||
// They use separate read and write operations to avoid an unnecessarily strict
|
||||
// atomic update on the marking bitmap.
|
||||
//
|
||||
// They may be called in parallel with read operations on the mark bitmap where
|
||||
// there is no required ordering between the operations. This happens when gray
|
||||
// unmarking occurs in parallel with background sweeping.
|
||||
|
||||
// The return value indicates if the cell went from unmarked to marked.
|
||||
MOZ_ALWAYS_INLINE bool MarkBitmap::markIfUnmarked(const TenuredCell* cell,
|
||||
MarkColor color) {
|
||||
|
@ -523,17 +533,17 @@ MOZ_ALWAYS_INLINE bool MarkBitmap::markIfUnmarked(const TenuredCell* cell,
|
|||
return false;
|
||||
}
|
||||
if (color == MarkColor::Black) {
|
||||
*word |= mask;
|
||||
uintptr_t bits = *word;
|
||||
*word = bits | mask;
|
||||
} else {
|
||||
/*
|
||||
* We use getMarkWordAndMask to recalculate both mask and word as
|
||||
* doing just mask << color may overflow the mask.
|
||||
*/
|
||||
// We use getMarkWordAndMask to recalculate both mask and word as doing just
|
||||
// mask << color may overflow the mask.
|
||||
getMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask);
|
||||
if (*word & mask) {
|
||||
return false;
|
||||
}
|
||||
*word |= mask;
|
||||
uintptr_t bits = *word;
|
||||
*word = bits | mask;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -542,7 +552,8 @@ MOZ_ALWAYS_INLINE void MarkBitmap::markBlack(const TenuredCell* cell) {
|
|||
MarkBitmapWord* word;
|
||||
uintptr_t mask;
|
||||
getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask);
|
||||
*word |= mask;
|
||||
uintptr_t bits = *word;
|
||||
*word = bits | mask;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void MarkBitmap::copyMarkBit(TenuredCell* dst,
|
||||
|
@ -557,19 +568,24 @@ MOZ_ALWAYS_INLINE void MarkBitmap::copyMarkBit(TenuredCell* dst,
|
|||
uintptr_t dstMask;
|
||||
getMarkWordAndMask(dst, colorBit, &dstWord, &dstMask);
|
||||
|
||||
*dstWord &= ~dstMask;
|
||||
uintptr_t bits = *dstWord;
|
||||
bits &= ~dstMask;
|
||||
if (*srcWord & srcMask) {
|
||||
*dstWord |= dstMask;
|
||||
bits |= dstMask;
|
||||
}
|
||||
*dstWord = bits;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE void MarkBitmap::unmark(const TenuredCell* cell) {
|
||||
MarkBitmapWord* word;
|
||||
uintptr_t mask;
|
||||
uintptr_t bits;
|
||||
getMarkWordAndMask(cell, ColorBit::BlackBit, &word, &mask);
|
||||
*word &= ~mask;
|
||||
bits = *word;
|
||||
*word = bits & ~mask;
|
||||
getMarkWordAndMask(cell, ColorBit::GrayOrBlackBit, &word, &mask);
|
||||
*word &= ~mask;
|
||||
bits = *word;
|
||||
*word = bits & ~mask;
|
||||
}
|
||||
|
||||
inline MarkBitmapWord* MarkBitmap::arenaBits(Arena* arena) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче