OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_REMEMBERED_SET_H | 5 #ifndef V8_REMEMBERED_SET_H |
6 #define V8_REMEMBERED_SET_H | 6 #define V8_REMEMBERED_SET_H |
7 | 7 |
8 #include "src/heap/heap.h" | 8 #include "src/heap/heap.h" |
9 #include "src/heap/slot-set.h" | 9 #include "src/heap/slot-set.h" |
10 #include "src/heap/spaces.h" | 10 #include "src/heap/spaces.h" |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 } | 232 } |
233 } else { | 233 } else { |
234 DCHECK(!heap->InNewSpace(object)); | 234 DCHECK(!heap->InNewSpace(object)); |
235 } | 235 } |
236 return REMOVE_SLOT; | 236 return REMOVE_SLOT; |
237 } | 237 } |
238 | 238 |
239 static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, Object** slot); | 239 static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, Object** slot); |
240 }; | 240 }; |
241 | 241 |
242 // Buffer for keeping thead local migration slots during compaction. | |
243 // TODO(ulan): Remove this once every thread gets local pages in compaction | |
244 // space. | |
245 class LocalSlotsBuffer BASE_EMBEDDED { | |
246 public: | |
247 LocalSlotsBuffer() : top_(new Node(nullptr)) {} | |
248 | |
249 ~LocalSlotsBuffer() { | |
250 Node* current = top_; | |
251 while (current != nullptr) { | |
252 Node* tmp = current->next; | |
253 delete current; | |
254 current = tmp; | |
255 } | |
256 } | |
257 | |
258 void Record(Address addr) { | |
259 EnsureSpaceFor(1); | |
260 uintptr_t entry = reinterpret_cast<uintptr_t>(addr); | |
261 DCHECK_GE(entry, static_cast<uintptr_t>(NUMBER_OF_SLOT_TYPES)); | |
262 Insert(entry); | |
263 } | |
264 | |
265 void Record(SlotType type, Address addr) { | |
266 EnsureSpaceFor(2); | |
267 Insert(static_cast<uintptr_t>(type)); | |
268 uintptr_t entry = reinterpret_cast<uintptr_t>(addr); | |
269 DCHECK_GE(entry, static_cast<uintptr_t>(NUMBER_OF_SLOT_TYPES)); | |
270 Insert(entry); | |
271 } | |
272 | |
273 template <typename UntypedCallback, typename TypedCallback> | |
274 void Iterate(UntypedCallback untyped_callback, TypedCallback typed_callback) { | |
275 Node* current = top_; | |
276 bool typed = false; | |
277 SlotType type; | |
278 Address addr; | |
279 while (current != nullptr) { | |
280 for (int i = 0; i < current->count; i++) { | |
281 uintptr_t entry = current->buffer[i]; | |
282 if (entry < NUMBER_OF_SLOT_TYPES) { | |
283 DCHECK(!typed); | |
284 typed = true; | |
285 type = static_cast<SlotType>(entry); | |
286 } else { | |
287 addr = reinterpret_cast<Address>(entry); | |
288 if (typed) { | |
289 typed_callback(type, addr); | |
290 typed = false; | |
291 } else { | |
292 untyped_callback(addr); | |
293 } | |
294 } | |
295 } | |
296 current = current->next; | |
297 } | |
298 } | |
299 | |
300 private: | |
301 void EnsureSpaceFor(int count) { | |
302 if (top_->remaining_free_slots() < count) top_ = new Node(top_); | |
303 } | |
304 | |
305 void Insert(uintptr_t entry) { top_->buffer[top_->count++] = entry; } | |
306 | |
307 static const int kBufferSize = 16 * KB; | |
308 | |
309 struct Node : Malloced { | |
310 explicit Node(Node* next_node) : next(next_node), count(0) {} | |
311 | |
312 inline int remaining_free_slots() { return kBufferSize - count; } | |
313 | |
314 Node* next; | |
315 uintptr_t buffer[kBufferSize]; | |
316 int count; | |
317 }; | |
318 | |
319 Node* top_; | |
320 }; | |
321 | |
322 } // namespace internal | 242 } // namespace internal |
323 } // namespace v8 | 243 } // namespace v8 |
324 | 244 |
325 #endif // V8_REMEMBERED_SET_H | 245 #endif // V8_REMEMBERED_SET_H |
OLD | NEW |