Commit 77099c24 authored by amistry's avatar amistry Committed by Commit bot

Convert renderer JS memory usage reporting to use Mojo.

As a result, removes the
NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED notification.

BUG=268984, 487927

Review URL: https://codereview.chromium.org/1081323003

Cr-Commit-Position: refs/heads/master@{#330692}
parent 3c38cc3e
...@@ -254,13 +254,6 @@ enum NotificationType { ...@@ -254,13 +254,6 @@ enum NotificationType {
// The details are none and the source is a Profile*. // The details are none and the source is a Profile*.
NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED, NOTIFICATION_PROFILE_URL_REQUEST_CONTEXT_GETTER_INITIALIZED,
// Task Manager ------------------------------------------------------------
// Sent when a renderer process is notified of new v8 heap statistics. The
// source is the ID of the renderer process, and the details are a
// V8HeapStatsDetails object.
NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
// Non-history storage services -------------------------------------------- // Non-history storage services --------------------------------------------
// The state of a web resource has been changed. A resource may have been // The state of a web resource has been changed. A resource may have been
......
...@@ -5,19 +5,57 @@ ...@@ -5,19 +5,57 @@
#include "chrome/browser/process_resource_usage.h" #include "chrome/browser/process_resource_usage.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop/message_loop_proxy.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
class ProcessResourceUsage::ErrorHandler : public mojo::ErrorHandler {
public:
ErrorHandler(ProcessResourceUsage* usage) : usage_(usage) {}
// mojo::ErrorHandler implementation:
void OnConnectionError() override;
private:
ProcessResourceUsage* usage_; // Not owned.
};
void ProcessResourceUsage::ErrorHandler::OnConnectionError() {
usage_->RunPendingRefreshCallbacks();
}
ProcessResourceUsage::ProcessResourceUsage(ResourceUsageReporterPtr service) ProcessResourceUsage::ProcessResourceUsage(ResourceUsageReporterPtr service)
: service_(service.Pass()), update_in_progress_(false) { : service_(service.Pass()),
update_in_progress_(false),
error_handler_(new ErrorHandler(this)) {
service_.set_error_handler(error_handler_.get());
} }
ProcessResourceUsage::~ProcessResourceUsage() { ProcessResourceUsage::~ProcessResourceUsage() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
} }
void ProcessResourceUsage::Refresh() { void ProcessResourceUsage::RunPendingRefreshCallbacks() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
if (!update_in_progress_ && service_) { auto message_loop = base::MessageLoopProxy::current();
for (const auto& callback : refresh_callbacks_)
message_loop->PostTask(FROM_HERE, callback);
refresh_callbacks_.clear();
}
void ProcessResourceUsage::Refresh(const base::Closure& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!service_ || service_.encountered_error()) {
if (!callback.is_null())
base::MessageLoopProxy::current()->PostTask(FROM_HERE, callback);
return;
}
if (!callback.is_null())
refresh_callbacks_.push_back(callback);
if (!update_in_progress_) {
update_in_progress_ = true; update_in_progress_ = true;
service_->GetUsageData(base::Bind(&ProcessResourceUsage::OnRefreshDone, service_->GetUsageData(base::Bind(&ProcessResourceUsage::OnRefreshDone,
base::Unretained(this))); base::Unretained(this)));
...@@ -28,6 +66,7 @@ void ProcessResourceUsage::OnRefreshDone(ResourceUsageDataPtr data) { ...@@ -28,6 +66,7 @@ void ProcessResourceUsage::OnRefreshDone(ResourceUsageDataPtr data) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
update_in_progress_ = false; update_in_progress_ = false;
stats_ = data.Pass(); stats_ = data.Pass();
RunPendingRefreshCallbacks();
} }
bool ProcessResourceUsage::ReportsV8MemoryStats() const { bool ProcessResourceUsage::ReportsV8MemoryStats() const {
......
...@@ -5,7 +5,11 @@ ...@@ -5,7 +5,11 @@
#ifndef CHROME_BROWSER_PROCESS_RESOURCE_USAGE_H_ #ifndef CHROME_BROWSER_PROCESS_RESOURCE_USAGE_H_
#define CHROME_BROWSER_PROCESS_RESOURCE_USAGE_H_ #define CHROME_BROWSER_PROCESS_RESOURCE_USAGE_H_
#include <deque>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "chrome/common/resource_usage_reporter.mojom.h" #include "chrome/common/resource_usage_reporter.mojom.h"
...@@ -34,8 +38,9 @@ class ProcessResourceUsage { ...@@ -34,8 +38,9 @@ class ProcessResourceUsage {
explicit ProcessResourceUsage(ResourceUsageReporterPtr service); explicit ProcessResourceUsage(ResourceUsageReporterPtr service);
~ProcessResourceUsage(); ~ProcessResourceUsage();
// Refresh the resource usage information. // Refresh the resource usage information. |callback| is invoked when the
void Refresh(); // usage data is updated, or when the IPC connection is lost.
void Refresh(const base::Closure& callback);
// Get V8 memory usage information. // Get V8 memory usage information.
bool ReportsV8MemoryStats() const; bool ReportsV8MemoryStats() const;
...@@ -43,14 +48,20 @@ class ProcessResourceUsage { ...@@ -43,14 +48,20 @@ class ProcessResourceUsage {
size_t GetV8MemoryUsed() const; size_t GetV8MemoryUsed() const;
private: private:
class ErrorHandler;
// Mojo IPC callback. // Mojo IPC callback.
void OnRefreshDone(ResourceUsageDataPtr data); void OnRefreshDone(ResourceUsageDataPtr data);
void RunPendingRefreshCallbacks();
ResourceUsageReporterPtr service_; ResourceUsageReporterPtr service_;
bool update_in_progress_; bool update_in_progress_;
std::deque<base::Closure> refresh_callbacks_;
ResourceUsageDataPtr stats_; ResourceUsageDataPtr stats_;
scoped_ptr<ErrorHandler> error_handler_;
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(ProcessResourceUsage); DISALLOW_COPY_AND_ASSIGN(ProcessResourceUsage);
......
...@@ -79,7 +79,6 @@ bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message) { ...@@ -79,7 +79,6 @@ bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnResourceTypeStats) OnResourceTypeStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats, IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats,
OnUpdatedCacheStats) OnUpdatedCacheStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_V8HeapStats, OnV8HeapStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage)
IPC_MESSAGE_HANDLER_DELAY_REPLY( IPC_MESSAGE_HANDLER_DELAY_REPLY(
...@@ -161,32 +160,6 @@ void ChromeRenderMessageFilter::OnUpdatedCacheStats( ...@@ -161,32 +160,6 @@ void ChromeRenderMessageFilter::OnUpdatedCacheStats(
render_process_id_, stats); render_process_id_, stats);
} }
void ChromeRenderMessageFilter::OnV8HeapStats(int v8_memory_allocated,
int v8_memory_used) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&ChromeRenderMessageFilter::OnV8HeapStats, this,
v8_memory_allocated, v8_memory_used));
return;
}
base::ProcessId renderer_id = peer_pid();
#if defined(ENABLE_TASK_MANAGER)
TaskManager::GetInstance()->model()->NotifyV8HeapStats(
renderer_id,
static_cast<size_t>(v8_memory_allocated),
static_cast<size_t>(v8_memory_used));
#endif // defined(ENABLE_TASK_MANAGER)
V8HeapStatsDetails details(v8_memory_allocated, v8_memory_used);
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
content::Source<const base::ProcessId>(&renderer_id),
content::Details<const V8HeapStatsDetails>(&details));
}
void ChromeRenderMessageFilter::OnAllowDatabase( void ChromeRenderMessageFilter::OnAllowDatabase(
int render_frame_id, int render_frame_id,
const GURL& origin_url, const GURL& origin_url,
......
...@@ -35,19 +35,6 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter { ...@@ -35,19 +35,6 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter {
public: public:
ChromeRenderMessageFilter(int render_process_id, Profile* profile); ChromeRenderMessageFilter(int render_process_id, Profile* profile);
class V8HeapStatsDetails {
public:
V8HeapStatsDetails(size_t v8_memory_allocated,
size_t v8_memory_used)
: v8_memory_allocated_(v8_memory_allocated),
v8_memory_used_(v8_memory_used) {}
size_t v8_memory_allocated() const { return v8_memory_allocated_; }
size_t v8_memory_used() const { return v8_memory_used_; }
private:
size_t v8_memory_allocated_;
size_t v8_memory_used_;
};
// content::BrowserMessageFilter methods: // content::BrowserMessageFilter methods:
bool OnMessageReceived(const IPC::Message& message) override; bool OnMessageReceived(const IPC::Message& message) override;
void OverrideThreadForMessage(const IPC::Message& message, void OverrideThreadForMessage(const IPC::Message& message,
...@@ -63,7 +50,6 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter { ...@@ -63,7 +50,6 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter {
void OnPreconnect(const GURL& url, int count); void OnPreconnect(const GURL& url, int count);
void OnResourceTypeStats(const blink::WebCache::ResourceTypeStats& stats); void OnResourceTypeStats(const blink::WebCache::ResourceTypeStats& stats);
void OnUpdatedCacheStats(const blink::WebCache::UsageStats& stats); void OnUpdatedCacheStats(const blink::WebCache::UsageStats& stats);
void OnV8HeapStats(int v8_memory_allocated, int v8_memory_used);
void OnAllowDatabase(int render_frame_id, void OnAllowDatabase(int render_frame_id,
const GURL& origin_url, const GURL& origin_url,
......
...@@ -253,7 +253,7 @@ base::string16 ChildProcessResource::GetLocalizedTitle() const { ...@@ -253,7 +253,7 @@ base::string16 ChildProcessResource::GetLocalizedTitle() const {
void ChildProcessResource::Refresh() { void ChildProcessResource::Refresh() {
if (resource_usage_) if (resource_usage_)
resource_usage_->Refresh(); resource_usage_->Refresh(base::Closure());
} }
bool ChildProcessResource::ReportsV8MemoryStats() const { bool ChildProcessResource::ReportsV8MemoryStats() const {
......
...@@ -6,12 +6,14 @@ ...@@ -6,12 +6,14 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/process_resource_usage.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/task_manager/resource_provider.h" #include "chrome/browser/task_manager/resource_provider.h"
#include "chrome/browser/task_manager/task_manager_util.h" #include "chrome/browser/task_manager/task_manager_util.h"
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/common/service_registry.h"
namespace task_manager { namespace task_manager {
...@@ -19,15 +21,17 @@ RendererResource::RendererResource(base::ProcessHandle process, ...@@ -19,15 +21,17 @@ RendererResource::RendererResource(base::ProcessHandle process,
content::RenderViewHost* render_view_host) content::RenderViewHost* render_view_host)
: process_(process), : process_(process),
render_view_host_(render_view_host), render_view_host_(render_view_host),
pending_stats_update_(false), pending_stats_update_(false) {
v8_memory_allocated_(0),
v8_memory_used_(0),
pending_v8_memory_allocated_update_(false) {
// We cache the process and pid as when a Tab/BackgroundContents is closed the // We cache the process and pid as when a Tab/BackgroundContents is closed the
// process reference becomes NULL and the TaskManager still needs it. // process reference becomes NULL and the TaskManager still needs it.
pid_ = base::GetProcId(process_);
unique_process_id_ = render_view_host_->GetProcess()->GetID(); unique_process_id_ = render_view_host_->GetProcess()->GetID();
memset(&stats_, 0, sizeof(stats_)); memset(&stats_, 0, sizeof(stats_));
ResourceUsageReporterPtr service;
content::ServiceRegistry* service_registry =
render_view_host_->GetProcess()->GetServiceRegistry();
if (service_registry)
service_registry->ConnectToRemoteService(&service);
process_resource_usage_.reset(new ProcessResourceUsage(service.Pass()));
} }
RendererResource::~RendererResource() { RendererResource::~RendererResource() {
...@@ -38,10 +42,7 @@ void RendererResource::Refresh() { ...@@ -38,10 +42,7 @@ void RendererResource::Refresh() {
render_view_host_->Send(new ChromeViewMsg_GetCacheResourceStats); render_view_host_->Send(new ChromeViewMsg_GetCacheResourceStats);
pending_stats_update_ = true; pending_stats_update_ = true;
} }
if (!pending_v8_memory_allocated_update_) { process_resource_usage_->Refresh(base::Closure());
render_view_host_->Send(new ChromeViewMsg_GetV8HeapStats);
pending_v8_memory_allocated_update_ = true;
}
} }
blink::WebCache::ResourceTypeStats blink::WebCache::ResourceTypeStats
...@@ -50,11 +51,11 @@ RendererResource::GetWebCoreCacheStats() const { ...@@ -50,11 +51,11 @@ RendererResource::GetWebCoreCacheStats() const {
} }
size_t RendererResource::GetV8MemoryAllocated() const { size_t RendererResource::GetV8MemoryAllocated() const {
return v8_memory_allocated_; return process_resource_usage_->GetV8MemoryAllocated();
} }
size_t RendererResource::GetV8MemoryUsed() const { size_t RendererResource::GetV8MemoryUsed() const {
return v8_memory_used_; return process_resource_usage_->GetV8MemoryUsed();
} }
void RendererResource::NotifyResourceTypeStats( void RendererResource::NotifyResourceTypeStats(
...@@ -63,13 +64,6 @@ void RendererResource::NotifyResourceTypeStats( ...@@ -63,13 +64,6 @@ void RendererResource::NotifyResourceTypeStats(
pending_stats_update_ = false; pending_stats_update_ = false;
} }
void RendererResource::NotifyV8HeapStats(
size_t v8_memory_allocated, size_t v8_memory_used) {
v8_memory_allocated_ = v8_memory_allocated;
v8_memory_used_ = v8_memory_used;
pending_v8_memory_allocated_update_ = false;
}
base::string16 RendererResource::GetProfileName() const { base::string16 RendererResource::GetProfileName() const {
return util::GetProfileNameFromInfoCache(Profile::FromBrowserContext( return util::GetProfileNameFromInfoCache(Profile::FromBrowserContext(
render_view_host_->GetProcess()->GetBrowserContext())); render_view_host_->GetProcess()->GetBrowserContext()));
......
...@@ -6,8 +6,11 @@ ...@@ -6,8 +6,11 @@
#define CHROME_BROWSER_TASK_MANAGER_RENDERER_RESOURCE_H_ #define CHROME_BROWSER_TASK_MANAGER_RENDERER_RESOURCE_H_
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/task_manager/resource_provider.h" #include "chrome/browser/task_manager/resource_provider.h"
class ProcessResourceUsage;
namespace content { namespace content {
class RenderViewHost; class RenderViewHost;
} }
...@@ -44,16 +47,12 @@ class RendererResource : public Resource { ...@@ -44,16 +47,12 @@ class RendererResource : public Resource {
void NotifyResourceTypeStats( void NotifyResourceTypeStats(
const blink::WebCache::ResourceTypeStats& stats) override; const blink::WebCache::ResourceTypeStats& stats) override;
void NotifyV8HeapStats(size_t v8_memory_allocated,
size_t v8_memory_used) override;
content::RenderViewHost* render_view_host() const { content::RenderViewHost* render_view_host() const {
return render_view_host_; return render_view_host_;
} }
private: private:
base::ProcessHandle process_; base::ProcessHandle process_;
int pid_;
int unique_process_id_; int unique_process_id_;
// RenderViewHost we use to fetch stats. // RenderViewHost we use to fetch stats.
...@@ -64,10 +63,7 @@ class RendererResource : public Resource { ...@@ -64,10 +63,7 @@ class RendererResource : public Resource {
// This flag is true if we are waiting for the renderer to report its stats. // This flag is true if we are waiting for the renderer to report its stats.
bool pending_stats_update_; bool pending_stats_update_;
// We do a similar dance to gather the V8 memory usage in a process. scoped_ptr<ProcessResourceUsage> process_resource_usage_;
size_t v8_memory_allocated_;
size_t v8_memory_used_;
bool pending_v8_memory_allocated_update_;
DISALLOW_COPY_AND_ASSIGN(RendererResource); DISALLOW_COPY_AND_ASSIGN(RendererResource);
}; };
......
...@@ -96,8 +96,6 @@ class Resource { ...@@ -96,8 +96,6 @@ class Resource {
virtual void NotifyResourceTypeStats( virtual void NotifyResourceTypeStats(
const blink::WebCache::ResourceTypeStats& stats) {} const blink::WebCache::ResourceTypeStats& stats) {}
virtual void NotifyV8HeapStats(size_t v8_memory_allocated,
size_t v8_memory_used) {}
static const char* GetResourceTypeAsString(const Type type) { static const char* GetResourceTypeAsString(const Type type) {
switch (type) { switch (type) {
......
...@@ -1216,17 +1216,6 @@ void TaskManagerModel::NotifyVideoMemoryUsageStats( ...@@ -1216,17 +1216,6 @@ void TaskManagerModel::NotifyVideoMemoryUsageStats(
pending_video_memory_usage_stats_update_ = false; pending_video_memory_usage_stats_update_ = false;
} }
void TaskManagerModel::NotifyV8HeapStats(base::ProcessId renderer_id,
size_t v8_memory_allocated,
size_t v8_memory_used) {
for (ResourceList::iterator it = resources_.begin();
it != resources_.end(); ++it) {
if (base::GetProcId((*it)->GetProcess()) == renderer_id) {
(*it)->NotifyV8HeapStats(v8_memory_allocated, v8_memory_used);
}
}
}
void TaskManagerModel::NotifyBytesRead(const net::URLRequest& request, void TaskManagerModel::NotifyBytesRead(const net::URLRequest& request,
int byte_count) { int byte_count) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
......
...@@ -281,7 +281,7 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> { ...@@ -281,7 +281,7 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> {
// changes to the model. // changes to the model.
void ModelChanged(); void ModelChanged();
// Updates the values for all rows. // Updates the values for all rows.
void Refresh(); void Refresh();
void NotifyResourceTypeStats( void NotifyResourceTypeStats(
...@@ -291,10 +291,6 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> { ...@@ -291,10 +291,6 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> {
void NotifyVideoMemoryUsageStats( void NotifyVideoMemoryUsageStats(
const content::GPUVideoMemoryUsageStats& video_memory_usage_stats); const content::GPUVideoMemoryUsageStats& video_memory_usage_stats);
void NotifyV8HeapStats(base::ProcessId renderer_id,
size_t v8_memory_allocated,
size_t v8_memory_used);
void NotifyBytesRead(const net::URLRequest& request, int bytes_read); void NotifyBytesRead(const net::URLRequest& request, int bytes_read);
void RegisterOnDataReadyCallback(const base::Closure& callback); void RegisterOnDataReadyCallback(const base::Closure& callback);
......
...@@ -4,11 +4,15 @@ ...@@ -4,11 +4,15 @@
#include "chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h" #include "chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h"
#include <map>
#include <set> #include <set>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "base/values.h" #include "base/values.h"
...@@ -17,6 +21,7 @@ ...@@ -17,6 +21,7 @@
#include "chrome/browser/memory_details.h" #include "chrome/browser/memory_details.h"
#include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h" #include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/process_resource_usage.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/renderer_host/chrome_render_message_filter.h" #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
...@@ -29,13 +34,11 @@ ...@@ -29,13 +34,11 @@
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui.h"
#include "content/public/common/service_registry.h"
#if defined(ENABLE_PRINT_PREVIEW) #if defined(ENABLE_PRINT_PREVIEW)
#include "chrome/browser/printing/background_printing_manager.h" #include "chrome/browser/printing/background_printing_manager.h"
...@@ -118,34 +121,52 @@ void GetAllWebContents(std::set<content::WebContents*>* web_contents) { ...@@ -118,34 +121,52 @@ void GetAllWebContents(std::set<content::WebContents*>* web_contents) {
} // namespace } // namespace
class RendererDetails : public content::NotificationObserver { class RendererDetails {
public: public:
typedef base::Callback<void(const base::ProcessId pid, typedef base::Callback<void(const base::ProcessId pid,
const size_t v8_allocated, const size_t v8_allocated,
const size_t v8_used)> V8DataCallback; const size_t v8_used)> V8DataCallback;
explicit RendererDetails(const V8DataCallback& callback) explicit RendererDetails(const V8DataCallback& callback)
: callback_(callback) { : callback_(callback), weak_factory_(this) {}
registrar_.Add(this, chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED, ~RendererDetails() {}
content::NotificationService::AllSources());
}
~RendererDetails() override {}
void Request() { void Request() {
for (std::set<content::WebContents*>::iterator iter = web_contents_.begin(); for (std::set<content::WebContents*>::iterator iter = web_contents_.begin();
iter != web_contents_.end(); ++iter) iter != web_contents_.end(); ++iter) {
(*iter)->GetRenderViewHost()->Send(new ChromeViewMsg_GetV8HeapStats); auto rph = (*iter)->GetRenderViewHost()->GetProcess();
auto resource_usage = resource_usage_reporters_[(*iter)];
DCHECK(resource_usage.get());
resource_usage->Refresh(base::Bind(&RendererDetails::OnRefreshDone,
weak_factory_.GetWeakPtr(), *iter,
base::GetProcId(rph->GetHandle())));
}
} }
void AddWebContents(content::WebContents* content) { void AddWebContents(content::WebContents* content) {
web_contents_.insert(content); web_contents_.insert(content);
auto rph = content->GetRenderViewHost()->GetProcess();
content::ServiceRegistry* service_registry = rph->GetServiceRegistry();
ResourceUsageReporterPtr service;
if (service_registry)
service_registry->ConnectToRemoteService(&service);
resource_usage_reporters_.insert(std::make_pair(
content, make_linked_ptr(new ProcessResourceUsage(service.Pass()))));
DCHECK_EQ(web_contents_.size(), resource_usage_reporters_.size());
} }
void Clear() { void Clear() {
web_contents_.clear(); web_contents_.clear();
resource_usage_reporters_.clear();
weak_factory_.InvalidateWeakPtrs();
} }
void RemoveWebContents(base::ProcessId) { void RemoveWebContents(base::ProcessId) {
// This function should only be called once for each WebContents, so this
// should be non-empty every time it's called.
DCHECK(!web_contents_.empty());
// We don't have to detect which content is the caller of this method. // We don't have to detect which content is the caller of this method.
if (!web_contents_.empty()) if (!web_contents_.empty())
web_contents_.erase(web_contents_.begin()); web_contents_.erase(web_contents_.begin());
...@@ -156,23 +177,19 @@ class RendererDetails : public content::NotificationObserver { ...@@ -156,23 +177,19 @@ class RendererDetails : public content::NotificationObserver {
} }
private: private:
// NotificationObserver: void OnRefreshDone(content::WebContents* content, const base::ProcessId pid) {
void Observe(int type, auto iter = resource_usage_reporters_.find(content);
const content::NotificationSource& source, DCHECK(iter != resource_usage_reporters_.end());
const content::NotificationDetails& details) override { linked_ptr<ProcessResourceUsage> usage = iter->second;
const base::ProcessId* pid = callback_.Run(pid, usage->GetV8MemoryAllocated(), usage->GetV8MemoryUsed());
content::Source<const base::ProcessId>(source).ptr();
const ChromeRenderMessageFilter::V8HeapStatsDetails* v8_heap =
content::Details<const ChromeRenderMessageFilter::V8HeapStatsDetails>(
details).ptr();
callback_.Run(*pid,
v8_heap->v8_memory_allocated(),
v8_heap->v8_memory_used());
} }
V8DataCallback callback_; V8DataCallback callback_;
content::NotificationRegistrar registrar_;
std::set<content::WebContents*> web_contents_; // This class does not own std::set<content::WebContents*> web_contents_; // This class does not own
std::map<content::WebContents*, linked_ptr<ProcessResourceUsage>>
resource_usage_reporters_;
base::WeakPtrFactory<RendererDetails> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RendererDetails); DISALLOW_COPY_AND_ASSIGN(RendererDetails);
}; };
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/memory_details.h" #include "chrome/browser/memory_details.h"
...@@ -78,7 +79,7 @@ class MemoryInternalsProxy ...@@ -78,7 +79,7 @@ class MemoryInternalsProxy
MemoryInternalsHandler* handler_; MemoryInternalsHandler* handler_;
base::DictionaryValue* information_; base::DictionaryValue* information_;
RendererDetails* renderer_details_; scoped_ptr<RendererDetails> renderer_details_;
DISALLOW_COPY_AND_ASSIGN(MemoryInternalsProxy); DISALLOW_COPY_AND_ASSIGN(MemoryInternalsProxy);
}; };
......
...@@ -246,6 +246,7 @@ ...@@ -246,6 +246,7 @@
'variables': { 'enable_wexit_time_destructors': 1, }, 'variables': { 'enable_wexit_time_destructors': 1, },
'dependencies': [ 'dependencies': [
'common', 'common',
'common_mojo_bindings',
'common_net', 'common_net',
'chrome_resources.gyp:chrome_resources', 'chrome_resources.gyp:chrome_resources',
'chrome_resources.gyp:chrome_strings', 'chrome_resources.gyp:chrome_strings',
......
...@@ -238,9 +238,6 @@ IPC_MESSAGE_CONTROL2(ChromeViewMsg_SetFieldTrialGroup, ...@@ -238,9 +238,6 @@ IPC_MESSAGE_CONTROL2(ChromeViewMsg_SetFieldTrialGroup,
std::string /* field trial name */, std::string /* field trial name */,
std::string /* group name that was assigned. */) std::string /* group name that was assigned. */)
// Asks the renderer to send back V8 heap stats.
IPC_MESSAGE_CONTROL0(ChromeViewMsg_GetV8HeapStats)
IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetPageSequenceNumber, IPC_MESSAGE_ROUTED1(ChromeViewMsg_SetPageSequenceNumber,
int /* page_seq_no */) int /* page_seq_no */)
...@@ -485,11 +482,6 @@ IPC_SYNC_MESSAGE_ROUTED2_1(ChromeViewHostMsg_GetSearchProviderInstallState, ...@@ -485,11 +482,6 @@ IPC_SYNC_MESSAGE_ROUTED2_1(ChromeViewHostMsg_GetSearchProviderInstallState,
GURL /* inquiry url */, GURL /* inquiry url */,
search_provider::InstallState /* install */) search_provider::InstallState /* install */)
// Sends back stats about the V8 heap.
IPC_MESSAGE_CONTROL2(ChromeViewHostMsg_V8HeapStats,
int /* size of heap (allocated from the OS) */,
int /* bytes in use */)
// Notifies when a plugin couldn't be loaded because it's outdated. // Notifies when a plugin couldn't be loaded because it's outdated.
IPC_MESSAGE_ROUTED2(ChromeViewHostMsg_BlockedOutdatedPlugin, IPC_MESSAGE_ROUTED2(ChromeViewHostMsg_BlockedOutdatedPlugin,
int /* placeholder ID */, int /* placeholder ID */,
......
...@@ -6,8 +6,6 @@ struct ResourceUsageData { ...@@ -6,8 +6,6 @@ struct ResourceUsageData {
bool reports_v8_stats = false; bool reports_v8_stats = false;
uint64 v8_bytes_allocated = 0; uint64 v8_bytes_allocated = 0;
uint64 v8_bytes_used = 0; uint64 v8_bytes_used = 0;
// TODO(amistry): Consider using this for the renderer process.
}; };
interface ResourceUsageReporter { interface ResourceUsageReporter {
......
...@@ -32,6 +32,7 @@ static_library("renderer") { ...@@ -32,6 +32,7 @@ static_library("renderer") {
deps = [ deps = [
"//base/allocator", "//base/allocator",
"//chrome/common", "//chrome/common",
"//chrome/common:mojo_bindings",
"//chrome/common/net", "//chrome/common/net",
"//chrome:resources", "//chrome:resources",
"//chrome:strings", "//chrome:strings",
......
...@@ -25,17 +25,20 @@ ...@@ -25,17 +25,20 @@
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/net/net_resource_provider.h" #include "chrome/common/net/net_resource_provider.h"
#include "chrome/common/render_messages.h" #include "chrome/common/render_messages.h"
#include "chrome/common/resource_usage_reporter.mojom.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/common/variations/variations_util.h" #include "chrome/common/variations/variations_util.h"
#include "chrome/renderer/content_settings_observer.h" #include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/security_filter_peer.h" #include "chrome/renderer/security_filter_peer.h"
#include "content/public/child/resource_dispatcher_delegate.h" #include "content/public/child/resource_dispatcher_delegate.h"
#include "content/public/common/service_registry.h"
#include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_visitor.h" #include "content/public/renderer/render_view_visitor.h"
#include "crypto/nss_util.h" #include "crypto/nss_util.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/base/net_module.h" #include "net/base/net_module.h"
#include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"
#include "third_party/WebKit/public/web/WebCache.h" #include "third_party/WebKit/public/web/WebCache.h"
#include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebFrame.h"
...@@ -110,98 +113,87 @@ class RendererResourceDelegate : public content::ResourceDispatcherDelegate { ...@@ -110,98 +113,87 @@ class RendererResourceDelegate : public content::ResourceDispatcherDelegate {
static const int kWaitForWorkersStatsTimeoutMS = 20; static const int kWaitForWorkersStatsTimeoutMS = 20;
class HeapStatisticsCollector { class ResourceUsageReporterImpl : public ResourceUsageReporter {
public: public:
HeapStatisticsCollector() : round_id_(0) {} explicit ResourceUsageReporterImpl(
mojo::InterfaceRequest<ResourceUsageReporter> req)
void InitiateCollection(); : binding_(this, req.Pass()), weak_factory_(this) {}
static HeapStatisticsCollector* Instance(); ~ResourceUsageReporterImpl() override {}
private: private:
void CollectOnWorkerThread(scoped_refptr<base::TaskRunner> master, static void CollectOnWorkerThread(
int round_id); const scoped_refptr<base::TaskRunner>& master,
void ReceiveStats(int round_id, size_t total_size, size_t used_size); base::WeakPtr<ResourceUsageReporterImpl> impl) {
void SendStatsToBrowser(int round_id); size_t total_bytes = 0;
size_t used_bytes = 0;
size_t total_bytes_; v8::Isolate* isolate = v8::Isolate::GetCurrent();
size_t used_bytes_; if (isolate) {
int workers_to_go_; v8::HeapStatistics heap_stats;
int round_id_; isolate->GetHeapStatistics(&heap_stats);
}; total_bytes = heap_stats.total_heap_size();
used_bytes = heap_stats.used_heap_size();
}
master->PostTask(FROM_HERE,
base::Bind(&ResourceUsageReporterImpl::ReceiveStats, impl,
total_bytes, used_bytes));
}
HeapStatisticsCollector* HeapStatisticsCollector::Instance() { void ReceiveStats(size_t total_bytes, size_t used_bytes) {
CR_DEFINE_STATIC_LOCAL(HeapStatisticsCollector, instance, ()); usage_data_->v8_bytes_allocated += total_bytes;
return &instance; usage_data_->v8_bytes_used += used_bytes;
} workers_to_go_--;
if (!workers_to_go_)
SendResults();
}
void HeapStatisticsCollector::InitiateCollection() { void SendResults() {
v8::HeapStatistics heap_stats; if (!callback_.is_null())
v8::Isolate::GetCurrent()->GetHeapStatistics(&heap_stats); callback_.Run(usage_data_.Pass());
total_bytes_ = heap_stats.total_heap_size(); callback_.reset();
used_bytes_ = heap_stats.used_heap_size(); weak_factory_.InvalidateWeakPtrs();
base::Closure collect = base::Bind( workers_to_go_ = 0;
&HeapStatisticsCollector::CollectOnWorkerThread,
base::Unretained(this),
base::MessageLoopProxy::current(),
round_id_);
workers_to_go_ = RenderThread::Get()->PostTaskToAllWebWorkers(collect);
if (workers_to_go_) {
// The guard task to send out partial stats
// in case some workers are not responsive.
base::MessageLoopProxy::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&HeapStatisticsCollector::SendStatsToBrowser,
base::Unretained(this),
round_id_),
base::TimeDelta::FromMilliseconds(kWaitForWorkersStatsTimeoutMS));
} else {
// No worker threads so just send out the main thread data right away.
SendStatsToBrowser(round_id_);
} }
}
void HeapStatisticsCollector::CollectOnWorkerThread( void GetUsageData(
scoped_refptr<base::TaskRunner> master, const mojo::Callback<void(ResourceUsageDataPtr)>& callback) override {
int round_id) { DCHECK(callback_.is_null());
weak_factory_.InvalidateWeakPtrs();
usage_data_ = ResourceUsageData::New();
usage_data_->reports_v8_stats = true;
callback_ = callback;
size_t total_bytes = 0;
size_t used_bytes = 0;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (isolate) {
v8::HeapStatistics heap_stats; v8::HeapStatistics heap_stats;
isolate->GetHeapStatistics(&heap_stats); v8::Isolate::GetCurrent()->GetHeapStatistics(&heap_stats);
total_bytes = heap_stats.total_heap_size(); usage_data_->v8_bytes_allocated = heap_stats.total_heap_size();
used_bytes = heap_stats.used_heap_size(); usage_data_->v8_bytes_used = heap_stats.used_heap_size();
base::Closure collect = base::Bind(
&ResourceUsageReporterImpl::CollectOnWorkerThread,
base::MessageLoopProxy::current(), weak_factory_.GetWeakPtr());
workers_to_go_ = RenderThread::Get()->PostTaskToAllWebWorkers(collect);
if (workers_to_go_) {
// The guard task to send out partial stats
// in case some workers are not responsive.
base::MessageLoopProxy::current()->PostDelayedTask(
FROM_HERE, base::Bind(&ResourceUsageReporterImpl::SendResults,
weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kWaitForWorkersStatsTimeoutMS));
} else {
// No worker threads so just send out the main thread data right away.
SendResults();
}
} }
master->PostTask(
FROM_HERE,
base::Bind(&HeapStatisticsCollector::ReceiveStats,
base::Unretained(this),
round_id,
total_bytes,
used_bytes));
}
void HeapStatisticsCollector::ReceiveStats(int round_id, ResourceUsageDataPtr usage_data_;
size_t total_bytes, mojo::Callback<void(ResourceUsageDataPtr)> callback_;
size_t used_bytes) { int workers_to_go_;
if (round_id != round_id_) mojo::StrongBinding<ResourceUsageReporter> binding_;
return;
total_bytes_ += total_bytes; base::WeakPtrFactory<ResourceUsageReporterImpl> weak_factory_;
used_bytes_ += used_bytes; };
if (!--workers_to_go_)
SendStatsToBrowser(round_id);
}
void HeapStatisticsCollector::SendStatsToBrowser(int round_id) { void CreateResourceUsageReporter(
if (round_id != round_id_) mojo::InterfaceRequest<ResourceUsageReporter> request) {
return; new ResourceUsageReporterImpl(request.Pass());
// TODO(alph): Do caching heap stats and use the cache if we haven't got
// reply from a worker.
// Currently a busy worker stats are not counted.
RenderThread::Get()->Send(new ChromeViewHostMsg_V8HeapStats(
total_bytes_, used_bytes_));
++round_id_;
} }
} // namespace } // namespace
...@@ -231,6 +223,12 @@ ChromeRenderProcessObserver::ChromeRenderProcessObserver() ...@@ -231,6 +223,12 @@ ChromeRenderProcessObserver::ChromeRenderProcessObserver()
resource_delegate_.reset(new RendererResourceDelegate()); resource_delegate_.reset(new RendererResourceDelegate());
thread->SetResourceDispatcherDelegate(resource_delegate_.get()); thread->SetResourceDispatcherDelegate(resource_delegate_.get());
content::ServiceRegistry* service_registry = thread->GetServiceRegistry();
if (service_registry) {
service_registry->AddService<ResourceUsageReporter>(
base::Bind(CreateResourceUsageReporter));
}
// Configure modules that need access to resources. // Configure modules that need access to resources.
net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider); net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
...@@ -261,7 +259,6 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived( ...@@ -261,7 +259,6 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived(
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetIsIncognitoProcess, IPC_MESSAGE_HANDLER(ChromeViewMsg_SetIsIncognitoProcess,
OnSetIsIncognitoProcess) OnSetIsIncognitoProcess)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup) IPC_MESSAGE_HANDLER(ChromeViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup)
IPC_MESSAGE_HANDLER(ChromeViewMsg_GetV8HeapStats, OnGetV8HeapStats)
IPC_MESSAGE_HANDLER(ChromeViewMsg_GetCacheResourceStats, IPC_MESSAGE_HANDLER(ChromeViewMsg_GetCacheResourceStats,
OnGetCacheResourceStats) OnGetCacheResourceStats)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules, IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules,
...@@ -321,10 +318,6 @@ void ChromeRenderProcessObserver::OnSetFieldTrialGroup( ...@@ -321,10 +318,6 @@ void ChromeRenderProcessObserver::OnSetFieldTrialGroup(
chrome_variations::SetChildProcessLoggingVariationList(); chrome_variations::SetChildProcessLoggingVariationList();
} }
void ChromeRenderProcessObserver::OnGetV8HeapStats() {
HeapStatisticsCollector::Instance()->InitiateCollection();
}
const RendererContentSettingRules* const RendererContentSettingRules*
ChromeRenderProcessObserver::content_setting_rules() const { ChromeRenderProcessObserver::content_setting_rules() const {
return &content_setting_rules_; return &content_setting_rules_;
......
...@@ -54,7 +54,6 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver, ...@@ -54,7 +54,6 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver,
void OnGetCacheResourceStats(); void OnGetCacheResourceStats();
void OnSetFieldTrialGroup(const std::string& fiel_trial_name, void OnSetFieldTrialGroup(const std::string& fiel_trial_name,
const std::string& group_name); const std::string& group_name);
void OnGetV8HeapStats();
static bool is_incognito_process_; static bool is_incognito_process_;
scoped_ptr<content::ResourceDispatcherDelegate> resource_delegate_; scoped_ptr<content::ResourceDispatcherDelegate> resource_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