summaryrefslogtreecommitdiff
path: root/deps/v8/src/heap/remembered-set.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/heap/remembered-set.h')
-rw-r--r--deps/v8/src/heap/remembered-set.h120
1 files changed, 104 insertions, 16 deletions
diff --git a/deps/v8/src/heap/remembered-set.h b/deps/v8/src/heap/remembered-set.h
index 351d76edb8..45408bf1e9 100644
--- a/deps/v8/src/heap/remembered-set.h
+++ b/deps/v8/src/heap/remembered-set.h
@@ -56,22 +56,44 @@ class RememberedSet {
}
// Iterates and filters the remembered set with the given callback.
- // The callback should take (Address slot) and return SlotSet::CallbackResult.
+ // The callback should take (Address slot) and return SlotCallbackResult.
template <typename Callback>
static void Iterate(Heap* heap, Callback callback) {
- PointerChunkIterator it(heap);
+ IterateMemoryChunks(
+ heap, [callback](MemoryChunk* chunk) { Iterate(chunk, callback); });
+ }
+
+ // Iterates over all memory chunks that contains non-empty slot sets.
+ // The callback should take (MemoryChunk* chunk) and return void.
+ template <typename Callback>
+ static void IterateMemoryChunks(Heap* heap, Callback callback) {
+ MemoryChunkIterator it(heap, direction == OLD_TO_OLD
+ ? MemoryChunkIterator::ALL
+ : MemoryChunkIterator::ALL_BUT_CODE_SPACE);
MemoryChunk* chunk;
while ((chunk = it.next()) != nullptr) {
SlotSet* slots = GetSlotSet(chunk);
- if (slots != nullptr) {
- size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize;
- int new_count = 0;
- for (size_t page = 0; page < pages; page++) {
- new_count += slots[page].Iterate(callback);
- }
- if (new_count == 0) {
- ReleaseSlotSet(chunk);
- }
+ TypedSlotSet* typed_slots = GetTypedSlotSet(chunk);
+ if (slots != nullptr || typed_slots != nullptr) {
+ callback(chunk);
+ }
+ }
+ }
+
+ // Iterates and filters the remembered set in the given memory chunk with
+ // the given callback. The callback should take (Address slot) and return
+ // SlotCallbackResult.
+ template <typename Callback>
+ static void Iterate(MemoryChunk* chunk, Callback callback) {
+ SlotSet* slots = GetSlotSet(chunk);
+ if (slots != nullptr) {
+ size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize;
+ int new_count = 0;
+ for (size_t page = 0; page < pages; page++) {
+ new_count += slots[page].Iterate(callback);
+ }
+ if (new_count == 0) {
+ ReleaseSlotSet(chunk);
}
}
}
@@ -89,6 +111,64 @@ class RememberedSet {
});
}
+ template <typename Callback>
+ static void IterateWithWrapper(Heap* heap, MemoryChunk* chunk,
+ Callback callback) {
+ Iterate(chunk, [heap, callback](Address addr) {
+ return Wrapper(heap, addr, callback);
+ });
+ }
+
+ // Given a page and a typed slot in that page, this function adds the slot
+ // to the remembered set.
+ static void InsertTyped(Page* page, SlotType slot_type, Address slot_addr) {
+ STATIC_ASSERT(direction == OLD_TO_OLD);
+ TypedSlotSet* slot_set = page->typed_old_to_old_slots();
+ if (slot_set == nullptr) {
+ page->AllocateTypedOldToOldSlots();
+ slot_set = page->typed_old_to_old_slots();
+ }
+ uintptr_t offset = slot_addr - page->address();
+ DCHECK_LT(offset, static_cast<uintptr_t>(TypedSlotSet::kMaxOffset));
+ slot_set->Insert(slot_type, static_cast<uint32_t>(offset));
+ }
+
+ // Given a page and a range of typed slots in that page, this function removes
+ // the slots from the remembered set.
+ static void RemoveRangeTyped(Page* page, Address start, Address end) {
+ TypedSlotSet* slots = page->typed_old_to_old_slots();
+ if (slots != nullptr) {
+ slots->Iterate([start, end](SlotType slot_type, Address slot_addr) {
+ return start <= slot_addr && slot_addr < end ? REMOVE_SLOT : KEEP_SLOT;
+ });
+ }
+ }
+
+ // Iterates and filters typed old to old pointers in the given memory chunk
+ // with the given callback. The callback should take (SlotType slot_type,
+ // Address slot_addr) and return SlotCallbackResult.
+ template <typename Callback>
+ static void IterateTyped(MemoryChunk* chunk, Callback callback) {
+ TypedSlotSet* slots = chunk->typed_old_to_old_slots();
+ if (slots != nullptr) {
+ int new_count = slots->Iterate(callback);
+ if (new_count == 0) {
+ chunk->ReleaseTypedOldToOldSlots();
+ }
+ }
+ }
+
+ // Clear all old to old slots from the remembered set.
+ static void ClearAll(Heap* heap) {
+ STATIC_ASSERT(direction == OLD_TO_OLD);
+ MemoryChunkIterator it(heap, MemoryChunkIterator::ALL);
+ MemoryChunk* chunk;
+ while ((chunk = it.next()) != nullptr) {
+ chunk->ReleaseOldToOldSlots();
+ chunk->ReleaseTypedOldToOldSlots();
+ }
+ }
+
// Eliminates all stale slots from the remembered set, i.e.
// slots that are not part of live objects anymore. This method must be
// called after marking, when the whole transitive closure is known and
@@ -106,6 +186,14 @@ class RememberedSet {
}
}
+ static TypedSlotSet* GetTypedSlotSet(MemoryChunk* chunk) {
+ if (direction == OLD_TO_OLD) {
+ return chunk->typed_old_to_old_slots();
+ } else {
+ return nullptr;
+ }
+ }
+
static void ReleaseSlotSet(MemoryChunk* chunk) {
if (direction == OLD_TO_OLD) {
chunk->ReleaseOldToOldSlots();
@@ -125,8 +213,8 @@ class RememberedSet {
}
template <typename Callback>
- static SlotSet::CallbackResult Wrapper(Heap* heap, Address slot_address,
- Callback slot_callback) {
+ static SlotCallbackResult Wrapper(Heap* heap, Address slot_address,
+ Callback slot_callback) {
STATIC_ASSERT(direction == OLD_TO_NEW);
Object** slot = reinterpret_cast<Object**>(slot_address);
Object* object = *slot;
@@ -140,15 +228,15 @@ class RememberedSet {
// Unfortunately, we do not know about the slot. It could be in a
// just freed free space object.
if (heap->InToSpace(object)) {
- return SlotSet::KEEP_SLOT;
+ return KEEP_SLOT;
}
} else {
DCHECK(!heap->InNewSpace(object));
}
- return SlotSet::REMOVE_SLOT;
+ return REMOVE_SLOT;
}
- static bool IsValidSlot(Heap* heap, Object** slot);
+ static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, Object** slot);
};
} // namespace internal