| // Copyright 2020 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_CPPGC_MARKER_H_ |
| #define V8_HEAP_CPPGC_MARKER_H_ |
| |
| #include <memory> |
| |
| #include "include/cppgc/heap.h" |
| #include "include/cppgc/visitor.h" |
| #include "src/base/macros.h" |
| #include "src/base/platform/time.h" |
| #include "src/heap/cppgc/globals.h" |
| #include "src/heap/cppgc/marking-state.h" |
| #include "src/heap/cppgc/marking-visitor.h" |
| #include "src/heap/cppgc/marking-worklists.h" |
| #include "src/heap/cppgc/worklist.h" |
| |
| namespace cppgc { |
| namespace internal { |
| |
| class HeapBase; |
| |
| // Marking algorithm. Example for a valid call sequence creating the marking |
| // phase: |
| // 1. StartMarking() |
| // 2. AdvanceMarkingWithDeadline() [Optional, depending on environment.] |
| // 3. EnterAtomicPause() |
| // 4. AdvanceMarkingWithDeadline() |
| // 5. LeaveAtomicPause() |
| // |
| // Alternatively, FinishMarking combines steps 3.-5. |
| class V8_EXPORT_PRIVATE MarkerBase { |
| public: |
| struct MarkingConfig { |
| enum class CollectionType : uint8_t { |
| kMinor, |
| kMajor, |
| }; |
| using StackState = cppgc::Heap::StackState; |
| enum MarkingType : uint8_t { |
| kAtomic, |
| kIncremental, |
| kIncrementalAndConcurrent |
| }; |
| |
| static constexpr MarkingConfig Default() { return {}; } |
| |
| CollectionType collection_type = CollectionType::kMajor; |
| StackState stack_state = StackState::kMayContainHeapPointers; |
| MarkingType marking_type = MarkingType::kAtomic; |
| }; |
| |
| virtual ~MarkerBase(); |
| |
| MarkerBase(const MarkerBase&) = delete; |
| MarkerBase& operator=(const MarkerBase&) = delete; |
| |
| // Initialize marking according to the given config. This method will |
| // trigger incremental/concurrent marking if needed. |
| void StartMarking(MarkingConfig config); |
| |
| // Signals entering the atomic marking pause. The method |
| // - stops incremental/concurrent marking; |
| // - flushes back any in-construction worklists if needed; |
| // - Updates the MarkingConfig if the stack state has changed; |
| void EnterAtomicPause(MarkingConfig config); |
| |
| // Makes marking progress. |
| virtual bool AdvanceMarkingWithDeadline(v8::base::TimeDelta); |
| |
| // Signals leaving the atomic marking pause. This method expects no more |
| // objects to be marked and merely updates marking states if needed. |
| void LeaveAtomicPause(); |
| |
| // Combines: |
| // - EnterAtomicPause() |
| // - AdvanceMarkingWithDeadline() |
| // - LeaveAtomicPause() |
| void FinishMarking(MarkingConfig config); |
| |
| void ProcessWeakness(); |
| |
| inline void WriteBarrierForInConstructionObject(ConstAddress); |
| inline void WriteBarrierForObject(HeapObjectHeader&); |
| |
| HeapBase& heap() { return heap_; } |
| |
| MarkingWorklists& MarkingWorklistsForTesting() { return marking_worklists_; } |
| MarkingState& MarkingStateForTesting() { return mutator_marking_state_; } |
| cppgc::Visitor& VisitorForTesting() { return visitor(); } |
| void ClearAllWorklistsForTesting(); |
| |
| protected: |
| explicit MarkerBase(HeapBase& heap); |
| |
| virtual cppgc::Visitor& visitor() = 0; |
| virtual ConservativeTracingVisitor& conservative_visitor() = 0; |
| virtual heap::base::StackVisitor& stack_visitor() = 0; |
| |
| void VisitRoots(); |
| |
| void MarkNotFullyConstructedObjects(); |
| |
| HeapBase& heap_; |
| MarkingConfig config_ = MarkingConfig::Default(); |
| |
| MarkingWorklists marking_worklists_; |
| MarkingState mutator_marking_state_; |
| }; |
| |
| class V8_EXPORT_PRIVATE Marker final : public MarkerBase { |
| public: |
| explicit Marker(HeapBase&); |
| |
| protected: |
| cppgc::Visitor& visitor() final { return marking_visitor_; } |
| ConservativeTracingVisitor& conservative_visitor() final { |
| return conservative_marking_visitor_; |
| } |
| heap::base::StackVisitor& stack_visitor() final { |
| return conservative_marking_visitor_; |
| } |
| |
| private: |
| MarkingVisitor marking_visitor_; |
| ConservativeMarkingVisitor conservative_marking_visitor_; |
| }; |
| |
| void MarkerBase::WriteBarrierForInConstructionObject(ConstAddress payload) { |
| MarkingWorklists::NotFullyConstructedWorklist::View |
| not_fully_constructed_worklist( |
| marking_worklists_.not_fully_constructed_worklist(), |
| MarkingWorklists::kMutatorThreadId); |
| not_fully_constructed_worklist.Push(payload); |
| } |
| |
| void MarkerBase::WriteBarrierForObject(HeapObjectHeader& header) { |
| MarkingWorklists::WriteBarrierWorklist::View write_barrier_worklist( |
| marking_worklists_.write_barrier_worklist(), |
| MarkingWorklists::kMutatorThreadId); |
| write_barrier_worklist.Push(&header); |
| } |
| |
| } // namespace internal |
| } // namespace cppgc |
| |
| #endif // V8_HEAP_CPPGC_MARKER_H_ |