1 // Copyright 2020 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 #ifndef V8_HEAP_MARKING_BARRIER_INL_H_
6 #define V8_HEAP_MARKING_BARRIER_INL_H_
7
8 #include "src/heap/incremental-marking-inl.h"
9 #include "src/heap/incremental-marking.h"
10 #include "src/heap/marking-barrier.h"
11
12 namespace v8 {
13 namespace internal {
14
MarkValue(HeapObject host,HeapObject value)15 bool MarkingBarrier::MarkValue(HeapObject host, HeapObject value) {
16 DCHECK(IsCurrentMarkingBarrier());
17 DCHECK(is_activated_);
18 DCHECK(!marking_state_.IsImpossible(value));
19 // Host may have an impossible markbit pattern if manual allocation folding
20 // is performed and host happens to be the last word of an allocated region.
21 // In that case host has only one markbit and the second markbit belongs to
22 // another object. We can detect that case by checking if value is a one word
23 // filler map.
24 DCHECK(!marking_state_.IsImpossible(host) ||
25 value == ReadOnlyRoots(heap_->isolate()).one_pointer_filler_map());
26 if (!V8_CONCURRENT_MARKING_BOOL && !marking_state_.IsBlack(host)) {
27 // The value will be marked and the slot will be recorded when the marker
28 // visits the host object.
29 return false;
30 }
31 BasicMemoryChunk* target_page = BasicMemoryChunk::FromHeapObject(value);
32 if (is_shared_heap_ != target_page->InSharedHeap()) return false;
33 if (WhiteToGreyAndPush(value)) {
34 if (is_main_thread_barrier_) {
35 incremental_marking_->RestartIfNotMarking();
36 }
37
38 if (V8_UNLIKELY(FLAG_track_retaining_path)) {
39 heap_->AddRetainingRoot(Root::kWriteBarrier, value);
40 }
41 }
42 return true;
43 }
44
45 template <typename TSlot>
MarkRange(HeapObject host,TSlot start,TSlot end)46 inline void MarkingBarrier::MarkRange(HeapObject host, TSlot start, TSlot end) {
47 auto* isolate = heap_->isolate();
48 for (TSlot slot = start; slot < end; ++slot) {
49 typename TSlot::TObject object = slot.Relaxed_Load();
50 HeapObject heap_object;
51 // Mark both, weak and strong edges.
52 if (object.GetHeapObject(isolate, &heap_object)) {
53 if (MarkValue(host, heap_object) && is_compacting_) {
54 collector_->RecordSlot(host, HeapObjectSlot(slot), heap_object);
55 }
56 }
57 }
58 }
59
WhiteToGreyAndPush(HeapObject obj)60 bool MarkingBarrier::WhiteToGreyAndPush(HeapObject obj) {
61 if (marking_state_.WhiteToGrey(obj)) {
62 worklist_.Push(obj);
63 return true;
64 }
65 return false;
66 }
67
68 } // namespace internal
69 } // namespace v8
70
71 #endif // V8_HEAP_MARKING_BARRIER_INL_H_
72