V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
marking.cc
1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/heap/marking.h"
6 
7 namespace v8 {
8 namespace internal {
9 
10 void Bitmap::Clear() {
11  base::Atomic32* cell_base = reinterpret_cast<base::Atomic32*>(cells());
12  for (int i = 0; i < CellsCount(); i++) {
13  base::Relaxed_Store(cell_base + i, 0);
14  }
15  // This fence prevents re-ordering of publishing stores with the mark-bit
16  // clearing stores.
17  base::SeqCst_MemoryFence();
18 }
19 
20 void Bitmap::MarkAllBits() {
21  base::Atomic32* cell_base = reinterpret_cast<base::Atomic32*>(cells());
22  for (int i = 0; i < CellsCount(); i++) {
23  base::Relaxed_Store(cell_base + i, 0xffffffff);
24  }
25  // This fence prevents re-ordering of publishing stores with the mark-bit
26  // clearing stores.
27  base::SeqCst_MemoryFence();
28 }
29 
30 void Bitmap::SetRange(uint32_t start_index, uint32_t end_index) {
31  if (start_index >= end_index) return;
32  end_index--;
33 
34  unsigned int start_cell_index = start_index >> Bitmap::kBitsPerCellLog2;
35  MarkBit::CellType start_index_mask = 1u << Bitmap::IndexInCell(start_index);
36  unsigned int end_cell_index = end_index >> Bitmap::kBitsPerCellLog2;
37  MarkBit::CellType end_index_mask = 1u << Bitmap::IndexInCell(end_index);
38  if (start_cell_index != end_cell_index) {
39  // Firstly, fill all bits from the start address to the end of the first
40  // cell with 1s.
41  SetBitsInCell<AccessMode::ATOMIC>(start_cell_index,
42  ~(start_index_mask - 1));
43  // Then fill all in between cells with 1s.
44  base::Atomic32* cell_base = reinterpret_cast<base::Atomic32*>(cells());
45  for (unsigned int i = start_cell_index + 1; i < end_cell_index; i++) {
46  base::Relaxed_Store(cell_base + i, ~0u);
47  }
48  // Finally, fill all bits until the end address in the last cell with 1s.
49  SetBitsInCell<AccessMode::ATOMIC>(end_cell_index,
50  end_index_mask | (end_index_mask - 1));
51  } else {
52  SetBitsInCell<AccessMode::ATOMIC>(
53  start_cell_index, end_index_mask | (end_index_mask - start_index_mask));
54  }
55  // This fence prevents re-ordering of publishing stores with the mark-
56  // bit setting stores.
57  base::SeqCst_MemoryFence();
58 }
59 
60 void Bitmap::ClearRange(uint32_t start_index, uint32_t end_index) {
61  if (start_index >= end_index) return;
62  end_index--;
63 
64  unsigned int start_cell_index = start_index >> Bitmap::kBitsPerCellLog2;
65  MarkBit::CellType start_index_mask = 1u << Bitmap::IndexInCell(start_index);
66 
67  unsigned int end_cell_index = end_index >> Bitmap::kBitsPerCellLog2;
68  MarkBit::CellType end_index_mask = 1u << Bitmap::IndexInCell(end_index);
69 
70  if (start_cell_index != end_cell_index) {
71  // Firstly, fill all bits from the start address to the end of the first
72  // cell with 0s.
73  ClearBitsInCell<AccessMode::ATOMIC>(start_cell_index,
74  ~(start_index_mask - 1));
75  // Then fill all in between cells with 0s.
76  base::Atomic32* cell_base = reinterpret_cast<base::Atomic32*>(cells());
77  for (unsigned int i = start_cell_index + 1; i < end_cell_index; i++) {
78  base::Relaxed_Store(cell_base + i, 0);
79  }
80  // Finally, set all bits until the end address in the last cell with 0s.
81  ClearBitsInCell<AccessMode::ATOMIC>(end_cell_index,
82  end_index_mask | (end_index_mask - 1));
83  } else {
84  ClearBitsInCell<AccessMode::ATOMIC>(
85  start_cell_index, end_index_mask | (end_index_mask - start_index_mask));
86  }
87  // This fence prevents re-ordering of publishing stores with the mark-
88  // bit clearing stores.
89  base::SeqCst_MemoryFence();
90 }
91 
92 bool Bitmap::AllBitsSetInRange(uint32_t start_index, uint32_t end_index) {
93  if (start_index >= end_index) return false;
94  end_index--;
95 
96  unsigned int start_cell_index = start_index >> Bitmap::kBitsPerCellLog2;
97  MarkBit::CellType start_index_mask = 1u << Bitmap::IndexInCell(start_index);
98 
99  unsigned int end_cell_index = end_index >> Bitmap::kBitsPerCellLog2;
100  MarkBit::CellType end_index_mask = 1u << Bitmap::IndexInCell(end_index);
101 
102  MarkBit::CellType matching_mask;
103  if (start_cell_index != end_cell_index) {
104  matching_mask = ~(start_index_mask - 1);
105  if ((cells()[start_cell_index] & matching_mask) != matching_mask) {
106  return false;
107  }
108  for (unsigned int i = start_cell_index + 1; i < end_cell_index; i++) {
109  if (cells()[i] != ~0u) return false;
110  }
111  matching_mask = end_index_mask | (end_index_mask - 1);
112  return ((cells()[end_cell_index] & matching_mask) == matching_mask);
113  } else {
114  matching_mask = end_index_mask | (end_index_mask - start_index_mask);
115  return (cells()[end_cell_index] & matching_mask) == matching_mask;
116  }
117 }
118 
119 bool Bitmap::AllBitsClearInRange(uint32_t start_index, uint32_t end_index) {
120  if (start_index >= end_index) return true;
121  end_index--;
122 
123  unsigned int start_cell_index = start_index >> Bitmap::kBitsPerCellLog2;
124  MarkBit::CellType start_index_mask = 1u << Bitmap::IndexInCell(start_index);
125 
126  unsigned int end_cell_index = end_index >> Bitmap::kBitsPerCellLog2;
127  MarkBit::CellType end_index_mask = 1u << Bitmap::IndexInCell(end_index);
128 
129  MarkBit::CellType matching_mask;
130  if (start_cell_index != end_cell_index) {
131  matching_mask = ~(start_index_mask - 1);
132  if ((cells()[start_cell_index] & matching_mask)) return false;
133  for (unsigned int i = start_cell_index + 1; i < end_cell_index; i++) {
134  if (cells()[i]) return false;
135  }
136  matching_mask = end_index_mask | (end_index_mask - 1);
137  return !(cells()[end_cell_index] & matching_mask);
138  } else {
139  matching_mask = end_index_mask | (end_index_mask - start_index_mask);
140  return !(cells()[end_cell_index] & matching_mask);
141  }
142 }
143 
144 namespace {
145 
146 void PrintWord(uint32_t word, uint32_t himask = 0) {
147  for (uint32_t mask = 1; mask != 0; mask <<= 1) {
148  if ((mask & himask) != 0) PrintF("[");
149  PrintF((mask & word) ? "1" : "0");
150  if ((mask & himask) != 0) PrintF("]");
151  }
152 }
153 
154 class CellPrinter {
155  public:
156  CellPrinter() : seq_start(0), seq_type(0), seq_length(0) {}
157 
158  void Print(uint32_t pos, uint32_t cell) {
159  if (cell == seq_type) {
160  seq_length++;
161  return;
162  }
163 
164  Flush();
165 
166  if (IsSeq(cell)) {
167  seq_start = pos;
168  seq_length = 0;
169  seq_type = cell;
170  return;
171  }
172 
173  PrintF("%d: ", pos);
174  PrintWord(cell);
175  PrintF("\n");
176  }
177 
178  void Flush() {
179  if (seq_length > 0) {
180  PrintF("%d: %dx%d\n", seq_start, seq_type == 0 ? 0 : 1,
181  seq_length * Bitmap::kBitsPerCell);
182  seq_length = 0;
183  }
184  }
185 
186  static bool IsSeq(uint32_t cell) { return cell == 0 || cell == 0xFFFFFFFF; }
187 
188  private:
189  uint32_t seq_start;
190  uint32_t seq_type;
191  uint32_t seq_length;
192 };
193 
194 } // anonymous namespace
195 
196 void Bitmap::Print() {
197  CellPrinter printer;
198  for (int i = 0; i < CellsCount(); i++) {
199  printer.Print(i, cells()[i]);
200  }
201  printer.Flush();
202  PrintF("\n");
203 }
204 
205 bool Bitmap::IsClean() {
206  for (int i = 0; i < CellsCount(); i++) {
207  if (cells()[i] != 0) {
208  return false;
209  }
210  }
211  return true;
212 }
213 
214 } // namespace internal
215 } // namespace v8
Definition: libplatform.h:13