summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc')
-rw-r--r--chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc91
1 files changed, 91 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc b/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc
new file mode 100644
index 00000000000..f17cea8db7b
--- /dev/null
+++ b/chromium/third_party/blink/renderer/platform/heap/marking_scheduling_oracle.cc
@@ -0,0 +1,91 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/platform/heap/marking_scheduling_oracle.h"
+
+namespace blink {
+
+constexpr double MarkingSchedulingOracle::kEstimatedMarkingTimeMs;
+constexpr base::TimeDelta
+ MarkingSchedulingOracle::kDefaultIncrementalMarkingStepDuration;
+constexpr size_t MarkingSchedulingOracle::kMinimumMarkedBytesInStep;
+constexpr base::TimeDelta
+ MarkingSchedulingOracle::kMaximumIncrementalMarkingStepDuration;
+
+MarkingSchedulingOracle::MarkingSchedulingOracle()
+ : incremental_marking_start_time_(base::TimeTicks::Now()) {}
+
+void MarkingSchedulingOracle::UpdateIncrementalMarkingStats(
+ size_t overall_marked_bytes,
+ base::TimeDelta overall_marking_time) {
+ incrementally_marked_bytes_ = overall_marked_bytes;
+ incremental_marking_time_so_far_ = overall_marking_time;
+}
+
+void MarkingSchedulingOracle::AddConcurrentlyMarkedBytes(size_t marked_bytes) {
+ base::AutoLock lock(concurrently_marked_bytes_lock_);
+ concurrently_marked_bytes_ += marked_bytes;
+}
+
+size_t MarkingSchedulingOracle::GetOverallMarkedBytes() {
+ base::AutoLock lock(concurrently_marked_bytes_lock_);
+ return incrementally_marked_bytes_ + concurrently_marked_bytes_;
+}
+
+double MarkingSchedulingOracle::GetElapsedTimeInMs(base::TimeTicks start_time) {
+ if (elapsed_time_for_testing_ != kNoSetElapsedTimeForTesting) {
+ double elapsed_time = elapsed_time_for_testing_;
+ elapsed_time_for_testing_ = kNoSetElapsedTimeForTesting;
+ return elapsed_time;
+ }
+ return (base::TimeTicks::Now() - start_time).InMillisecondsF();
+}
+
+base::TimeDelta MarkingSchedulingOracle::GetMinimumStepDuration() {
+ DCHECK_LT(0u, incrementally_marked_bytes_);
+ DCHECK(!incremental_marking_time_so_far_.is_zero());
+ base::TimeDelta minimum_duration = incremental_marking_time_so_far_ *
+ kMinimumMarkedBytesInStep /
+ incrementally_marked_bytes_;
+ return minimum_duration;
+}
+
+base::TimeDelta MarkingSchedulingOracle::GetNextIncrementalStepDurationForTask(
+ size_t estimated_live_bytes) {
+ if ((incrementally_marked_bytes_ == 0) ||
+ incremental_marking_time_so_far_.is_zero()) {
+ // Impossible to estimate marking speed. Fallback to default duration.
+ return kDefaultIncrementalMarkingStepDuration;
+ }
+ double elapsed_time_in_ms =
+ GetElapsedTimeInMs(incremental_marking_start_time_);
+ size_t actual_marked_bytes = GetOverallMarkedBytes();
+ double expected_marked_bytes =
+ estimated_live_bytes * elapsed_time_in_ms / kEstimatedMarkingTimeMs;
+ base::TimeDelta minimum_duration = GetMinimumStepDuration();
+ if (expected_marked_bytes < actual_marked_bytes) {
+ // Marking is ahead of schedule, incremental marking doesn't need to
+ // do anything.
+ return std::min(minimum_duration, kMaximumIncrementalMarkingStepDuration);
+ }
+ // Assuming marking will take |kEstimatedMarkingTime|, overall there will
+ // be |estimated_live_bytes| live bytes to mark, and that marking speed is
+ // constant, after |elapsed_time| the number of marked_bytes should be
+ // |estimated_live_bytes| * (|elapsed_time| / |kEstimatedMarkingTime|),
+ // denoted as |expected_marked_bytes|. If |actual_marked_bytes| is less,
+ // i.e. marking is behind schedule, incremental marking should help "catch
+ // up" by marking (|expected_marked_bytes| - |actual_marked_bytes|).
+ // Assuming constant marking speed, duration of the next incremental step
+ // should be as follows:
+ double marking_time_to_catch_up_in_ms =
+ (expected_marked_bytes - actual_marked_bytes) *
+ incremental_marking_time_so_far_.InMillisecondsF() /
+ incrementally_marked_bytes_;
+ return std::min(
+ kMaximumIncrementalMarkingStepDuration,
+ std::max(minimum_duration, base::TimeDelta::FromMillisecondsD(
+ marking_time_to_catch_up_in_ms)));
+}
+
+} // namespace blink