Commit 00e7992e authored by erikchen's avatar erikchen Committed by Commit Bot

Convert PrerenderContents to use memory_instrumentation.

PrerenderContents are destroyed when they use too much memory. They were
previously using base::ProcessMetrics, which returns inconsistent
results across OSes. This CL changes it to use memory_instrumentation,
which returns consistent metrics across all OSes.

Bug: 819289
Change-Id: I1b459c2b8838c5ed69c07bf37182ca4e164d7fc3
Reviewed-on: https://chromium-review.googlesource.com/966598Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Commit-Queue: Erik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543825}
parent 1cf01253
......@@ -11,7 +11,6 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/process/process_metrics.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
......@@ -32,7 +31,6 @@
#include "chrome/common/prerender_types.h"
#include "chrome/common/prerender_util.h"
#include "components/history/core/browser/history_types.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_service.h"
......@@ -45,6 +43,7 @@
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/frame_navigate_params.h"
#include "net/http/http_response_headers.h"
#include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "ui/base/page_transition_types.h"
#include "ui/gfx/geometry/size.h"
......@@ -203,6 +202,7 @@ PrerenderContents::PrerenderContents(PrerenderManager* prerender_manager,
has_finished_loading_(false),
final_status_(FINAL_STATUS_MAX),
prerendering_has_been_cancelled_(false),
process_pid_(base::kNullProcessId),
child_id_(-1),
route_id_(-1),
origin_(origin),
......@@ -634,41 +634,54 @@ void PrerenderContents::Destroy(FinalStatus final_status) {
NotifyPrerenderStop();
}
base::ProcessMetrics* PrerenderContents::MaybeGetProcessMetrics() {
if (!process_metrics_) {
// If a PrenderContents hasn't started prerending, don't be fully formed.
void PrerenderContents::DestroyWhenUsingTooManyResources() {
if (process_pid_ == base::kNullProcessId) {
const RenderViewHost* rvh = GetRenderViewHost();
if (!rvh)
return nullptr;
return;
const content::RenderProcessHost* rph = rvh->GetProcess();
if (!rph)
return nullptr;
return;
base::ProcessHandle handle = rph->GetHandle();
if (handle == base::kNullProcessHandle)
return nullptr;
#if !defined(OS_MACOSX)
process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(handle);
#else
process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(
handle, content::BrowserChildProcessHost::GetPortProvider());
#endif
return;
process_pid_ = base::GetProcId(handle);
}
return process_metrics_.get();
if (process_pid_ == base::kNullProcessId)
return;
// Using AdaptCallbackForRepeating allows for an easier transition to
// OnceCallbacks for https://crbug.com/714018.
memory_instrumentation::MemoryInstrumentation::GetInstance()
->RequestGlobalDumpForPid(process_pid_,
base::AdaptCallbackForRepeating(base::BindOnce(
&PrerenderContents::DidGetMemoryUsage,
weak_factory_.GetWeakPtr())));
}
void PrerenderContents::DestroyWhenUsingTooManyResources() {
base::ProcessMetrics* metrics = MaybeGetProcessMetrics();
if (!metrics)
void PrerenderContents::DidGetMemoryUsage(
bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> global_dump) {
if (!success)
return;
size_t private_bytes, shared_bytes;
if (metrics->GetMemoryBytes(&private_bytes, &shared_bytes) &&
private_bytes > prerender_manager_->config().max_bytes) {
Destroy(FINAL_STATUS_MEMORY_LIMIT_EXCEEDED);
for (const memory_instrumentation::GlobalMemoryDump::ProcessDump& dump :
global_dump->process_dumps()) {
if (dump.pid() != process_pid_)
continue;
// If |final_status_| == |FINAL_STATUS_USED|, then destruction will be
// handled by the entity that set final_status_.
if (dump.os_dump().private_footprint_kb * 1024 >
prerender_manager_->config().max_bytes &&
final_status_ != FINAL_STATUS_USED) {
Destroy(FINAL_STATUS_MEMORY_LIMIT_EXCEEDED);
}
return;
}
}
......
......@@ -45,6 +45,10 @@ namespace history {
struct HistoryAddPageArgs;
}
namespace memory_instrumentation {
class GlobalMemoryDump;
}
namespace prerender {
class PrerenderManager;
......@@ -302,7 +306,9 @@ class PrerenderContents : public content::NotificationObserver,
friend class PrerenderContentsFactoryImpl;
// Returns the ProcessMetrics for the render process, if it exists.
base::ProcessMetrics* MaybeGetProcessMetrics();
void DidGetMemoryUsage(
bool success,
std::unique_ptr<memory_instrumentation::GlobalMemoryDump> dump);
// chrome::mojom::PrerenderCanceler:
void CancelPrerenderForPrinting() override;
......@@ -354,9 +360,9 @@ class PrerenderContents : public content::NotificationObserver,
// Used solely to prevent double deletion.
bool prerendering_has_been_cancelled_;
// Process Metrics of the render process associated with the
// RenderViewHost for this object.
std::unique_ptr<base::ProcessMetrics> process_metrics_;
// Pid of the render process associated with the RenderViewHost for this
// object.
base::ProcessId process_pid_;
std::unique_ptr<WebContentsDelegateImpl> web_contents_delegate_;
......
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