Chromium Code Reviews| Index: src/heap/remembered-set.cc |
| diff --git a/src/heap/remembered-set.cc b/src/heap/remembered-set.cc |
| index c5dab905159b33be62906139efb79b64209ee46e..9cac2462f7194c321295e45140020ab9ca172395 100644 |
| --- a/src/heap/remembered-set.cc |
| +++ b/src/heap/remembered-set.cc |
| @@ -15,9 +15,12 @@ namespace v8 { |
| namespace internal { |
| template <PointerDirection direction> |
| -void RememberedSet<direction>::ClearInvalidSlots(Heap* heap) { |
| +void RememberedSet<direction>::ClearInvalidSlots(Heap* heap, |
| + MemoryChunk* chunk) { |
| STATIC_ASSERT(direction == OLD_TO_NEW); |
| - for (MemoryChunk* chunk : *heap->old_space()) { |
| + AllocationSpace identity = chunk->owner()->identity(); |
| + DCHECK(identity == OLD_SPACE || identity == MAP_SPACE); |
| + if (identity == OLD_SPACE) { |
|
ulan
2016/10/06 12:52:13
Both old and map space should clear untyped slots.
Hannes Payer (out of office)
2016/10/06 13:22:40
Done.
|
| SlotSet* slots = GetSlotSet(chunk); |
| if (slots != nullptr) { |
| slots->Iterate( |
| @@ -25,10 +28,9 @@ void RememberedSet<direction>::ClearInvalidSlots(Heap* heap) { |
| Object** slot = reinterpret_cast<Object**>(addr); |
| return IsValidSlot(heap, chunk, slot) ? KEEP_SLOT : REMOVE_SLOT; |
| }, |
| - SlotSet::PREFREE_EMPTY_BUCKETS); |
| + SlotSet::KEEP_EMPTY_BUCKETS); |
| } |
| - } |
| - for (MemoryChunk* chunk : *heap->code_space()) { |
| + } else if (identity == MAP_SPACE) { |
|
ulan
2016/10/06 12:52:13
This branch is not needed.
Michael Lippautz
2016/10/06 13:02:19
and the top branch should also apply for map space
Hannes Payer (out of office)
2016/10/06 13:22:40
Done.
|
| TypedSlotSet* slots = GetTypedSlotSet(chunk); |
| if (slots != nullptr) { |
| slots->Iterate( |
| @@ -39,69 +41,44 @@ void RememberedSet<direction>::ClearInvalidSlots(Heap* heap) { |
| return REMOVE_SLOT; |
| } |
| }, |
| - TypedSlotSet::PREFREE_EMPTY_CHUNKS); |
| - } |
| - } |
| - for (MemoryChunk* chunk : *heap->map_space()) { |
| - SlotSet* slots = GetSlotSet(chunk); |
| - if (slots != nullptr) { |
| - slots->Iterate( |
| - [heap, chunk](Address addr) { |
| - Object** slot = reinterpret_cast<Object**>(addr); |
| - // TODO(mlippautz): In map space all allocations would ideally be |
| - // map |
| - // aligned. After establishing this invariant IsValidSlot could just |
| - // refer to the containing object using alignment and check the mark |
| - // bits. |
| - return IsValidSlot(heap, chunk, slot) ? KEEP_SLOT : REMOVE_SLOT; |
| - }, |
| - SlotSet::PREFREE_EMPTY_BUCKETS); |
| + TypedSlotSet::KEEP_EMPTY_CHUNKS); |
| } |
| } |
| } |
| template <PointerDirection direction> |
| -void RememberedSet<direction>::VerifyValidSlots(Heap* heap) { |
| - Iterate(heap, [heap](Address addr) { |
| - HeapObject* obj = |
| - heap->mark_compact_collector()->FindBlackObjectBySlotSlow(addr); |
| - if (obj == nullptr) { |
| - // The slot is in dead object. |
| - MemoryChunk* chunk = MemoryChunk::FromAnyPointerAddress(heap, addr); |
| - AllocationSpace owner = chunk->owner()->identity(); |
| - // The old to old remembered set should not have dead slots. |
| - CHECK_NE(direction, OLD_TO_OLD); |
| - // The old to new remembered set is allowed to have slots in dead |
| - // objects only in map and large object space because these space |
| - // cannot have raw untagged pointers. |
| - CHECK(owner == MAP_SPACE || owner == LO_SPACE); |
| - } else { |
| - int offset = static_cast<int>(addr - obj->address()); |
| - CHECK(obj->IsValidSlot(offset)); |
| - } |
| - return KEEP_SLOT; |
| - }); |
| +void RememberedSet<direction>::ClearInvalidTypedSlots(Heap* heap, |
| + MemoryChunk* chunk) { |
| + STATIC_ASSERT(direction == OLD_TO_NEW); |
| + DCHECK(chunk->owner()->identity() == CODE_SPACE); |
| + TypedSlotSet* slots = GetTypedSlotSet(chunk); |
| + if (slots != nullptr) { |
| + slots->Iterate( |
| + [heap, chunk](SlotType type, Address host_addr, Address addr) { |
| + if (Marking::IsBlack(ObjectMarking::MarkBitFrom(host_addr))) { |
| + return KEEP_SLOT; |
| + } else { |
| + return REMOVE_SLOT; |
| + } |
| + }, |
| + TypedSlotSet::KEEP_EMPTY_CHUNKS); |
| + } |
| } |
| template <PointerDirection direction> |
| bool RememberedSet<direction>::IsValidSlot(Heap* heap, MemoryChunk* chunk, |
| Object** slot) { |
| STATIC_ASSERT(direction == OLD_TO_NEW); |
| - Object* object = *slot; |
| - if (!heap->InNewSpace(object)) { |
| - return false; |
| - } |
| - HeapObject* heap_object = HeapObject::cast(object); |
| // If the target object is not black, the source slot must be part |
| // of a non-black (dead) object. |
| - return Marking::IsBlack(ObjectMarking::MarkBitFrom(heap_object)) && |
| - heap->mark_compact_collector()->IsSlotInBlackObject( |
| - chunk, reinterpret_cast<Address>(slot)); |
| + return heap->mark_compact_collector()->IsSlotInBlackObject( |
| + chunk, reinterpret_cast<Address>(slot)); |
| } |
| -template void RememberedSet<OLD_TO_NEW>::ClearInvalidSlots(Heap* heap); |
| -template void RememberedSet<OLD_TO_NEW>::VerifyValidSlots(Heap* heap); |
| -template void RememberedSet<OLD_TO_OLD>::VerifyValidSlots(Heap* heap); |
| +template void RememberedSet<OLD_TO_NEW>::ClearInvalidSlots(Heap* heap, |
| + MemoryChunk* chunk); |
| +template void RememberedSet<OLD_TO_NEW>::ClearInvalidTypedSlots( |
| + Heap* heap, MemoryChunk* chunk); |
| } // namespace internal |
| } // namespace v8 |