| 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();
|
|
|