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