// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_HEAP_INCREMENTAL_MARKING_INL_H_ #define V8_HEAP_INCREMENTAL_MARKING_INL_H_ #include "src/heap/incremental-marking.h" #include "src/execution/isolate.h" #include "src/heap/mark-compact-inl.h" #include "src/objects/maybe-object.h" #include "src/objects/objects-inl.h" namespace v8 { namespace internal { void IncrementalMarking::TransferColor(HeapObject from, HeapObject to) { if (atomic_marking_state()->IsBlack(to)) { DCHECK(black_allocation()); return; } DCHECK(atomic_marking_state()->IsWhite(to)); if (atomic_marking_state()->IsGrey(from)) { bool success = atomic_marking_state()->WhiteToGrey(to); DCHECK(success); USE(success); } else if (atomic_marking_state()->IsBlack(from)) { bool success = atomic_marking_state()->WhiteToBlack(to); DCHECK(success); USE(success); } } bool IncrementalMarking::BaseRecordWrite(HeapObject obj, HeapObject value) { DCHECK(!marking_state()->IsImpossible(value)); DCHECK(!marking_state()->IsImpossible(obj)); // The write barrier stub generated with V8_CONCURRENT_MARKING does not // check the color of the source object. const bool need_recording = V8_CONCURRENT_MARKING_BOOL || marking_state()->IsBlack(obj); if (need_recording && WhiteToGreyAndPush(value)) { RestartIfNotMarking(); } return is_compacting_ && need_recording; } template void IncrementalMarking::RecordWrite(HeapObject obj, TSlot slot, typename TSlot::TObject value) { static_assert(std::is_same::value || std::is_same::value, "Only ObjectSlot and MaybeObjectSlot are expected here"); DCHECK_NE(slot.address(), kNullAddress); DCHECK_IMPLIES(!TSlot::kCanBeWeak, !HAS_WEAK_HEAP_OBJECT_TAG((*slot).ptr())); DCHECK_IMPLIES(!TSlot::kCanBeWeak, !HAS_WEAK_HEAP_OBJECT_TAG(value.ptr())); // When writing a weak reference, treat it as strong for the purposes of the // marking barrier. HeapObject value_heap_object; if (IsMarking() && value.GetHeapObject(&value_heap_object)) { RecordWriteSlow(obj, HeapObjectSlot(slot), value_heap_object); } } bool IncrementalMarking::WhiteToGreyAndPush(HeapObject obj) { if (marking_state()->WhiteToGrey(obj)) { marking_worklist()->Push(obj); return true; } return false; } void IncrementalMarking::RestartIfNotMarking() { if (state_ == COMPLETE) { state_ = MARKING; if (FLAG_trace_incremental_marking) { heap()->isolate()->PrintWithTimestamp( "[IncrementalMarking] Restarting (new grey objects)\n"); } } } } // namespace internal } // namespace v8 #endif // V8_HEAP_INCREMENTAL_MARKING_INL_H_