Index: src/heap/remembered-set.h |
diff --git a/src/heap/remembered-set.h b/src/heap/remembered-set.h |
index 1b866d120679e2477afb3abf8019d0e1e1980950..2631e1e3aee10daa00641ef8b7e69ec27390a3d2 100644 |
--- a/src/heap/remembered-set.h |
+++ b/src/heap/remembered-set.h |
@@ -59,21 +59,41 @@ class RememberedSet { |
// The callback should take (Address slot) and return SlotCallbackResult. |
template <typename Callback> |
static void Iterate(Heap* heap, Callback callback) { |
+ 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); |
} |
} |
} |
@@ -91,6 +111,14 @@ 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) { |
@@ -116,20 +144,16 @@ class RememberedSet { |
} |
} |
- // Iterates and filters typed old to old pointers with the given callback. |
- // The callback should take (SlotType slot_type, Address slot_addr) and |
- // return SlotCallbackResult. |
+ // 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(Heap* heap, Callback callback) { |
- MemoryChunkIterator it(heap, MemoryChunkIterator::ALL_BUT_MAP_SPACE); |
- MemoryChunk* chunk; |
- while ((chunk = it.next()) != nullptr) { |
- TypedSlotSet* slots = chunk->typed_old_to_old_slots(); |
- if (slots != nullptr) { |
- int new_count = slots->Iterate(callback); |
- if (new_count == 0) { |
- chunk->ReleaseTypedOldToOldSlots(); |
- } |
+ 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(); |
} |
} |
} |
@@ -162,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(); |