19static constexpr double kMarkingScheduleRatioBeforeConcurrentPriorityIncrease =
22static constexpr size_t kDefaultDeadlineCheckInterval = 750u;
25 size_t kDeadlineCheckInterval = kDefaultDeadlineCheckInterval,
26 typename WorklistLocal,
typename Callback>
27bool DrainWorklistWithYielding(
JobDelegate* job_delegate,
28 StatsCollector* stats_collector,
29 ConcurrentMarkingState& marking_state,
30 ConcurrentMarkerBase& concurrent_marker,
31 WorklistLocal& worklist_local,
34 [&concurrent_marker, &marking_state, job_delegate]() {
35 concurrent_marker.AddConcurrentlyMarkedBytes(
36 marking_state.RecentlyMarkedBytes());
37 return job_delegate->ShouldYield();
46size_t WorkSizeForConcurrentMarking(MarkingWorklists& marking_worklists) {
47 return marking_worklists.marking_worklist()->Size() +
48 marking_worklists.write_barrier_worklist()->Size() +
49 marking_worklists.previously_not_fully_constructed_worklist()->Size();
55bool HasWorkForConcurrentMarking(MarkingWorklists& marking_worklists) {
56 return !marking_worklists.marking_worklist()->IsEmpty() ||
57 !marking_worklists.write_barrier_worklist()->IsEmpty() ||
58 !marking_worklists.previously_not_fully_constructed_worklist()
62class ConcurrentMarkingTask final :
public v8::JobTask {
64 explicit ConcurrentMarkingTask(ConcurrentMarkerBase&);
68 size_t GetMaxConcurrency(
size_t)
const final;
71 void ProcessWorklists(
JobDelegate*, ConcurrentMarkingState&, Visitor&);
76ConcurrentMarkingTask::ConcurrentMarkingTask(
77 ConcurrentMarkerBase& concurrent_marker)
80void ConcurrentMarkingTask::Run(JobDelegate* job_delegate) {
81 StatsCollector::EnabledConcurrentScope stats_scope(
83 StatsCollector::kConcurrentMark);
86 ConcurrentMarkingState concurrent_marking_state(
89 std::unique_ptr<Visitor> concurrent_marking_visitor =
91 concurrent_marking_state);
92 ProcessWorklists(job_delegate, concurrent_marking_state,
93 *concurrent_marking_visitor);
95 concurrent_marking_state.RecentlyMarkedBytes());
96 concurrent_marking_state.Publish();
99size_t ConcurrentMarkingTask::GetMaxConcurrency(
100 size_t current_worker_count)
const {
102 current_worker_count;
105void ConcurrentMarkingTask::ProcessWorklists(
106 JobDelegate* job_delegate, ConcurrentMarkingState& concurrent_marking_state,
107 Visitor& concurrent_marking_visitor) {
110 if (!DrainWorklistWithYielding<
111 StatsCollector::kConcurrentMarkProcessNotFullyconstructedWorklist>(
112 job_delegate, stats_collector, concurrent_marking_state,
114 concurrent_marking_state
115 .previously_not_fully_constructed_worklist(),
116 [&concurrent_marking_state,
117 &concurrent_marking_visitor](HeapObjectHeader* header) {
118 BasePage::FromPayload(header)->SynchronizedLoad();
119 concurrent_marking_state.AccountMarkedBytes(*header);
120 DynamicallyTraceMarkedObject<AccessMode::kAtomic>(
121 concurrent_marking_visitor, *header);
125 if (!DrainWorklistWithYielding<
126 StatsCollector::kConcurrentMarkProcessMarkingWorklist>(
127 job_delegate, stats_collector, concurrent_marking_state,
129 [&concurrent_marking_state, &concurrent_marking_visitor](
130 const MarkingWorklists::MarkingItem& item) {
131 BasePage::FromPayload(item.base_object_payload)
132 ->SynchronizedLoad();
133 const HeapObjectHeader& header =
134 HeapObjectHeader::FromObject(item.base_object_payload);
135 DCHECK(!header.IsInConstruction<AccessMode::kAtomic>());
136 DCHECK(header.IsMarked<AccessMode::kAtomic>());
137 concurrent_marking_state.AccountMarkedBytes(header);
138 item.callback(&concurrent_marking_visitor,
139 item.base_object_payload);
143 if (!DrainWorklistWithYielding<
144 StatsCollector::kConcurrentMarkProcessWriteBarrierWorklist>(
145 job_delegate, stats_collector, concurrent_marking_state,
147 concurrent_marking_state.write_barrier_worklist(),
148 [&concurrent_marking_state,
149 &concurrent_marking_visitor](HeapObjectHeader* header) {
150 BasePage::FromPayload(header)->SynchronizedLoad();
151 concurrent_marking_state.AccountMarkedBytes(*header);
152 DynamicallyTraceMarkedObject<AccessMode::kAtomic>(
153 concurrent_marking_visitor, *header);
157 if (!DrainWorklistWithYielding<
158 StatsCollector::kConcurrentMarkProcessEphemeronWorklist>(
159 job_delegate, stats_collector, concurrent_marking_state,
161 concurrent_marking_state.ephemeron_pairs_for_processing_worklist(),
162 [&concurrent_marking_state, &concurrent_marking_visitor](
163 const MarkingWorklists::EphemeronPairItem& item) {
164 concurrent_marking_state.ProcessEphemeron(
165 item.key, item.value, item.value_desc,
166 concurrent_marking_visitor);
171 !concurrent_marking_state.marking_worklist().IsLocalAndGlobalEmpty());
176ConcurrentMarkerBase::ConcurrentMarkerBase(
182 incremental_marking_schedule_(incremental_marking_schedule),
189 std::make_unique<ConcurrentMarkingTask>(*
this));
255 const auto time_delta =
257 if (!time_delta.IsZero() &&
258 (time_delta.InMillisecondsF() >
261 kMarkingScheduleRatioBeforeConcurrentPriorityIncrease))) {
263 cppgc::TaskPriority::kUserBlocking);
270 return std::make_unique<ConcurrentMarkingVisitor>(
heap(), marking_state);
heap::base::IncrementalMarkingSchedule & incremental_marking_schedule_
void AddConcurrentlyMarkedBytes(size_t marked_bytes)
std::atomic< size_t > concurrently_marked_bytes_
void NotifyIncrementalMutatorStepCompleted()
cppgc::Platform *const platform_
std::unique_ptr< JobHandle > concurrent_marking_handle_
void NotifyOfWorkIfNeeded(cppgc::TaskPriority priority)
bool concurrent_marking_priority_increased_
heap::base::IncrementalMarkingSchedule & incremental_marking_schedule() const
void IncreaseMarkingPriorityIfNeeded()
virtual ~ConcurrentMarkerBase()
MarkingWorklists & marking_worklists_
std::unique_ptr< Visitor > CreateConcurrentMarkingVisitor(ConcurrentMarkingState &) const final
InternalScope< kDisabled, kConcurrentThread > DisabledConcurrentScope
v8::base::TimeDelta GetTimeSinceLastConcurrentMarkingUpdate()
static constexpr v8::base::TimeDelta kEstimatedMarkingTime
void AddConcurrentlyMarkedBytes(size_t)
void NotifyConcurrentMarkingStart()
double InMillisecondsF() const
ConcurrentMarkerBase & concurrent_marker_
bool DrainWorklistWithPredicate(Predicate ShouldYield, CreateStatsScopeCallback CreateStatsScope, WorklistLocal &worklist_local, ProcessWorklistItemCallback ProcessWorklistItem)
v8::JobDelegate JobDelegate
MarkingWorklists marking_worklists_
#define CHECK_IMPLIES(lhs, rhs)
#define DCHECK(condition)