Index: src/heap/remembered-set.h |
diff --git a/src/heap/remembered-set.h b/src/heap/remembered-set.h |
index 37439bfa62d023a63a55cc6274b1f8bd90220729..d11c47f0aa893c79ab9f4dc6b805195c5784c9fb 100644 |
--- a/src/heap/remembered-set.h |
+++ b/src/heap/remembered-set.h |
@@ -13,17 +13,19 @@ |
namespace v8 { |
namespace internal { |
+enum PointerDirection { OLD_TO_OLD, OLD_TO_NEW }; |
+ |
// TODO(ulan): Investigate performance of de-templatizing this class. |
-template <RememberedSetType type> |
+template <PointerDirection direction> |
class RememberedSet : public AllStatic { |
public: |
// Given a page and a slot in that page, this function adds the slot to the |
// remembered set. |
static void Insert(MemoryChunk* chunk, Address slot_addr) { |
DCHECK(chunk->Contains(slot_addr)); |
- SlotSet* slot_set = chunk->slot_set<type>(); |
+ SlotSet* slot_set = GetSlotSet(chunk); |
if (slot_set == nullptr) { |
- slot_set = chunk->AllocateSlotSet<type>(); |
+ slot_set = AllocateSlotSet(chunk); |
} |
uintptr_t offset = slot_addr - chunk->address(); |
slot_set[offset / Page::kPageSize].Insert(offset % Page::kPageSize); |
@@ -33,7 +35,7 @@ class RememberedSet : public AllStatic { |
// the remembered set contains the slot. |
static bool Contains(MemoryChunk* chunk, Address slot_addr) { |
DCHECK(chunk->Contains(slot_addr)); |
- SlotSet* slot_set = chunk->slot_set<type>(); |
+ SlotSet* slot_set = GetSlotSet(chunk); |
if (slot_set == nullptr) { |
return false; |
} |
@@ -47,7 +49,7 @@ class RememberedSet : public AllStatic { |
// If the slot was never added, then the function does nothing. |
static void Remove(MemoryChunk* chunk, Address slot_addr) { |
DCHECK(chunk->Contains(slot_addr)); |
- SlotSet* slot_set = chunk->slot_set<type>(); |
+ SlotSet* slot_set = GetSlotSet(chunk); |
if (slot_set != nullptr) { |
uintptr_t offset = slot_addr - chunk->address(); |
slot_set[offset / Page::kPageSize].Remove(offset % Page::kPageSize); |
@@ -58,7 +60,7 @@ class RememberedSet : public AllStatic { |
// slots from the remembered set. |
static void RemoveRange(MemoryChunk* chunk, Address start, Address end, |
SlotSet::EmptyBucketMode mode) { |
- SlotSet* slot_set = chunk->slot_set<type>(); |
+ SlotSet* slot_set = GetSlotSet(chunk); |
if (slot_set != nullptr) { |
uintptr_t start_offset = start - chunk->address(); |
uintptr_t end_offset = end - chunk->address(); |
@@ -110,8 +112,8 @@ class RememberedSet : public AllStatic { |
MemoryChunkIterator it(heap); |
MemoryChunk* chunk; |
while ((chunk = it.next()) != nullptr) { |
- SlotSet* slots = chunk->slot_set<type>(); |
- TypedSlotSet* typed_slots = chunk->typed_slot_set<type>(); |
+ SlotSet* slots = GetSlotSet(chunk); |
+ TypedSlotSet* typed_slots = GetTypedSlotSet(chunk); |
if (slots != nullptr || typed_slots != nullptr) { |
callback(chunk); |
} |
@@ -123,7 +125,7 @@ class RememberedSet : public AllStatic { |
// SlotCallbackResult. |
template <typename Callback> |
static void Iterate(MemoryChunk* chunk, Callback callback) { |
- SlotSet* slots = chunk->slot_set<type>(); |
+ SlotSet* slots = GetSlotSet(chunk); |
if (slots != nullptr) { |
size_t pages = (chunk->size() + Page::kPageSize - 1) / Page::kPageSize; |
int new_count = 0; |
@@ -133,8 +135,8 @@ class RememberedSet : public AllStatic { |
} |
// Only old-to-old slot sets are released eagerly. Old-new-slot sets are |
// released by the sweeper threads. |
- if (type == OLD_TO_OLD && new_count == 0) { |
- chunk->ReleaseSlotSet<OLD_TO_OLD>(); |
+ if (direction == OLD_TO_OLD && new_count == 0) { |
+ chunk->ReleaseOldToOldSlots(); |
} |
} |
} |
@@ -143,9 +145,10 @@ class RememberedSet : public AllStatic { |
// to the remembered set. |
static void InsertTyped(Page* page, Address host_addr, SlotType slot_type, |
Address slot_addr) { |
- TypedSlotSet* slot_set = page->typed_slot_set<type>(); |
+ TypedSlotSet* slot_set = GetTypedSlotSet(page); |
if (slot_set == nullptr) { |
- slot_set = page->AllocateTypedSlotSet<type>(); |
+ AllocateTypedSlotSet(page); |
+ slot_set = GetTypedSlotSet(page); |
} |
if (host_addr == nullptr) { |
host_addr = page->address(); |
@@ -161,7 +164,7 @@ class RememberedSet : public AllStatic { |
// Given a page and a range of typed slots in that page, this function removes |
// the slots from the remembered set. |
static void RemoveRangeTyped(MemoryChunk* page, Address start, Address end) { |
- TypedSlotSet* slots = page->typed_slot_set<type>(); |
+ TypedSlotSet* slots = GetTypedSlotSet(page); |
if (slots != nullptr) { |
slots->Iterate( |
[start, end](SlotType slot_type, Address host_addr, |
@@ -188,23 +191,23 @@ class RememberedSet : public AllStatic { |
// Address slot_addr) and return SlotCallbackResult. |
template <typename Callback> |
static void IterateTyped(MemoryChunk* chunk, Callback callback) { |
- TypedSlotSet* slots = chunk->typed_slot_set<type>(); |
+ TypedSlotSet* slots = GetTypedSlotSet(chunk); |
if (slots != nullptr) { |
int new_count = slots->Iterate(callback, TypedSlotSet::KEEP_EMPTY_CHUNKS); |
if (new_count == 0) { |
- chunk->ReleaseTypedSlotSet<type>(); |
+ ReleaseTypedSlotSet(chunk); |
} |
} |
} |
// Clear all old to old slots from the remembered set. |
static void ClearAll(Heap* heap) { |
- STATIC_ASSERT(type == OLD_TO_OLD); |
+ STATIC_ASSERT(direction == OLD_TO_OLD); |
MemoryChunkIterator it(heap); |
MemoryChunk* chunk; |
while ((chunk = it.next()) != nullptr) { |
- chunk->ReleaseSlotSet<OLD_TO_OLD>(); |
- chunk->ReleaseTypedSlotSet<OLD_TO_OLD>(); |
+ chunk->ReleaseOldToOldSlots(); |
+ chunk->ReleaseTypedOldToOldSlots(); |
} |
} |
@@ -215,6 +218,48 @@ class RememberedSet : public AllStatic { |
static void ClearInvalidTypedSlots(Heap* heap, MemoryChunk* chunk); |
private: |
+ static SlotSet* GetSlotSet(MemoryChunk* chunk) { |
+ if (direction == OLD_TO_OLD) { |
+ return chunk->old_to_old_slots(); |
+ } else { |
+ return chunk->old_to_new_slots(); |
+ } |
+ } |
+ |
+ static TypedSlotSet* GetTypedSlotSet(MemoryChunk* chunk) { |
+ if (direction == OLD_TO_OLD) { |
+ return chunk->typed_old_to_old_slots(); |
+ } else { |
+ return chunk->typed_old_to_new_slots(); |
+ } |
+ } |
+ |
+ static void ReleaseTypedSlotSet(MemoryChunk* chunk) { |
+ if (direction == OLD_TO_OLD) { |
+ chunk->ReleaseTypedOldToOldSlots(); |
+ } |
+ } |
+ |
+ static SlotSet* AllocateSlotSet(MemoryChunk* chunk) { |
+ if (direction == OLD_TO_OLD) { |
+ chunk->AllocateOldToOldSlots(); |
+ return chunk->old_to_old_slots(); |
+ } else { |
+ chunk->AllocateOldToNewSlots(); |
+ return chunk->old_to_new_slots(); |
+ } |
+ } |
+ |
+ static TypedSlotSet* AllocateTypedSlotSet(MemoryChunk* chunk) { |
+ if (direction == OLD_TO_OLD) { |
+ chunk->AllocateTypedOldToOldSlots(); |
+ return chunk->typed_old_to_old_slots(); |
+ } else { |
+ chunk->AllocateTypedOldToNewSlots(); |
+ return chunk->typed_old_to_new_slots(); |
+ } |
+ } |
+ |
static bool IsValidSlot(Heap* heap, MemoryChunk* chunk, Object** slot); |
}; |