From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Yutaka Hirano Date: Fri, 11 Jun 2021 08:42:15 +0000 Subject: Reduce memory consumption on LongTaskObserver::DidProcessTask https://crrev.com/c/2909934 fixed a security issue, but it introduced a copy operation for each DidProcessTask for a long task. We see a memory regression on the change, and this is an attempt to mitigate the regression. (cherry picked from commit 8097e73295a88e64d8318d982847a5e4f2bcc4d2) (cherry picked from commit 7be6a34fe2f01af881bb074bc616bf5b6b5f7c31) Bug: 1210487, 1211539 Change-Id: Ib9101e29d70fadb11b7967754e847bb5cc754feb Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2915153 Reviewed-by: Benoit L Commit-Queue: Yutaka Hirano Cr-Original-Original-Commit-Position: refs/heads/master@{#886221} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2944320 Bot-Commit: Rubber Stamper Cr-Original-Commit-Position: refs/branch-heads/4472@{#1460} Cr-Original-Branched-From: 3d60439cfb36485e76a1c5bb7f513d3721b20da1-refs/heads/master@{#870763} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2948750 Owners-Override: Victor-Gabriel Savu Reviewed-by: Artem Sumaneev Commit-Queue: Victor-Gabriel Savu Cr-Commit-Position: refs/branch-heads/4430@{#1520} Cr-Branched-From: e5ce7dc4f7518237b3d9bb93cccca35d25216cbe-refs/heads/master@{#857950} diff --git a/third_party/blink/renderer/core/loader/long_task_detector.cc b/third_party/blink/renderer/core/loader/long_task_detector.cc index f040ae5053265fb136c629f106aeefa0b01130f1..3816779cfafaef06295734b4a8a2f033bf752691 100644 --- a/third_party/blink/renderer/core/loader/long_task_detector.cc +++ b/third_party/blink/renderer/core/loader/long_task_detector.cc @@ -24,6 +24,7 @@ LongTaskDetector::LongTaskDetector() = default; void LongTaskDetector::RegisterObserver(LongTaskObserver* observer) { DCHECK(IsMainThread()); DCHECK(observer); + DCHECK(!iterating_); if (observers_.insert(observer).is_new_entry && observers_.size() == 1) { // Number of observers just became non-zero. Thread::Current()->AddTaskTimeObserver(this); @@ -32,6 +33,10 @@ void LongTaskDetector::RegisterObserver(LongTaskObserver* observer) { void LongTaskDetector::UnregisterObserver(LongTaskObserver* observer) { DCHECK(IsMainThread()); + if (iterating_) { + observers_to_be_removed_.push_back(observer); + return; + } observers_.erase(observer); if (observers_.size() == 0) { Thread::Current()->RemoveTaskTimeObserver(this); @@ -43,16 +48,21 @@ void LongTaskDetector::DidProcessTask(base::TimeTicks start_time, if ((end_time - start_time) < LongTaskDetector::kLongTaskThreshold) return; - // We copy `observers_` because it might be mutated in OnLongTaskDetected, - // and container mutation is not allowed during iteration. - const HeapHashSet> observers = observers_; - for (auto& observer : observers) { + iterating_ = true; + for (auto& observer : observers_) { observer->OnLongTaskDetected(start_time, end_time); } + iterating_ = false; + + for (const auto& observer : observers_to_be_removed_) { + UnregisterObserver(observer); + } + observers_to_be_removed_.clear(); } void LongTaskDetector::Trace(Visitor* visitor) const { visitor->Trace(observers_); + visitor->Trace(observers_to_be_removed_); } } // namespace blink diff --git a/third_party/blink/renderer/core/loader/long_task_detector.h b/third_party/blink/renderer/core/loader/long_task_detector.h index dc6f0dbab5c059b83bfe4212f0126e9690ab1a7f..5fd4bb8d2abcc67dd4e47927daa260fa37bc4aca 100644 --- a/third_party/blink/renderer/core/loader/long_task_detector.h +++ b/third_party/blink/renderer/core/loader/long_task_detector.h @@ -49,6 +49,8 @@ class CORE_EXPORT LongTaskDetector final base::TimeTicks end_time) override; HeapHashSet> observers_; + HeapVector> observers_to_be_removed_; + bool iterating_ = false; DISALLOW_COPY_AND_ASSIGN(LongTaskDetector); }; diff --git a/third_party/blink/renderer/core/loader/long_task_detector_test.cc b/third_party/blink/renderer/core/loader/long_task_detector_test.cc index 04959d3b682ddbf40577adc5799fe57a9ae9d500..403ba452362a3fa2a6b24f238bad35d9eb1bac0c 100644 --- a/third_party/blink/renderer/core/loader/long_task_detector_test.cc +++ b/third_party/blink/renderer/core/loader/long_task_detector_test.cc @@ -39,6 +39,8 @@ class SelfUnregisteringObserver } bool IsCalled() const { return called_; } + void Reset() { called_ = false; } + private: bool called_ = false; }; @@ -148,6 +150,11 @@ TEST_F(LongTaskDetectorTest, SelfUnregisteringObserver) { SimulateTask(LongTaskDetector::kLongTaskThreshold + base::TimeDelta::FromMilliseconds(10)); EXPECT_TRUE(observer->IsCalled()); + observer->Reset(); + + SimulateTask(LongTaskDetector::kLongTaskThreshold + + base::TimeDelta::FromMilliseconds(10)); + EXPECT_FALSE(observer->IsCalled()); } } // namespace blink