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 @@ ...@@ -11,7 +11,6 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/process/process_metrics.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -32,7 +31,6 @@ ...@@ -32,7 +31,6 @@
#include "chrome/common/prerender_types.h" #include "chrome/common/prerender_types.h"
#include "chrome/common/prerender_util.h" #include "chrome/common/prerender_util.h"
#include "components/history/core/browser/history_types.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/browser_thread.h"
#include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
...@@ -45,6 +43,7 @@ ...@@ -45,6 +43,7 @@
#include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_delegate.h"
#include "content/public/common/frame_navigate_params.h" #include "content/public/common/frame_navigate_params.h"
#include "net/http/http_response_headers.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 "services/service_manager/public/cpp/binder_registry.h"
#include "ui/base/page_transition_types.h" #include "ui/base/page_transition_types.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
...@@ -203,6 +202,7 @@ PrerenderContents::PrerenderContents(PrerenderManager* prerender_manager, ...@@ -203,6 +202,7 @@ PrerenderContents::PrerenderContents(PrerenderManager* prerender_manager,
has_finished_loading_(false), has_finished_loading_(false),
final_status_(FINAL_STATUS_MAX), final_status_(FINAL_STATUS_MAX),
prerendering_has_been_cancelled_(false), prerendering_has_been_cancelled_(false),
process_pid_(base::kNullProcessId),
child_id_(-1), child_id_(-1),
route_id_(-1), route_id_(-1),
origin_(origin), origin_(origin),
...@@ -634,42 +634,55 @@ void PrerenderContents::Destroy(FinalStatus final_status) { ...@@ -634,42 +634,55 @@ void PrerenderContents::Destroy(FinalStatus final_status) {
NotifyPrerenderStop(); NotifyPrerenderStop();
} }
base::ProcessMetrics* PrerenderContents::MaybeGetProcessMetrics() { void PrerenderContents::DestroyWhenUsingTooManyResources() {
if (!process_metrics_) { if (process_pid_ == base::kNullProcessId) {
// If a PrenderContents hasn't started prerending, don't be fully formed.
const RenderViewHost* rvh = GetRenderViewHost(); const RenderViewHost* rvh = GetRenderViewHost();
if (!rvh) if (!rvh)
return nullptr; return;
const content::RenderProcessHost* rph = rvh->GetProcess(); const content::RenderProcessHost* rph = rvh->GetProcess();
if (!rph) if (!rph)
return nullptr; return;
base::ProcessHandle handle = rph->GetHandle(); base::ProcessHandle handle = rph->GetHandle();
if (handle == base::kNullProcessHandle) if (handle == base::kNullProcessHandle)
return nullptr; return;
#if !defined(OS_MACOSX) process_pid_ = base::GetProcId(handle);
process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(handle);
#else
process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(
handle, content::BrowserChildProcessHost::GetPortProvider());
#endif
} }
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() { void PrerenderContents::DidGetMemoryUsage(
base::ProcessMetrics* metrics = MaybeGetProcessMetrics(); bool success,
if (!metrics) std::unique_ptr<memory_instrumentation::GlobalMemoryDump> global_dump) {
if (!success)
return; return;
size_t private_bytes, shared_bytes; for (const memory_instrumentation::GlobalMemoryDump::ProcessDump& dump :
if (metrics->GetMemoryBytes(&private_bytes, &shared_bytes) && global_dump->process_dumps()) {
private_bytes > prerender_manager_->config().max_bytes) { 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); Destroy(FINAL_STATUS_MEMORY_LIMIT_EXCEEDED);
} }
return;
}
} }
std::unique_ptr<WebContents> PrerenderContents::ReleasePrerenderContents() { std::unique_ptr<WebContents> PrerenderContents::ReleasePrerenderContents() {
......
...@@ -45,6 +45,10 @@ namespace history { ...@@ -45,6 +45,10 @@ namespace history {
struct HistoryAddPageArgs; struct HistoryAddPageArgs;
} }
namespace memory_instrumentation {
class GlobalMemoryDump;
}
namespace prerender { namespace prerender {
class PrerenderManager; class PrerenderManager;
...@@ -302,7 +306,9 @@ class PrerenderContents : public content::NotificationObserver, ...@@ -302,7 +306,9 @@ class PrerenderContents : public content::NotificationObserver,
friend class PrerenderContentsFactoryImpl; friend class PrerenderContentsFactoryImpl;
// Returns the ProcessMetrics for the render process, if it exists. // 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: // chrome::mojom::PrerenderCanceler:
void CancelPrerenderForPrinting() override; void CancelPrerenderForPrinting() override;
...@@ -354,9 +360,9 @@ class PrerenderContents : public content::NotificationObserver, ...@@ -354,9 +360,9 @@ class PrerenderContents : public content::NotificationObserver,
// Used solely to prevent double deletion. // Used solely to prevent double deletion.
bool prerendering_has_been_cancelled_; bool prerendering_has_been_cancelled_;
// Process Metrics of the render process associated with the // Pid of the render process associated with the RenderViewHost for this
// RenderViewHost for this object. // object.
std::unique_ptr<base::ProcessMetrics> process_metrics_; base::ProcessId process_pid_;
std::unique_ptr<WebContentsDelegateImpl> web_contents_delegate_; 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