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 12namespace v8 { 13namespace internal { 14 15bool 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 45template <typename TSlot> 46inline 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 60bool 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