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 {
// The details are none and the source is a Profile*.
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 --------------------------------------------
// The state of a web resource has been changed. A resource may have been
......
......@@ -5,19 +5,57 @@
#include "chrome/browser/process_resource_usage.h"
#include "base/bind.h"
#include "base/location.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)
: 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() {
DCHECK(thread_checker_.CalledOnValidThread());
}
void ProcessResourceUsage::Refresh() {
void ProcessResourceUsage::RunPendingRefreshCallbacks() {
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;
service_->GetUsageData(base::Bind(&ProcessResourceUsage::OnRefreshDone,
base::Unretained(this)));
......@@ -28,6 +66,7 @@ void ProcessResourceUsage::OnRefreshDone(ResourceUsageDataPtr data) {
DCHECK(thread_checker_.CalledOnValidThread());
update_in_progress_ = false;
stats_ = data.Pass();
RunPendingRefreshCallbacks();
}
bool ProcessResourceUsage::ReportsV8MemoryStats() const {
......
......@@ -5,7 +5,11 @@
#ifndef CHROME_BROWSER_PROCESS_RESOURCE_USAGE_H_
#define CHROME_BROWSER_PROCESS_RESOURCE_USAGE_H_
#include <deque>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
#include "chrome/common/resource_usage_reporter.mojom.h"
......@@ -34,8 +38,9 @@ class ProcessResourceUsage {
explicit ProcessResourceUsage(ResourceUsageReporterPtr service);
~ProcessResourceUsage();
// Refresh the resource usage information.
void Refresh();
// Refresh the resource usage information. |callback| is invoked when the
// usage data is updated, or when the IPC connection is lost.
void Refresh(const base::Closure& callback);
// Get V8 memory usage information.
bool ReportsV8MemoryStats() const;
......@@ -43,14 +48,20 @@ class ProcessResourceUsage {
size_t GetV8MemoryUsed() const;
private:
class ErrorHandler;
// Mojo IPC callback.
void OnRefreshDone(ResourceUsageDataPtr data);
void RunPendingRefreshCallbacks();
ResourceUsageReporterPtr service_;
bool update_in_progress_;
std::deque<base::Closure> refresh_callbacks_;
ResourceUsageDataPtr stats_;
scoped_ptr<ErrorHandler> error_handler_;
base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(ProcessResourceUsage);
......
......@@ -79,7 +79,6 @@ bool ChromeRenderMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnResourceTypeStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_UpdatedCacheStats,
OnUpdatedCacheStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_V8HeapStats, OnV8HeapStats)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDatabase, OnAllowDatabase)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AllowDOMStorage, OnAllowDOMStorage)
IPC_MESSAGE_HANDLER_DELAY_REPLY(
......@@ -161,32 +160,6 @@ void ChromeRenderMessageFilter::OnUpdatedCacheStats(
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(
int render_frame_id,
const GURL& origin_url,
......
......@@ -35,19 +35,6 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter {
public:
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:
bool OnMessageReceived(const IPC::Message& message) override;
void OverrideThreadForMessage(const IPC::Message& message,
......@@ -63,7 +50,6 @@ class ChromeRenderMessageFilter : public content::BrowserMessageFilter {
void OnPreconnect(const GURL& url, int count);
void OnResourceTypeStats(const blink::WebCache::ResourceTypeStats& stats);
void OnUpdatedCacheStats(const blink::WebCache::UsageStats& stats);
void OnV8HeapStats(int v8_memory_allocated, int v8_memory_used);
void OnAllowDatabase(int render_frame_id,
const GURL& origin_url,
......
......@@ -253,7 +253,7 @@ base::string16 ChildProcessResource::GetLocalizedTitle() const {
void ChildProcessResource::Refresh() {
if (resource_usage_)
resource_usage_->Refresh();
resource_usage_->Refresh(base::Closure());
}
bool ChildProcessResource::ReportsV8MemoryStats() const {
......
......@@ -6,12 +6,14 @@
#include "base/basictypes.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/process_resource_usage.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/task_manager/resource_provider.h"
#include "chrome/browser/task_manager/task_manager_util.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/service_registry.h"
namespace task_manager {
......@@ -19,15 +21,17 @@ RendererResource::RendererResource(base::ProcessHandle process,
content::RenderViewHost* render_view_host)
: process_(process),
render_view_host_(render_view_host),
pending_stats_update_(false),
v8_memory_allocated_(0),
v8_memory_used_(0),
pending_v8_memory_allocated_update_(false) {
pending_stats_update_(false) {
// We cache the process and pid as when a Tab/BackgroundContents is closed the
// process reference becomes NULL and the TaskManager still needs it.
pid_ = base::GetProcId(process_);
unique_process_id_ = render_view_host_->GetProcess()->GetID();
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() {
......@@ -38,10 +42,7 @@ void RendererResource::Refresh() {
render_view_host_->Send(new ChromeViewMsg_GetCacheResourceStats);
pending_stats_update_ = true;
}
if (!pending_v8_memory_allocated_update_) {
render_view_host_->Send(new ChromeViewMsg_GetV8HeapStats);
pending_v8_memory_allocated_update_ = true;
}
process_resource_usage_->Refresh(base::Closure());
}
blink::WebCache::ResourceTypeStats
......@@ -50,11 +51,11 @@ RendererResource::GetWebCoreCacheStats() const {
}
size_t RendererResource::GetV8MemoryAllocated() const {
return v8_memory_allocated_;
return process_resource_usage_->GetV8MemoryAllocated();
}
size_t RendererResource::GetV8MemoryUsed() const {
return v8_memory_used_;
return process_resource_usage_->GetV8MemoryUsed();
}
void RendererResource::NotifyResourceTypeStats(
......@@ -63,13 +64,6 @@ void RendererResource::NotifyResourceTypeStats(
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 {
return util::GetProfileNameFromInfoCache(Profile::FromBrowserContext(
render_view_host_->GetProcess()->GetBrowserContext()));
......
......@@ -6,8 +6,11 @@
#define CHROME_BROWSER_TASK_MANAGER_RENDERER_RESOURCE_H_
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/task_manager/resource_provider.h"
class ProcessResourceUsage;
namespace content {
class RenderViewHost;
}
......@@ -44,16 +47,12 @@ class RendererResource : public Resource {
void NotifyResourceTypeStats(
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 {
return render_view_host_;
}
private:
base::ProcessHandle process_;
int pid_;
int unique_process_id_;
// RenderViewHost we use to fetch stats.
......@@ -64,10 +63,7 @@ class RendererResource : public Resource {
// This flag is true if we are waiting for the renderer to report its stats.
bool pending_stats_update_;
// We do a similar dance to gather the V8 memory usage in a process.
size_t v8_memory_allocated_;
size_t v8_memory_used_;
bool pending_v8_memory_allocated_update_;
scoped_ptr<ProcessResourceUsage> process_resource_usage_;
DISALLOW_COPY_AND_ASSIGN(RendererResource);
};
......
......@@ -96,8 +96,6 @@ class Resource {
virtual void NotifyResourceTypeStats(
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) {
switch (type) {
......
......@@ -1216,17 +1216,6 @@ void TaskManagerModel::NotifyVideoMemoryUsageStats(
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,
int byte_count) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
......
......@@ -281,7 +281,7 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> {
// changes to the model.
void ModelChanged();
// Updates the values for all rows.
// Updates the values for all rows.
void Refresh();
void NotifyResourceTypeStats(
......@@ -291,10 +291,6 @@ class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> {
void NotifyVideoMemoryUsageStats(
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 RegisterOnDataReadyCallback(const base::Closure& callback);
......
......@@ -4,11 +4,15 @@
#include "chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h"
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/sys_info.h"
#include "base/values.h"
......@@ -17,6 +21,7 @@
#include "chrome/browser/memory_details.h"
#include "chrome/browser/prerender/prerender_manager.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_manager.h"
#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
......@@ -29,13 +34,11 @@
#include "chrome/common/render_messages.h"
#include "content/public/browser/navigation_controller.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_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/common/service_registry.h"
#if defined(ENABLE_PRINT_PREVIEW)
#include "chrome/browser/printing/background_printing_manager.h"
......@@ -118,34 +121,52 @@ void GetAllWebContents(std::set<content::WebContents*>* web_contents) {
} // namespace
class RendererDetails : public content::NotificationObserver {
class RendererDetails {
public:
typedef base::Callback<void(const base::ProcessId pid,
const size_t v8_allocated,
const size_t v8_used)> V8DataCallback;
explicit RendererDetails(const V8DataCallback& callback)
: callback_(callback) {
registrar_.Add(this, chrome::NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED,
content::NotificationService::AllSources());
}
~RendererDetails() override {}
: callback_(callback), weak_factory_(this) {}
~RendererDetails() {}
void Request() {
for (std::set<content::WebContents*>::iterator iter = web_contents_.begin();
iter != web_contents_.end(); ++iter)
(*iter)->GetRenderViewHost()->Send(new ChromeViewMsg_GetV8HeapStats);
iter != web_contents_.end(); ++iter) {
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) {
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() {
web_contents_.clear();
resource_usage_reporters_.clear();
weak_factory_.InvalidateWeakPtrs();
}
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.
if (!web_contents_.empty())
web_contents_.erase(web_contents_.begin());
......@@ -156,23 +177,19 @@ class RendererDetails : public content::NotificationObserver {
}
private:
// NotificationObserver:
void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) override {
const base::ProcessId* pid =
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());
void OnRefreshDone(content::WebContents* content, const base::ProcessId pid) {
auto iter = resource_usage_reporters_.find(content);
DCHECK(iter != resource_usage_reporters_.end());
linked_ptr<ProcessResourceUsage> usage = iter->second;
callback_.Run(pid, usage->GetV8MemoryAllocated(), usage->GetV8MemoryUsed());
}
V8DataCallback callback_;
content::NotificationRegistrar registrar_;
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);
};
......
......@@ -9,6 +9,7 @@
#include <string>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "base/values.h"
#include "chrome/browser/memory_details.h"
......@@ -78,7 +79,7 @@ class MemoryInternalsProxy
MemoryInternalsHandler* handler_;
base::DictionaryValue* information_;
RendererDetails* renderer_details_;
scoped_ptr<RendererDetails> renderer_details_;
DISALLOW_COPY_AND_ASSIGN(MemoryInternalsProxy);
};
......
......@@ -246,6 +246,7 @@
'variables': { 'enable_wexit_time_destructors': 1, },
'dependencies': [
'common',
'common_mojo_bindings',
'common_net',
'chrome_resources.gyp:chrome_resources',
'chrome_resources.gyp:chrome_strings',
......
......@@ -238,9 +238,6 @@ IPC_MESSAGE_CONTROL2(ChromeViewMsg_SetFieldTrialGroup,
std::string /* field trial name */,
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,
int /* page_seq_no */)
......@@ -485,11 +482,6 @@ IPC_SYNC_MESSAGE_ROUTED2_1(ChromeViewHostMsg_GetSearchProviderInstallState,
GURL /* inquiry url */,
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.
IPC_MESSAGE_ROUTED2(ChromeViewHostMsg_BlockedOutdatedPlugin,
int /* placeholder ID */,
......
......@@ -6,8 +6,6 @@ struct ResourceUsageData {
bool reports_v8_stats = false;
uint64 v8_bytes_allocated = 0;
uint64 v8_bytes_used = 0;
// TODO(amistry): Consider using this for the renderer process.
};
interface ResourceUsageReporter {
......
......@@ -32,6 +32,7 @@ static_library("renderer") {
deps = [
"//base/allocator",
"//chrome/common",
"//chrome/common:mojo_bindings",
"//chrome/common/net",
"//chrome:resources",
"//chrome:strings",
......
......@@ -25,17 +25,20 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/net_resource_provider.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/resource_usage_reporter.mojom.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/variations/variations_util.h"
#include "chrome/renderer/content_settings_observer.h"
#include "chrome/renderer/security_filter_peer.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_view.h"
#include "content/public/renderer/render_view_visitor.h"
#include "crypto/nss_util.h"
#include "net/base/net_errors.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/WebDocument.h"
#include "third_party/WebKit/public/web/WebFrame.h"
......@@ -110,98 +113,87 @@ class RendererResourceDelegate : public content::ResourceDispatcherDelegate {
static const int kWaitForWorkersStatsTimeoutMS = 20;
class HeapStatisticsCollector {
class ResourceUsageReporterImpl : public ResourceUsageReporter {
public:
HeapStatisticsCollector() : round_id_(0) {}
void InitiateCollection();
static HeapStatisticsCollector* Instance();
explicit ResourceUsageReporterImpl(
mojo::InterfaceRequest<ResourceUsageReporter> req)
: binding_(this, req.Pass()), weak_factory_(this) {}
~ResourceUsageReporterImpl() override {}
private:
void CollectOnWorkerThread(scoped_refptr<base::TaskRunner> master,
int round_id);
void ReceiveStats(int round_id, size_t total_size, size_t used_size);
void SendStatsToBrowser(int round_id);
size_t total_bytes_;
size_t used_bytes_;
int workers_to_go_;
int round_id_;
};
static void CollectOnWorkerThread(
const scoped_refptr<base::TaskRunner>& master,
base::WeakPtr<ResourceUsageReporterImpl> impl) {
size_t total_bytes = 0;
size_t used_bytes = 0;
v8::Isolate* isolate = v8::Isolate::GetCurrent();
if (isolate) {
v8::HeapStatistics heap_stats;
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() {
CR_DEFINE_STATIC_LOCAL(HeapStatisticsCollector, instance, ());
return &instance;
}
void ReceiveStats(size_t total_bytes, size_t used_bytes) {
usage_data_->v8_bytes_allocated += total_bytes;
usage_data_->v8_bytes_used += used_bytes;
workers_to_go_--;
if (!workers_to_go_)
SendResults();
}
void HeapStatisticsCollector::InitiateCollection() {
v8::HeapStatistics heap_stats;
v8::Isolate::GetCurrent()->GetHeapStatistics(&heap_stats);
total_bytes_ = heap_stats.total_heap_size();
used_bytes_ = heap_stats.used_heap_size();
base::Closure collect = base::Bind(
&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 SendResults() {
if (!callback_.is_null())
callback_.Run(usage_data_.Pass());
callback_.reset();
weak_factory_.InvalidateWeakPtrs();
workers_to_go_ = 0;
}
}
void HeapStatisticsCollector::CollectOnWorkerThread(
scoped_refptr<base::TaskRunner> master,
int round_id) {
void GetUsageData(
const mojo::Callback<void(ResourceUsageDataPtr)>& callback) override {
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;
isolate->GetHeapStatistics(&heap_stats);
total_bytes = heap_stats.total_heap_size();
used_bytes = heap_stats.used_heap_size();
v8::Isolate::GetCurrent()->GetHeapStatistics(&heap_stats);
usage_data_->v8_bytes_allocated = heap_stats.total_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,
size_t total_bytes,
size_t used_bytes) {
if (round_id != round_id_)
return;
total_bytes_ += total_bytes;
used_bytes_ += used_bytes;
if (!--workers_to_go_)
SendStatsToBrowser(round_id);
}
ResourceUsageDataPtr usage_data_;
mojo::Callback<void(ResourceUsageDataPtr)> callback_;
int workers_to_go_;
mojo::StrongBinding<ResourceUsageReporter> binding_;
base::WeakPtrFactory<ResourceUsageReporterImpl> weak_factory_;
};
void HeapStatisticsCollector::SendStatsToBrowser(int round_id) {
if (round_id != round_id_)
return;
// 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_;
void CreateResourceUsageReporter(
mojo::InterfaceRequest<ResourceUsageReporter> request) {
new ResourceUsageReporterImpl(request.Pass());
}
} // namespace
......@@ -231,6 +223,12 @@ ChromeRenderProcessObserver::ChromeRenderProcessObserver()
resource_delegate_.reset(new RendererResourceDelegate());
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.
net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
......@@ -261,7 +259,6 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived(
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetIsIncognitoProcess,
OnSetIsIncognitoProcess)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup)
IPC_MESSAGE_HANDLER(ChromeViewMsg_GetV8HeapStats, OnGetV8HeapStats)
IPC_MESSAGE_HANDLER(ChromeViewMsg_GetCacheResourceStats,
OnGetCacheResourceStats)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules,
......@@ -321,10 +318,6 @@ void ChromeRenderProcessObserver::OnSetFieldTrialGroup(
chrome_variations::SetChildProcessLoggingVariationList();
}
void ChromeRenderProcessObserver::OnGetV8HeapStats() {
HeapStatisticsCollector::Instance()->InitiateCollection();
}
const RendererContentSettingRules*
ChromeRenderProcessObserver::content_setting_rules() const {
return &content_setting_rules_;
......
......@@ -54,7 +54,6 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver,
void OnGetCacheResourceStats();
void OnSetFieldTrialGroup(const std::string& fiel_trial_name,
const std::string& group_name);
void OnGetV8HeapStats();
static bool is_incognito_process_;
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