v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
incremental-marking-schedule.cc
Go to the documentation of this file.
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
6
7#include <algorithm>
8#include <atomic>
9#include <cmath>
10#include <memory>
11
13
14namespace heap::base {
15
16namespace {
17
18constexpr auto kTimeDeltaForPredictableSchedule =
20
21} // namespace
22
23// static
24std::unique_ptr<IncrementalMarkingSchedule> IncrementalMarkingSchedule::Create(
25 bool predictable_schedule) {
26 return std::unique_ptr<IncrementalMarkingSchedule>(
27 new IncrementalMarkingSchedule(0, predictable_schedule));
28}
29
30// static
31std::unique_ptr<IncrementalMarkingSchedule>
33 size_t min_marked_bytes_per_step, bool predictable_schedule) {
34 return std::unique_ptr<IncrementalMarkingSchedule>(
36 predictable_schedule));
37}
38
40 size_t min_marked_bytes_per_step, bool predictable_schedule)
41 : min_marked_bytes_per_step_(min_marked_bytes_per_step),
42 predictable_schedule_(predictable_schedule) {
44 elapsed_time_override_.emplace(kTimeDeltaForPredictableSchedule);
45 }
46}
47
54
61
63 size_t marked_bytes) {
64 mutator_thread_marked_bytes_ += marked_bytes;
65}
66
68 size_t marked_bytes) {
69 concurrently_marked_bytes_.fetch_add(marked_bytes, std::memory_order_relaxed);
70}
71
75
77 return concurrently_marked_bytes_.load(std::memory_order_relaxed);
78}
79
82 if (elapsed_time_override_.has_value()) {
83 const v8::base::TimeDelta elapsed_time = *elapsed_time_override_;
85 elapsed_time_override_ = kTimeDeltaForPredictableSchedule;
86 } else {
88 }
89 return elapsed_time;
90 }
92}
93
98
100 size_t estimated_live_bytes) {
101 last_estimated_live_bytes_ = estimated_live_bytes;
103 const auto elapsed_time = GetElapsedTimeSinceMarkingStart();
104 const size_t last_marked_bytes = current_step_.marked_bytes();
105 const size_t actual_marked_bytes = GetOverallMarkedBytes();
106 const size_t expected_marked_bytes =
107 std::ceil(estimated_live_bytes * elapsed_time.InMillisecondsF() /
109 // Stash away the current data for others to access.
111 estimated_live_bytes, expected_marked_bytes, elapsed_time};
112 if ((actual_marked_bytes >= last_marked_bytes) &&
113 (actual_marked_bytes - last_marked_bytes) <
116 }
117 if (expected_marked_bytes < actual_marked_bytes) {
118 // Marking is ahead of schedule, incremental marking should do the minimum.
120 }
121 // Assuming marking will take |kEstimatedMarkingTime|, overall there will
122 // be |estimated_live_bytes| live bytes to mark, and that marking speed is
123 // constant, after |elapsed_time| the number of marked_bytes should be
124 // |estimated_live_bytes| * (|elapsed_time| / |kEstimatedMarkingTime|),
125 // denoted as |expected_marked_bytes|. If |actual_marked_bytes| is less,
126 // i.e. marking is behind schedule, incremental marking should help "catch
127 // up" by marking (|expected_marked_bytes| - |actual_marked_bytes|).
128 return std::max(min_marked_bytes_per_step_,
129 expected_marked_bytes - actual_marked_bytes);
130}
131
132constexpr double
142
145 const size_t current_concurrently_marked_bytes = GetConcurrentlyMarkedBytes();
146 if (current_concurrently_marked_bytes > last_concurrently_marked_bytes_) {
147 last_concurrently_marked_bytes_ = current_concurrently_marked_bytes;
149 return {};
150 }
151 // In case `NotifyConcurrentMarkingStart()` was not called we just return an
152 // empty time delta, providing the same signal as making progress.
154 return {};
155 }
157}
158
163
164} // namespace heap::base
static std::unique_ptr< IncrementalMarkingSchedule > CreateWithMarkedBytesPerStepForTesting(size_t min_marked_bytes_per_step, bool predictable_schedule=false)
size_t GetNextIncrementalStepDuration(size_t estimated_live_bytes)
std::optional< v8::base::TimeDelta > elapsed_time_override_
static std::unique_ptr< IncrementalMarkingSchedule > Create(bool predictable_schedule=false)
IncrementalMarkingSchedule(const IncrementalMarkingSchedule &)=delete
static constexpr v8::base::TimeDelta kEstimatedMarkingTime
double InMillisecondsF() const
Definition time.cc:226
static constexpr TimeDelta FromMilliseconds(int64_t milliseconds)
Definition time.h:84
static TimeTicks Now()
Definition time.cc:736
constexpr bool IsNull() const
Definition time.h:265
#define DCHECK(condition)
Definition logging.h:482