blob: 0bc5e6e32401de0e4566cf81e37e9d23ab67ab04 [file] [log] [blame]
Ben Murdoch097c5b22016-05-18 11:27:45 +01001// 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
13namespace v8 {
14namespace internal {
15
16template <PointerDirection direction>
17void RememberedSet<direction>::ClearInvalidSlots(Heap* heap) {
18 STATIC_ASSERT(direction == OLD_TO_NEW);
Ben Murdoch61f157c2016-09-16 13:49:30 +010019 for (MemoryChunk* chunk : *heap->old_space()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010020 SlotSet* slots = GetSlotSet(chunk);
21 if (slots != nullptr) {
Ben Murdochda12d292016-06-02 14:46:10 +010022 slots->Iterate([heap, chunk](Address addr) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010023 Object** slot = reinterpret_cast<Object**>(addr);
Ben Murdochda12d292016-06-02 14:46:10 +010024 return IsValidSlot(heap, chunk, slot) ? KEEP_SLOT : REMOVE_SLOT;
Ben Murdoch097c5b22016-05-18 11:27:45 +010025 });
26 }
27 }
28}
29
30template <PointerDirection direction>
31void RememberedSet<direction>::VerifyValidSlots(Heap* heap) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010032 Iterate(heap, [heap](Address addr) {
Ben Murdochda12d292016-06-02 14:46:10 +010033 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));
Ben Murdoch097c5b22016-05-18 11:27:45 +010048 }
Ben Murdochda12d292016-06-02 14:46:10 +010049 return KEEP_SLOT;
Ben Murdoch097c5b22016-05-18 11:27:45 +010050 });
51}
52
53template <PointerDirection direction>
Ben Murdochda12d292016-06-02 14:46:10 +010054bool RememberedSet<direction>::IsValidSlot(Heap* heap, MemoryChunk* chunk,
55 Object** slot) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010056 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)) &&
Ben Murdochda12d292016-06-02 14:46:10 +010065 heap->mark_compact_collector()->IsSlotInBlackObject(
66 chunk, reinterpret_cast<Address>(slot));
Ben Murdoch097c5b22016-05-18 11:27:45 +010067}
68
69template void RememberedSet<OLD_TO_NEW>::ClearInvalidSlots(Heap* heap);
70template void RememberedSet<OLD_TO_NEW>::VerifyValidSlots(Heap* heap);
Ben Murdochda12d292016-06-02 14:46:10 +010071template void RememberedSet<OLD_TO_OLD>::VerifyValidSlots(Heap* heap);
Ben Murdoch097c5b22016-05-18 11:27:45 +010072
73} // namespace internal
74} // namespace v8