Home | History | Annotate | Download | only in heap
      1 // Copyright 2016 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/heap/remembered-set.h"
      6 #include "src/heap/heap-inl.h"
      7 #include "src/heap/heap.h"
      8 #include "src/heap/mark-compact.h"
      9 #include "src/heap/slot-set.h"
     10 #include "src/heap/spaces.h"
     11 #include "src/heap/store-buffer.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 template <PointerDirection direction>
     17 void RememberedSet<direction>::ClearInvalidSlots(Heap* heap) {
     18   STATIC_ASSERT(direction == OLD_TO_NEW);
     19   for (MemoryChunk* chunk : *heap->old_space()) {
     20     SlotSet* slots = GetSlotSet(chunk);
     21     if (slots != nullptr) {
     22       slots->Iterate([heap, chunk](Address addr) {
     23         Object** slot = reinterpret_cast<Object**>(addr);
     24         return IsValidSlot(heap, chunk, slot) ? KEEP_SLOT : REMOVE_SLOT;
     25       });
     26     }
     27   }
     28 }
     29 
     30 template <PointerDirection direction>
     31 void RememberedSet<direction>::VerifyValidSlots(Heap* heap) {
     32   Iterate(heap, [heap](Address addr) {
     33     HeapObject* obj =
     34         heap->mark_compact_collector()->FindBlackObjectBySlotSlow(addr);
     35     if (obj == nullptr) {
     36       // The slot is in dead object.
     37       MemoryChunk* chunk = MemoryChunk::FromAnyPointerAddress(heap, addr);
     38       AllocationSpace owner = chunk->owner()->identity();
     39       // The old to old remembered set should not have dead slots.
     40       CHECK_NE(direction, OLD_TO_OLD);
     41       // The old to new remembered set is allowed to have slots in dead
     42       // objects only in map and large object space because these space
     43       // cannot have raw untagged pointers.
     44       CHECK(owner == MAP_SPACE || owner == LO_SPACE);
     45     } else {
     46       int offset = static_cast<int>(addr - obj->address());
     47       CHECK(obj->IsValidSlot(offset));
     48     }
     49     return KEEP_SLOT;
     50   });
     51 }
     52 
     53 template <PointerDirection direction>
     54 bool RememberedSet<direction>::IsValidSlot(Heap* heap, MemoryChunk* chunk,
     55                                            Object** slot) {
     56   STATIC_ASSERT(direction == OLD_TO_NEW);
     57   Object* object = *slot;
     58   if (!heap->InNewSpace(object)) {
     59     return false;
     60   }
     61   HeapObject* heap_object = HeapObject::cast(object);
     62   // If the target object is not black, the source slot must be part
     63   // of a non-black (dead) object.
     64   return Marking::IsBlack(Marking::MarkBitFrom(heap_object)) &&
     65          heap->mark_compact_collector()->IsSlotInBlackObject(
     66              chunk, reinterpret_cast<Address>(slot));
     67 }
     68 
     69 template void RememberedSet<OLD_TO_NEW>::ClearInvalidSlots(Heap* heap);
     70 template void RememberedSet<OLD_TO_NEW>::VerifyValidSlots(Heap* heap);
     71 template void RememberedSet<OLD_TO_OLD>::VerifyValidSlots(Heap* heap);
     72 
     73 }  // namespace internal
     74 }  // namespace v8
     75