Commit 5548808f authored by Sebastien Marchand's avatar Sebastien Marchand Committed by Commit Bot

[PM] High PM policy: discard tabs directly

This updates the High PM policy to make it discard tabs directly rather
than sending memory pressure signals.

Change-Id: I26c85179b8c03268d84c0c99918239f2344bb6d3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2304106
Commit-Queue: Sébastien Marchand <sebmarchand@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790908}
parent b790cc7a
......@@ -1073,8 +1073,6 @@ static_library("browser") {
"performance_manager/decorators/process_metrics_decorator.h",
"performance_manager/decorators/process_priority_aggregator.cc",
"performance_manager/decorators/process_priority_aggregator.h",
"performance_manager/mechanisms/high_pmf_memory_pressure_signals.cc",
"performance_manager/mechanisms/high_pmf_memory_pressure_signals.h",
"performance_manager/mechanisms/working_set_trimmer.cc",
"performance_manager/mechanisms/working_set_trimmer.h",
"performance_manager/metrics/memory_pressure_metrics.cc",
......@@ -1084,8 +1082,6 @@ static_library("browser") {
"performance_manager/observers/isolation_context_metrics.h",
"performance_manager/observers/metrics_collector.cc",
"performance_manager/observers/metrics_collector.h",
"performance_manager/policies/high_pmf_memory_pressure_policy.cc",
"performance_manager/policies/high_pmf_memory_pressure_policy.h",
"performance_manager/policies/policy_features.cc",
"performance_manager/policies/policy_features.h",
"performance_manager/policies/working_set_trimmer_policy.cc",
......@@ -3363,6 +3359,8 @@ static_library("browser") {
"performance_manager/policies/background_tab_loading_policy.h",
"performance_manager/policies/background_tab_loading_policy_helpers.cc",
"performance_manager/policies/background_tab_loading_policy_helpers.h",
"performance_manager/policies/high_pmf_discard_policy.cc",
"performance_manager/policies/high_pmf_discard_policy.h",
"performance_manager/policies/page_discarding_helper.cc",
"performance_manager/policies/page_discarding_helper.h",
"performance_manager/policies/urgent_page_discarding_policy.cc",
......
......@@ -19,7 +19,7 @@
#include "chrome/browser/performance_manager/observers/isolation_context_metrics.h"
#include "chrome/browser/performance_manager/observers/metrics_collector.h"
#include "chrome/browser/performance_manager/policies/background_tab_loading_policy.h"
#include "chrome/browser/performance_manager/policies/high_pmf_memory_pressure_policy.h"
#include "chrome/browser/performance_manager/policies/high_pmf_discard_policy.h"
#include "chrome/browser/performance_manager/policies/policy_features.h"
#include "chrome/browser/performance_manager/policies/working_set_trimmer_policy.h"
#include "chrome/browser/profiles/profile_manager.h"
......@@ -120,18 +120,17 @@ void ChromeBrowserMainExtraPartsPerformanceManager::CreatePoliciesAndDecorators(
std::make_unique<
performance_manager::policies::BackgroundTabLoadingPolicy>());
}
if (base::FeatureList::IsEnabled(
performance_manager::features::kHighPMFDiscardPolicy)) {
graph->PassToGraph(std::make_unique<
performance_manager::policies::HighPMFDiscardPolicy>());
}
#endif // !defined(OS_ANDROID)
graph->PassToGraph(
std::make_unique<performance_manager::metrics::MemoryPressureMetrics>());
if (base::FeatureList::IsEnabled(
performance_manager::features::kHighPMFMemoryPressureSignals)) {
graph->PassToGraph(
std::make_unique<
performance_manager::policies::HighPMFMemoryPressurePolicy>());
}
if (base::FeatureList::IsEnabled(
performance_manager::features::kTabLoadingFrameNavigationThrottles)) {
graph->PassToGraph(
......
......@@ -49,12 +49,12 @@ void ProcessMetricsDecorator::StartTimer() {
#if !defined(OS_ANDROID)
// Bump the refresh frequency when urgent discarding is done from the graph or
// when emitting memory pressure signals on high PMF as these features relies
// on relatively fresh data.
// when discarding tabs on high PMF as these features relies on relatively
// fresh data.
// TODO(sebmarchand): Measure the performance impact of this.
if (base::FeatureList::IsEnabled(
features::kUrgentDiscardingFromPerformanceManager) ||
base::FeatureList::IsEnabled(features::kHighPMFMemoryPressureSignals)) {
base::FeatureList::IsEnabled(features::kHighPMFDiscardPolicy)) {
refresh_period = kFastRefreshTimerPeriod;
}
#endif
......
// 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 "chrome/browser/performance_manager/mechanisms/high_pmf_memory_pressure_signals.h"
#include <memory>
#include "base/bind.h"
#include "base/memory/memory_pressure_monitor.h"
#include "base/util/memory_pressure/memory_pressure_voter.h"
#include "base/util/memory_pressure/multi_source_memory_pressure_monitor.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
namespace performance_manager {
namespace mechanism {
// Wrapper around a MemoryPressureVoter living on the UI thread.
class MemoryPressureVoterOnUIThread {
public:
MemoryPressureVoterOnUIThread() = default;
virtual ~MemoryPressureVoterOnUIThread() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}
MemoryPressureVoterOnUIThread(const MemoryPressureVoterOnUIThread& other) =
delete;
MemoryPressureVoterOnUIThread& operator=(
const MemoryPressureVoterOnUIThread&) = delete;
void InitOnUIThread() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
voter_ = static_cast<util::MultiSourceMemoryPressureMonitor*>(
base::MemoryPressureMonitor::Get())
->CreateVoter();
}
void SetVote(base::MemoryPressureListener::MemoryPressureLevel level,
bool notify) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
voter_->SetVote(level, notify);
}
private:
std::unique_ptr<util::MemoryPressureVoter> voter_;
};
HighPMFMemoryPressureSignals::HighPMFMemoryPressureSignals() {
ui_thread_voter_ = std::make_unique<MemoryPressureVoterOnUIThread>();
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(&MemoryPressureVoterOnUIThread::InitOnUIThread,
base::Unretained(ui_thread_voter_.get())));
}
HighPMFMemoryPressureSignals::~HighPMFMemoryPressureSignals() {
content::GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE,
std::move(ui_thread_voter_));
}
void HighPMFMemoryPressureSignals::SetPressureLevel(MemoryPressureLevel level) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
bool notify = level == MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL;
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(&MemoryPressureVoterOnUIThread::SetVote,
base::Unretained(ui_thread_voter_.get()), level, notify));
pressure_level_ = level;
}
} // namespace mechanism
} // namespace performance_manager
// 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.
#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_MECHANISMS_HIGH_PMF_MEMORY_PRESSURE_SIGNALS_H_
#define CHROME_BROWSER_PERFORMANCE_MANAGER_MECHANISMS_HIGH_PMF_MEMORY_PRESSURE_SIGNALS_H_
#include "base/memory/memory_pressure_listener.h"
#include "base/sequence_checker.h"
namespace performance_manager {
namespace mechanism {
class MemoryPressureVoterOnUIThread;
// HighPMFMemoryPressureSignals is meant to be used by a
// HighPMFMemoryPressurePolicy to notify the global MemoryPressureMonitor when
// the total PMF of Chrome exceeds a threshold.
class HighPMFMemoryPressureSignals {
public:
using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
HighPMFMemoryPressureSignals();
~HighPMFMemoryPressureSignals();
HighPMFMemoryPressureSignals(const HighPMFMemoryPressureSignals& other) =
delete;
HighPMFMemoryPressureSignals& operator=(const HighPMFMemoryPressureSignals&) =
delete;
// Should be called each time the memory pressure level computed by
// HighPMFMemoryPressurePolicy changes.
void SetPressureLevel(MemoryPressureLevel level);
private:
MemoryPressureLevel pressure_level_ =
MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_NONE;
std::unique_ptr<MemoryPressureVoterOnUIThread> ui_thread_voter_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace mechanism
} // namespace performance_manager
#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_MECHANISMS_HIGH_PMF_MEMORY_PRESSURE_SIGNALS_H_
......@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/performance_manager/policies/high_pmf_memory_pressure_policy.h"
#include "chrome/browser/performance_manager/policies/high_pmf_discard_policy.h"
#include "base/bind.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/metrics/field_trial_params.h"
#include "base/process/process_metrics.h"
#include "chrome/browser/performance_manager/mechanisms/high_pmf_memory_pressure_signals.h"
#include "chrome/browser/performance_manager/policies/page_discarding_helper.h"
#include "chrome/browser/performance_manager/policies/policy_features.h"
#include "components/performance_manager/public/graph/process_node.h"
......@@ -20,15 +19,20 @@ namespace {
// The factor that will be applied to the total amount of RAM to establish the
// PMF limit.
static constexpr base::FeatureParam<double> kRAMRatioPMFLimitFactor{
&performance_manager::features::kHighPMFMemoryPressureSignals,
&performance_manager::features::kHighPMFDiscardPolicy,
"RAMRatioPMFLimitFactor", 1.5};
// The discard strategy to use.
static constexpr base::FeatureParam<int> kDiscardStrategy{
&performance_manager::features::kHighPMFDiscardPolicy, "DiscardStrategy",
static_cast<int>(features::DiscardStrategy::LRU)};
} // namespace
HighPMFMemoryPressurePolicy::HighPMFMemoryPressurePolicy() = default;
HighPMFMemoryPressurePolicy::~HighPMFMemoryPressurePolicy() = default;
HighPMFDiscardPolicy::HighPMFDiscardPolicy() = default;
HighPMFDiscardPolicy::~HighPMFDiscardPolicy() = default;
void HighPMFMemoryPressurePolicy::OnPassedToGraph(Graph* graph) {
void HighPMFDiscardPolicy::OnPassedToGraph(Graph* graph) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
graph->AddSystemNodeObserver(this);
graph_ = graph;
......@@ -37,37 +41,51 @@ void HighPMFMemoryPressurePolicy::OnPassedToGraph(Graph* graph) {
if (base::GetSystemMemoryInfo(&mem_info))
pmf_limit_kb_ = mem_info.total * kRAMRatioPMFLimitFactor.Get();
mechanism_ = std::make_unique<mechanism::HighPMFMemoryPressureSignals>();
DCHECK(PageDiscardingHelper::GetFromGraph(graph_))
<< "A PageDiscardingHelper instance should be registered against the "
"graph in order to use this policy.";
}
void HighPMFMemoryPressurePolicy::OnTakenFromGraph(Graph* graph) {
void HighPMFDiscardPolicy::OnTakenFromGraph(Graph* graph) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
graph->RemoveSystemNodeObserver(this);
graph_ = nullptr;
pmf_limit_kb_ = kInvalidPMFLimitValue;
mechanism_.reset();
}
void HighPMFMemoryPressurePolicy::OnProcessMemoryMetricsAvailable(
void HighPMFDiscardPolicy::OnProcessMemoryMetricsAvailable(
const SystemNode* unused) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (pmf_limit_kb_ == kInvalidPMFLimitValue)
return;
if (discard_attempt_in_progress_)
return;
int total_pmf_kb = 0;
MemoryPressureLevel pressure_level =
MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_NONE;
bool should_discard = false;
auto process_nodes = graph_->GetAllProcessNodes();
for (const auto* node : process_nodes) {
total_pmf_kb += node->GetPrivateFootprintKb();
if (total_pmf_kb >= pmf_limit_kb_) {
pressure_level = MemoryPressureLevel::MEMORY_PRESSURE_LEVEL_CRITICAL;
should_discard = true;
break;
}
}
mechanism_->SetPressureLevel(pressure_level);
if (should_discard) {
discard_attempt_in_progress_ = true;
PageDiscardingHelper::GetFromGraph(graph_)->UrgentlyDiscardAPage(
static_cast<features::DiscardStrategy>(kDiscardStrategy.Get()),
base::BindOnce(&HighPMFDiscardPolicy::PostDiscardAttemptCallback,
base::Unretained(this)));
}
}
void HighPMFDiscardPolicy::PostDiscardAttemptCallback(bool success) {
DCHECK(discard_attempt_in_progress_);
discard_attempt_in_progress_ = false;
}
} // namespace policies
......
......@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_HIGH_PMF_MEMORY_PRESSURE_POLICY_H_
#define CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_HIGH_PMF_MEMORY_PRESSURE_POLICY_H_
#ifndef CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_HIGH_PMF_DISCARD_POLICY_H_
#define CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_HIGH_PMF_DISCARD_POLICY_H_
#include "base/memory/memory_pressure_listener.h"
#include "base/sequence_checker.h"
#include "components/performance_manager/public/graph/graph.h"
#include "components/performance_manager/public/graph/system_node.h"
......@@ -14,23 +13,17 @@ namespace performance_manager {
class Graph;
namespace mechanism {
class HighPMFMemoryPressureSignals;
}
namespace policies {
// The HighPMFMemoryPressurePolicy will emit critical memory pressure signal
// when Chrome's total PMF exceeds a given threshold.
class HighPMFMemoryPressurePolicy : public GraphOwned,
public SystemNode::ObserverDefaultImpl {
// The HighPMFDiscardPolicy will discard tabs when Chrome's total PMF exceeds a
// given threshold.
class HighPMFDiscardPolicy : public GraphOwned,
public SystemNode::ObserverDefaultImpl {
public:
HighPMFMemoryPressurePolicy();
~HighPMFMemoryPressurePolicy() override;
HighPMFMemoryPressurePolicy(const HighPMFMemoryPressurePolicy& other) =
delete;
HighPMFMemoryPressurePolicy& operator=(const HighPMFMemoryPressurePolicy&) =
delete;
HighPMFDiscardPolicy();
~HighPMFDiscardPolicy() override;
HighPMFDiscardPolicy(const HighPMFDiscardPolicy& other) = delete;
HighPMFDiscardPolicy& operator=(const HighPMFDiscardPolicy&) = delete;
// GraphOwned implementation:
void OnPassedToGraph(Graph* graph) override;
......@@ -44,18 +37,23 @@ class HighPMFMemoryPressurePolicy : public GraphOwned,
}
private:
using MemoryPressureLevel = base::MemoryPressureListener::MemoryPressureLevel;
// Callback called when a discard attempt has completed.
void PostDiscardAttemptCallback(bool success);
const int kInvalidPMFLimitValue = 0;
int pmf_limit_kb_ = kInvalidPMFLimitValue;
std::unique_ptr<mechanism::HighPMFMemoryPressureSignals> mechanism_;
Graph* graph_ = nullptr;
// Indicates whether or not there's a discard attempt in progress. This could
// happen if this attempt doesn't complete between 2 calls to
// OnProcessMemoryMetricsAvailable.
bool discard_attempt_in_progress_ = false;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace policies
} // namespace performance_manager
#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_HIGH_PMF_MEMORY_PRESSURE_POLICY_H_
#endif // CHROME_BROWSER_PERFORMANCE_MANAGER_POLICIES_HIGH_PMF_DISCARD_POLICY_H_
// 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 "chrome/browser/performance_manager/policies/high_pmf_discard_policy.h"
#include "base/bind.h"
#include "chrome/browser/performance_manager/test_support/page_discarding_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace performance_manager {
namespace policies {
using HighPMFDiscardPolicyTest = testing::GraphTestHarnessWithMockDiscarder;
TEST_F(HighPMFDiscardPolicyTest, EndToEnd) {
// Create the policy and pass it to the graph.
auto policy = std::make_unique<HighPMFDiscardPolicy>();
auto* policy_raw = policy.get();
graph()->PassToGraph(std::move(policy));
const int kPMFLimitKb = 100 * 1024;
policy_raw->set_pmf_limit_for_testing(kPMFLimitKb);
auto process_node = CreateNode<performance_manager::ProcessNodeImpl>();
process_node->set_private_footprint_kb(kPMFLimitKb - 1);
graph()->FindOrCreateSystemNodeImpl()->OnProcessMemoryMetricsAvailable();
// Make sure that no task get posted to the discarder.
task_env().RunUntilIdle();
::testing::Mock::VerifyAndClearExpectations(discarder());
process_node->set_private_footprint_kb(kPMFLimitKb);
EXPECT_CALL(*discarder(), DiscardPageNodeImpl(page_node()))
.WillOnce(::testing::Return(true));
graph()->FindOrCreateSystemNodeImpl()->OnProcessMemoryMetricsAvailable();
task_env().RunUntilIdle();
::testing::Mock::VerifyAndClearExpectations(discarder());
graph()->TakeFromGraph(policy_raw);
}
} // namespace policies
} // namespace performance_manager
// 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 "chrome/browser/performance_manager/policies/high_pmf_memory_pressure_policy.h"
#include "base/bind.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/util/memory_pressure/multi_source_memory_pressure_monitor.h"
#include "components/performance_manager/graph/graph_impl.h"
#include "components/performance_manager/test_support/graph_test_harness.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace performance_manager {
namespace policies {
using HighPMFMemoryPressurePolicyTest = GraphTestHarness;
TEST_F(HighPMFMemoryPressurePolicyTest, EndToEnd) {
// Create the policy and pass it to the graph.
auto policy = std::make_unique<HighPMFMemoryPressurePolicy>();
auto* policy_raw = policy.get();
graph()->PassToGraph(std::move(policy));
const int kPMFLimitKb = 100 * 1024;
policy_raw->set_pmf_limit_for_testing(kPMFLimitKb);
// Create a MemoryPressureListener object that will record that a critical
// memory pressure signal has been emitted.
base::RunLoop run_loop;
auto quit_closure = run_loop.QuitClosure();
bool memory_pressure_listener_called = false;
util::MultiSourceMemoryPressureMonitor memory_pressure_monitor;
base::MemoryPressureListener memory_pressure_listener(
FROM_HERE,
base::BindLambdaForTesting(
[&](base::MemoryPressureListener::MemoryPressureLevel level) {
EXPECT_EQ(base::MemoryPressureListener::MemoryPressureLevel::
MEMORY_PRESSURE_LEVEL_CRITICAL,
level);
memory_pressure_listener_called = true;
quit_closure.Run();
}));
auto process_node = CreateNode<performance_manager::ProcessNodeImpl>();
process_node->set_private_footprint_kb(kPMFLimitKb - 1);
graph()->FindOrCreateSystemNodeImpl()->OnProcessMemoryMetricsAvailable();
// Make sure that no task get posted to the memory pressure monitor to record
// a memory pressure event.
task_env().RunUntilIdle();
EXPECT_FALSE(memory_pressure_listener_called);
EXPECT_EQ(base::MemoryPressureListener::MemoryPressureLevel::
MEMORY_PRESSURE_LEVEL_NONE,
memory_pressure_monitor.GetCurrentPressureLevel());
process_node->set_private_footprint_kb(kPMFLimitKb);
graph()->FindOrCreateSystemNodeImpl()->OnProcessMemoryMetricsAvailable();
// Wait for the MemoryPressureListener to be called.
run_loop.Run();
EXPECT_TRUE(memory_pressure_listener_called);
EXPECT_EQ(base::MemoryPressureListener::MemoryPressureLevel::
MEMORY_PRESSURE_LEVEL_CRITICAL,
memory_pressure_monitor.GetCurrentPressureLevel());
memory_pressure_listener_called = false;
process_node->set_private_footprint_kb(kPMFLimitKb - 1);
graph()->FindOrCreateSystemNodeImpl()->OnProcessMemoryMetricsAvailable();
// Make sure that the pressure level goes back to NONE.
task_env().RunUntilIdle();
EXPECT_FALSE(memory_pressure_listener_called);
EXPECT_EQ(base::MemoryPressureListener::MemoryPressureLevel::
MEMORY_PRESSURE_LEVEL_NONE,
memory_pressure_monitor.GetCurrentPressureLevel());
graph()->TakeFromGraph(policy_raw);
// The policy's voter post a task to the UI thread on destruction, wait for
// this to complete.
task_env().RunUntilIdle();
}
} // namespace policies
} // namespace performance_manager
......@@ -64,7 +64,7 @@ PageDiscardingHelper::PageDiscardingHelper()
PageDiscardingHelper::~PageDiscardingHelper() = default;
void PageDiscardingHelper::UrgentlyDiscardAPage(
features::UrgentDiscardingParams::DiscardStrategy discard_strategy,
features::DiscardStrategy discard_strategy,
base::OnceCallback<void(bool)> post_discard_cb) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......@@ -93,11 +93,9 @@ void PageDiscardingHelper::UrgentlyDiscardAPage(
return;
}
if (discard_strategy ==
features::UrgentDiscardingParams::DiscardStrategy::LRU) {
if (discard_strategy == features::DiscardStrategy::LRU) {
discard_candidate = oldest_bg_discardable_page_node;
} else if (discard_strategy ==
features::UrgentDiscardingParams::DiscardStrategy::BIGGEST_RSS) {
} else if (discard_strategy == features::DiscardStrategy::BIGGEST_RSS) {
// List all the processes associated with these page nodes.
base::flat_set<const ProcessNode*> process_nodes;
for (const auto& iter : discardable_pages) {
......@@ -301,7 +299,7 @@ base::Value PageDiscardingHelper::DescribePageNodeData(
}
void PageDiscardingHelper::PostDiscardAttemptCallback(
features::UrgentDiscardingParams::DiscardStrategy discard_strategy,
features::DiscardStrategy discard_strategy,
base::OnceCallback<void(bool)> post_discard_cb,
bool success) {
if (!success) {
......
......@@ -41,9 +41,8 @@ class PageDiscardingHelper : public GraphOwned,
// Selects a tab to discard based on |strategy| and posts to the UI thread to
// discard it. This will try to discard a tab until there's been a successful
// discard or until there's no more discard candidate.
void UrgentlyDiscardAPage(
features::UrgentDiscardingParams::DiscardStrategy discard_strategy,
base::OnceCallback<void(bool)> post_discard_cb);
void UrgentlyDiscardAPage(features::DiscardStrategy discard_strategy,
base::OnceCallback<void(bool)> post_discard_cb);
// PageNodeObserver:
void OnBeforePageNodeRemoved(const PageNode* page_node) override;
......@@ -77,7 +76,7 @@ class PageDiscardingHelper : public GraphOwned,
// the attempt has been successful. |post_discard_cb| will be called once
// there's been a successful discard or if there's no more discard candidates.
void PostDiscardAttemptCallback(
features::UrgentDiscardingParams::DiscardStrategy discard_strategy,
features::DiscardStrategy discard_strategy,
base::OnceCallback<void(bool)> post_discard_cb,
bool success);
......
......@@ -192,8 +192,7 @@ TEST_F(PageDiscardingHelperTest, TestCannotDiscardPageWithFormInteractions) {
class ParameterizedPageDiscardingHelperTest
: public PageDiscardingHelperTest,
public ::testing::WithParamInterface<
features::UrgentDiscardingParams::DiscardStrategy> {
public ::testing::WithParamInterface<features::DiscardStrategy> {
public:
ParameterizedPageDiscardingHelperTest() = default;
~ParameterizedPageDiscardingHelperTest() override = default;
......@@ -261,8 +260,7 @@ TEST_P(ParameterizedPageDiscardingHelperTest,
process_node()->set_resident_set_kb(1024);
process_node2->set_resident_set_kb(2048);
if (GetParam() ==
features::UrgentDiscardingParams::DiscardStrategy::BIGGEST_RSS) {
if (GetParam() == features::DiscardStrategy::BIGGEST_RSS) {
// |page_node2| should be discarded despite being the most recently visible
// page as it has a bigger footprint.
EXPECT_CALL(*discarder(), DiscardPageNodeImpl(page_node2.get()))
......@@ -301,8 +299,7 @@ TEST_P(ParameterizedPageDiscardingHelperTest,
// Pretends that the first discardable page hasn't been discarded
// successfully, the other one should be discarded in this case.
if (GetParam() ==
features::UrgentDiscardingParams::DiscardStrategy::BIGGEST_RSS) {
if (GetParam() == features::DiscardStrategy::BIGGEST_RSS) {
::testing::InSequence in_sequence;
// The first candidate is the tab with the biggest RSS.
EXPECT_CALL(*discarder(), DiscardPageNodeImpl(page_node2.get()))
......@@ -382,9 +379,8 @@ TEST_P(ParameterizedPageDiscardingHelperTest,
INSTANTIATE_TEST_CASE_P(
PageDiscardingHelperWithParamTest,
ParameterizedPageDiscardingHelperTest,
::testing::Values(
features::UrgentDiscardingParams::DiscardStrategy::LRU,
features::UrgentDiscardingParams::DiscardStrategy::BIGGEST_RSS));
::testing::Values(features::DiscardStrategy::LRU,
features::DiscardStrategy::BIGGEST_RSS));
} // namespace policies
} // namespace performance_manager
......@@ -99,19 +99,18 @@ constexpr base::FeatureParam<int> UrgentDiscardingParams::kDiscardStrategy;
// static
UrgentDiscardingParams UrgentDiscardingParams::GetParams() {
UrgentDiscardingParams params = {};
params.discard_strategy_ =
static_cast<UrgentDiscardingParams::DiscardStrategy>(
UrgentDiscardingParams::kDiscardStrategy.Get());
params.discard_strategy_ = static_cast<DiscardStrategy>(
UrgentDiscardingParams::kDiscardStrategy.Get());
return params;
}
const base::Feature kBackgroundTabLoadingFromPerformanceManager{
"BackgroundTabLoadingFromPerformanceManager",
base::FEATURE_DISABLED_BY_DEFAULT};
#endif
const base::Feature kHighPMFMemoryPressureSignals{
"HighPMFMemoryPressureSignals", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kHighPMFDiscardPolicy{"HighPMFDiscardPolicy",
base::FEATURE_DISABLED_BY_DEFAULT};
#endif
} // namespace features
} // namespace performance_manager
......@@ -82,23 +82,23 @@ extern const base::Feature kPageFreezingFromPerformanceManager;
// than via TabManager.
extern const base::Feature kUrgentDiscardingFromPerformanceManager;
// The discard strategy to use.
// Integer values are specified to allow conversion from the integer value in
// the DiscardStrategy feature param.
enum class DiscardStrategy : int {
// Discards the least recently used tab among the eligible ones. This is the
// default strategy.
LRU = 0,
// Discard the tab with the biggest resident set among the eligible ones.
BIGGEST_RSS = 1,
};
class UrgentDiscardingParams {
public:
~UrgentDiscardingParams();
static UrgentDiscardingParams GetParams();
// The discard strategy to use.
// Integer values are specified to allow conversion from the integer value in
// the DiscardStrategy feature param.
enum class DiscardStrategy : int {
// Discards the least recently used tab among the eligible ones. This is the
// default strategy.
LRU = 0,
// Discard the tab with the biggest resident set among the eligible ones.
BIGGEST_RSS = 1,
};
DiscardStrategy discard_strategy() const { return discard_strategy_; }
static constexpr base::FeatureParam<int> kDiscardStrategy{
......@@ -115,11 +115,11 @@ class UrgentDiscardingParams {
// Enable background tab loading of pages (restored via session restore)
// directly from Performance Manager rather than via TabLoader.
extern const base::Feature kBackgroundTabLoadingFromPerformanceManager;
#endif
// Feature that controls whether or not memory pressure signals will be emitted
// Feature that controls whether or not tabs should be automatically discarded
// when the total PMF is too high.
extern const base::Feature kHighPMFMemoryPressureSignals;
extern const base::Feature kHighPMFDiscardPolicy;
#endif
} // namespace features
} // namespace performance_manager
......
......@@ -3337,7 +3337,6 @@ test("unit_tests") {
"../browser/performance_manager/observers/isolation_context_metrics_unittest.cc",
"../browser/performance_manager/observers/metrics_collector_unittest.cc",
"../browser/performance_manager/policies/dynamic_tcmalloc_policy_chromeos_unittest.cc",
"../browser/performance_manager/policies/high_pmf_memory_pressure_policy_unittest.cc",
"../browser/performance_manager/policies/working_set_trimmer_policy_chromeos_unittest.cc",
"../browser/performance_manager/policies/working_set_trimmer_policy_unittest.cc",
"../browser/performance_manager/test_support/page_aggregator.cc",
......@@ -4142,7 +4141,9 @@ test("unit_tests") {
"../browser/performance_manager/persistence/site_data/unittest_utils.cc",
"../browser/performance_manager/persistence/site_data/unittest_utils.h",
# Urgent discarding from performance_manager isn't supported on Android.
# Urgent discarding from performance_manager and the High-PMF discard
# policy aren't supported on Android.
"../browser/performance_manager/policies/high_pmf_discard_policy_unittest.cc",
"../browser/performance_manager/policies/page_discarding_helper_unittest.cc",
"../browser/performance_manager/policies/urgent_page_discarding_policy_unittest.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment