Commit 9b5926ea authored by Joe Mason's avatar Joe Mason Committed by Commit Bot

[PM] Track lazy and bounded V8PerFrameMemoryRequest's separately

Upgrade lazy requests to bounded to prevent starvation if the lazy
request has not received a result by the time the next bounded request
would be sent.

R=chrisha, ulan

Bug: 1080672
Change-Id: Ic3f44a67ff8052efdd83160ba453218fbb6f24e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2349978
Commit-Queue: Joe Mason <joenotcharles@chromium.org>
Reviewed-by: default avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798757}
parent 3ec8590a
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_V8_MEMORY_V8_PER_FRAME_MEMORY_DECORATOR_H_ #ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_V8_MEMORY_V8_PER_FRAME_MEMORY_DECORATOR_H_
#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_V8_MEMORY_V8_PER_FRAME_MEMORY_DECORATOR_H_ #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_V8_MEMORY_V8_PER_FRAME_MEMORY_DECORATOR_H_
#include <vector>
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -267,6 +269,10 @@ class V8PerFrameMemoryDecorator ...@@ -267,6 +269,10 @@ class V8PerFrameMemoryDecorator
// Returns the next measurement request that should be scheduled. // Returns the next measurement request that should be scheduled.
V8PerFrameMemoryRequest* GetNextRequest() const; V8PerFrameMemoryRequest* GetNextRequest() const;
// Returns the next measurement request with mode kBounded that should be
// scheduled.
V8PerFrameMemoryRequest* GetNextBoundedRequest() const;
// Implementation details below this point. // Implementation details below this point.
// V8PerFrameMemoryRequest objects register themselves with the decorator. // V8PerFrameMemoryRequest objects register themselves with the decorator.
...@@ -287,8 +293,9 @@ class V8PerFrameMemoryDecorator ...@@ -287,8 +293,9 @@ class V8PerFrameMemoryDecorator
Graph* graph_ = nullptr; Graph* graph_ = nullptr;
// List of requests sorted by min_time_between_requests (lowest first). // Lists of requests sorted by min_time_between_requests (lowest first).
std::vector<V8PerFrameMemoryRequest*> measurement_requests_; std::vector<V8PerFrameMemoryRequest*> bounded_measurement_requests_;
std::vector<V8PerFrameMemoryRequest*> lazy_measurement_requests_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
}; };
......
...@@ -571,8 +571,10 @@ TEST_F(V8PerFrameMemoryDecoratorTest, PerFrameDataIsDistributed) { ...@@ -571,8 +571,10 @@ TEST_F(V8PerFrameMemoryDecoratorTest, PerFrameDataIsDistributed) {
} }
TEST_F(V8PerFrameMemoryDecoratorTest, LazyRequests) { TEST_F(V8PerFrameMemoryDecoratorTest, LazyRequests) {
constexpr base::TimeDelta kLazyRequestLength =
base::TimeDelta::FromSeconds(30);
V8PerFrameMemoryRequest lazy_request( V8PerFrameMemoryRequest lazy_request(
kMinTimeBetweenRequests, V8PerFrameMemoryRequest::MeasurementMode::kLazy, kLazyRequestLength, V8PerFrameMemoryRequest::MeasurementMode::kLazy,
graph()); graph());
MockV8PerFrameMemoryReporter reporter; MockV8PerFrameMemoryReporter reporter;
...@@ -586,15 +588,79 @@ TEST_F(V8PerFrameMemoryDecoratorTest, LazyRequests) { ...@@ -586,15 +588,79 @@ TEST_F(V8PerFrameMemoryDecoratorTest, LazyRequests) {
content::PROCESS_TYPE_RENDERER, content::PROCESS_TYPE_RENDERER,
RenderProcessHostProxy::CreateForTesting(kTestProcessID)); RenderProcessHostProxy::CreateForTesting(kTestProcessID));
task_env().RunUntilIdle(); task_env().FastForwardBy(base::TimeDelta::FromSeconds(1));
testing::Mock::VerifyAndClearExpectations(&reporter); testing::Mock::VerifyAndClearExpectations(&reporter);
// Bounded requests should be preferred over lazy requests with the same // If a lazy request takes too long to respond it should be upgraded to a
// min_time_between_requests. // bounded request if one is in the queue.
V8PerFrameMemoryRequest bounded_request(kMinTimeBetweenRequests, graph()); constexpr base::TimeDelta kLongBoundedRequestLength =
base::TimeDelta::FromSeconds(45);
V8PerFrameMemoryRequest long_bounded_request(kLongBoundedRequestLength,
graph());
auto* decorator = V8PerFrameMemoryDecorator::GetFromGraph(graph()); auto* decorator = V8PerFrameMemoryDecorator::GetFromGraph(graph());
ASSERT_TRUE(decorator); ASSERT_TRUE(decorator);
ASSERT_TRUE(decorator->GetNextRequest()); ASSERT_TRUE(decorator->GetNextRequest());
EXPECT_EQ(decorator->GetNextRequest()->min_time_between_requests(),
kLazyRequestLength);
EXPECT_EQ(decorator->GetNextRequest()->mode(),
V8PerFrameMemoryRequest::MeasurementMode::kLazy);
{
// Next lazy request sent after 30 sec + 10 sec delay until reply = 40 sec
// until reply arrives. kLongBoundedRequestLength > 40 sec so the reply
// should arrive in time to prevent upgrading the request.
auto data = blink::mojom::PerProcessV8MemoryUsageData::New();
data->unassociated_bytes_used = 1U;
ExpectQueryAndDelayReply(&reporter, base::TimeDelta::FromSeconds(10),
std::move(data),
MockV8PerFrameMemoryReporter::Mode::LAZY);
}
// Wait long enough for the upgraded request to be sent, to verify that it
// wasn't sent.
task_env().FastForwardBy(kLongBoundedRequestLength);
testing::Mock::VerifyAndClearExpectations(&reporter);
constexpr base::TimeDelta kUpgradeRequestLength =
base::TimeDelta::FromSeconds(40);
V8PerFrameMemoryRequest bounded_request_upgrade(kUpgradeRequestLength,
graph());
ASSERT_TRUE(decorator->GetNextRequest());
EXPECT_EQ(decorator->GetNextRequest()->min_time_between_requests(),
kLazyRequestLength);
EXPECT_EQ(decorator->GetNextRequest()->mode(),
V8PerFrameMemoryRequest::MeasurementMode::kLazy);
{
::testing::InSequence seq;
// Again, 40 sec total until reply arrives. kUpgradeRequestLength <= 40 sec
// so a second upgraded request should be sent.
auto data = blink::mojom::PerProcessV8MemoryUsageData::New();
data->unassociated_bytes_used = 2U;
ExpectQueryAndDelayReply(&reporter, base::TimeDelta::FromSeconds(10),
std::move(data),
MockV8PerFrameMemoryReporter::Mode::LAZY);
auto data2 = blink::mojom::PerProcessV8MemoryUsageData::New();
data2->unassociated_bytes_used = 3U;
ExpectQueryAndReply(&reporter, std::move(data2),
MockV8PerFrameMemoryReporter::Mode::DEFAULT);
}
// Wait long enough for the upgraded request to be sent.
task_env().FastForwardBy(kUpgradeRequestLength);
testing::Mock::VerifyAndClearExpectations(&reporter);
EXPECT_TRUE(V8PerFrameMemoryProcessData::ForProcessNode(process.get()));
EXPECT_EQ(3u, V8PerFrameMemoryProcessData::ForProcessNode(process.get())
->unassociated_v8_bytes_used());
// Bounded requests should be preferred over lazy requests with the same
// min_time_between_requests.
V8PerFrameMemoryRequest short_bounded_request(kLazyRequestLength, graph());
ASSERT_TRUE(decorator->GetNextRequest());
EXPECT_EQ(decorator->GetNextRequest()->min_time_between_requests(),
kLazyRequestLength);
EXPECT_EQ(decorator->GetNextRequest()->mode(), EXPECT_EQ(decorator->GetNextRequest()->mode(),
V8PerFrameMemoryRequest::MeasurementMode::kBounded); V8PerFrameMemoryRequest::MeasurementMode::kBounded);
} }
......
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