5 #ifndef V8_HEAP_MARKING_H_ 6 #define V8_HEAP_MARKING_H_ 8 #include "src/base/atomic-utils.h" 17 STATIC_ASSERT(
sizeof(
CellType) ==
sizeof(base::Atomic32));
22 bool operator==(
const MarkBit& other) {
23 return cell_ == other.cell_ && mask_ == other.mask_;
33 return MarkBit(cell_, new_mask);
39 template <AccessMode mode = AccessMode::NON_ATOMIC>
42 template <AccessMode mode = AccessMode::NON_ATOMIC>
47 template <AccessMode mode = AccessMode::NON_ATOMIC>
54 friend class ConcurrentMarkingMarkbits;
59 inline bool MarkBit::Set<AccessMode::NON_ATOMIC>() {
60 CellType old_value = *cell_;
61 *cell_ = old_value | mask_;
62 return (old_value & mask_) == 0;
66 inline bool MarkBit::Set<AccessMode::ATOMIC>() {
67 return base::AsAtomic32::SetBits(cell_, mask_, mask_);
71 inline bool MarkBit::Get<AccessMode::NON_ATOMIC>() {
72 return (*cell_ & mask_) != 0;
76 inline bool MarkBit::Get<AccessMode::ATOMIC>() {
77 return (base::AsAtomic32::Acquire_Load(cell_) & mask_) != 0;
81 inline bool MarkBit::Clear<AccessMode::NON_ATOMIC>() {
82 CellType old_value = *cell_;
83 *cell_ = old_value & ~mask_;
84 return (old_value & mask_) == mask_;
88 inline bool MarkBit::Clear<AccessMode::ATOMIC>() {
89 return base::AsAtomic32::SetBits(cell_, 0u, mask_);
95 static const uint32_t kBitsPerCell = 32;
96 static const uint32_t kBitsPerCellLog2 = 5;
97 static const uint32_t kBitIndexMask = kBitsPerCell - 1;
98 static const uint32_t kBytesPerCell = kBitsPerCell / kBitsPerByte;
99 static const uint32_t kBytesPerCellLog2 = kBitsPerCellLog2 - kBitsPerByteLog2;
101 static const size_t kLength = (1 << kPageSizeBits) >> (kPointerSizeLog2);
103 static const size_t kSize = (1 << kPageSizeBits) >>
104 (kPointerSizeLog2 + kBitsPerByteLog2);
106 static int CellsForLength(
int length) {
107 return (length + kBitsPerCell - 1) >> kBitsPerCellLog2;
110 int CellsCount() {
return CellsForLength(kLength); }
113 return index >> kBitsPerCellLog2;
117 return index & kBitIndexMask;
122 return index & ~kBitIndexMask;
130 return reinterpret_cast<Bitmap*
>(addr);
145 template <AccessMode mode = AccessMode::NON_ATOMIC>
150 template <AccessMode mode = AccessMode::NON_ATOMIC>
175 inline void Bitmap::SetBitsInCell<AccessMode::NON_ATOMIC>(
uint32_t cell_index,
177 cells()[cell_index] |= mask;
181 inline void Bitmap::SetBitsInCell<AccessMode::ATOMIC>(
uint32_t cell_index,
183 base::AsAtomic32::SetBits(cells() + cell_index, mask, mask);
187 inline void Bitmap::ClearBitsInCell<AccessMode::NON_ATOMIC>(
uint32_t cell_index,
189 cells()[cell_index] &= ~mask;
193 inline void Bitmap::ClearBitsInCell<AccessMode::ATOMIC>(
uint32_t cell_index,
195 base::AsAtomic32::SetBits(cells() + cell_index, 0u, mask);
205 static const char* kImpossibleBitPattern;
206 template <AccessMode mode = AccessMode::NON_ATOMIC>
207 V8_INLINE
static bool IsImpossible(
MarkBit mark_bit) {
208 if (mode == AccessMode::NON_ATOMIC) {
209 return !mark_bit.Get<mode>() && mark_bit.Next().Get<mode>();
215 bool is_impossible = !mark_bit.Get<mode>() && mark_bit.Next().Get<mode>();
217 return !mark_bit.Get<mode>();
223 static const char* kBlackBitPattern;
224 template <AccessMode mode = AccessMode::NON_ATOMIC>
225 V8_INLINE
static bool IsBlack(
MarkBit mark_bit) {
226 return mark_bit.Get<mode>() && mark_bit.Next().Get<mode>();
230 static const char* kWhiteBitPattern;
231 template <AccessMode mode = AccessMode::NON_ATOMIC>
232 V8_INLINE
static bool IsWhite(
MarkBit mark_bit) {
233 DCHECK(!IsImpossible<mode>(mark_bit));
234 return !mark_bit.Get<mode>();
238 static const char* kGreyBitPattern;
239 template <AccessMode mode = AccessMode::NON_ATOMIC>
240 V8_INLINE
static bool IsGrey(
MarkBit mark_bit) {
241 return mark_bit.Get<mode>() && !mark_bit.Next().Get<mode>();
246 template <AccessMode mode = AccessMode::NON_ATOMIC>
247 V8_INLINE
static bool IsBlackOrGrey(
MarkBit mark_bit) {
248 return mark_bit.Get<mode>();
251 template <AccessMode mode = AccessMode::NON_ATOMIC>
252 V8_INLINE
static void MarkWhite(
MarkBit markbit) {
253 STATIC_ASSERT(mode == AccessMode::NON_ATOMIC);
254 markbit.Clear<mode>();
255 markbit.Next().Clear<mode>();
261 template <AccessMode mode = AccessMode::NON_ATOMIC>
262 V8_INLINE
static void MarkBlack(
MarkBit markbit) {
264 markbit.Next().Set<mode>();
267 template <AccessMode mode = AccessMode::NON_ATOMIC>
268 V8_INLINE
static bool WhiteToGrey(
MarkBit markbit) {
269 return markbit.Set<mode>();
272 template <AccessMode mode = AccessMode::NON_ATOMIC>
273 V8_INLINE
static bool WhiteToBlack(
MarkBit markbit) {
274 return markbit.Set<mode>() && markbit.Next().Set<mode>();
277 template <AccessMode mode = AccessMode::NON_ATOMIC>
278 V8_INLINE
static bool GreyToBlack(
MarkBit markbit) {
279 return markbit.Get<mode>() && markbit.Next().Set<mode>();
289 static const char* ColorName(ObjectColor color) {
297 case IMPOSSIBLE_COLOR:
303 static ObjectColor Color(
MarkBit mark_bit) {
304 if (IsBlack(mark_bit))
return BLACK_OBJECT;
305 if (IsWhite(mark_bit))
return WHITE_OBJECT;
306 if (IsGrey(mark_bit))
return GREY_OBJECT;
311 DISALLOW_IMPLICIT_CONSTRUCTORS(
Marking);
317 #endif // V8_HEAP_MARKING_H_