summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-11 01:51:32 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-11 01:51:32 +0000
commit38b48a844731cd10d69d8e99d476e3dac9e81980 (patch)
treeb73cc4ca2cae009276db4305eac119d080f0381f
parent5ecc992a4bf8546b21db89901f2d87e8b4ae1a94 (diff)
downloadchromium_src-38b48a844731cd10d69d8e99d476e3dac9e81980.zip
chromium_src-38b48a844731cd10d69d8e99d476e3dac9e81980.tar.gz
chromium_src-38b48a844731cd10d69d8e99d476e3dac9e81980.tar.bz2
Adds a 'V8' column to task manager to track amount of memory in JavaScript heap
BUG=27226 TEST=open task manager, enable column, compare with V8 heap profiler Review URL: http://codereview.chromium.org/377037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31641 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd5
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc22
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h5
-rw-r--r--chrome/browser/task_manager.cc24
-rw-r--r--chrome/browser/task_manager.h13
-rw-r--r--chrome/browser/task_manager_resource_providers.cc24
-rw-r--r--chrome/browser/task_manager_resource_providers.h16
-rw-r--r--chrome/browser/views/task_manager_view.cc11
-rw-r--r--chrome/common/render_messages_internal.h10
-rw-r--r--chrome/renderer/render_thread.cc10
-rw-r--r--chrome/renderer/render_thread.h1
11 files changed, 134 insertions, 7 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 1729d19..dae19c5 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -2508,11 +2508,14 @@ each locale. -->
<message name="IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN" desc="Amount of memory used by SQLite.">
SQLite memory
</message>
+ <message name="IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN" desc="Task manager JavaScript memory allocated column. Shows the amount of memory used by JavaScript within a process">
+ JavaScript memory
+ </message>
<message name="IDS_TASK_MANAGER_MEM_CELL_TEXT" desc="The value displayed in the memory usage cells.">
<ph name="NUM_KILOBYTES">$1<ex>5,000</ex></ph>K
</message>
<message name="IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT" desc="The value displayed in the cache size cells.">
- <ph name="NUM_KILOBYTES">$1<ex>5,000</ex></ph>K (<ph name="NUM_KILOBYTES">$2<ex>5,000</ex></ph>K live)
+ <ph name="NUM_KILOBYTES">$1<ex>5,000</ex></ph>K (<ph name="NUM_KILOBYTES_LIVE">$2<ex>5,000</ex></ph>K live)
</message>
<message name="IDS_TASK_MANAGER_NA_CELL_TEXT" desc="The value displayed for network / webcache usage when the information is not available (Not Applicable).">
N/A
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 41ddd3d..a7d53c0 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -369,6 +369,7 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) {
OnAllocatePDFTransport)
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_ResourceTypeStats, OnResourceTypeStats)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_V8HeapStats, OnV8HeapStats)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ResolveProxy, OnResolveProxy)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetDefaultPrintSettings,
OnGetDefaultPrintSettings)
@@ -827,6 +828,27 @@ void ResourceMessageFilter::OnResourceTypeStatsOnUIThread(
renderer_id, stats);
}
+
+void ResourceMessageFilter::OnV8HeapStats(int v8_memory_allocated,
+ int v8_memory_used) {
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableFunction(&ResourceMessageFilter::OnV8HeapStatsOnUIThread,
+ v8_memory_allocated,
+ v8_memory_used,
+ base::GetProcId(handle())));
+}
+
+// static
+void ResourceMessageFilter::OnV8HeapStatsOnUIThread(
+ int v8_memory_allocated, int v8_memory_used, base::ProcessId renderer_id) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ TaskManager::GetInstance()->model()->NotifyV8HeapStats(
+ renderer_id,
+ static_cast<size_t>(v8_memory_allocated),
+ static_cast<size_t>(v8_memory_used));
+}
+
void ResourceMessageFilter::OnResolveProxy(const GURL& url,
IPC::Message* reply_msg) {
resolve_proxy_msg_helper_.Start(url, reply_msg);
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 84a5a33..250b737 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -244,6 +244,11 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
static void OnResourceTypeStatsOnUIThread(WebKit::WebCache::ResourceTypeStats,
base::ProcessId renderer_id);
+ void OnV8HeapStats(int v8_memory_allocated, int v8_memory_used);
+ static void OnV8HeapStatsOnUIThread(int v8_memory_allocated,
+ int v8_memory_used,
+ base::ProcessId renderer_id);
+
void OnResolveProxy(const GURL& url, IPC::Message* reply_msg);
// ResolveProxyMsgHelper::Delegate implementation:
diff --git a/chrome/browser/task_manager.cc b/chrome/browser/task_manager.cc
index 43e2657..090f626 100644
--- a/chrome/browser/task_manager.cc
+++ b/chrome/browser/task_manager.cc
@@ -196,6 +196,19 @@ std::wstring TaskManagerModel::GetResourceSqliteMemoryUsed(int index) const {
return GetMemCellText(resources_[index]->SqliteMemoryUsedBytes() / 1024);
}
+std::wstring TaskManagerModel::GetResourceV8MemoryAllocatedSize(
+ int index) const {
+ if (!resources_[index]->ReportsV8MemoryStats())
+ return l10n_util::GetString(IDS_TASK_MANAGER_NA_CELL_TEXT);
+ return l10n_util::GetStringF(IDS_TASK_MANAGER_CACHE_SIZE_CELL_TEXT,
+ FormatBytes(resources_[index]->GetV8MemoryAllocated(),
+ DATA_UNITS_KILOBYTE,
+ false),
+ FormatBytes(resources_[index]->GetV8MemoryUsed(),
+ DATA_UNITS_KILOBYTE,
+ false));
+}
+
bool TaskManagerModel::IsResourceFirstInGroup(int index) const {
DCHECK(index < ResourceCount());
TaskManager::Resource* resource = resources_[index];
@@ -621,6 +634,17 @@ void TaskManagerModel::NotifyResourceTypeStats(
}
}
+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::Refresh() {
DCHECK_NE(IDLE, update_state_);
diff --git a/chrome/browser/task_manager.h b/chrome/browser/task_manager.h
index 9fa19f6..2c76a7d 100644
--- a/chrome/browser/task_manager.h
+++ b/chrome/browser/task_manager.h
@@ -59,6 +59,10 @@ class TaskManager {
// if not applicable.
virtual const Extension* GetExtension() const { return NULL; }
+ virtual bool ReportsV8MemoryStats() const { return false; }
+ virtual size_t GetV8MemoryAllocated() const { return 0; }
+ virtual size_t GetV8MemoryUsed() const { return 0; }
+
// A helper function for ActivateFocusedTab. Returns NULL by default
// because not all resources have an associated tab.
virtual TabContents* GetTabContents() const { return NULL; }
@@ -80,6 +84,8 @@ class TaskManager {
virtual void NotifyResourceTypeStats(
const WebKit::WebCache::ResourceTypeStats& stats) {}
+ virtual void NotifyV8HeapStats(size_t v8_memory_allocated,
+ size_t v8_memory_used) {}
};
// ResourceProviders are responsible for adding/removing resources to the task
@@ -202,6 +208,7 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver,
std::wstring GetResourceWebCoreCSSCacheSize(int index) const;
std::wstring GetResourceSqliteMemoryUsed(int index) const;
std::wstring GetResourceGoatsTeleported(int index) const;
+ std::wstring GetResourceV8MemoryAllocatedSize(int index) const;
// Returns true if the resource is first in its group (resources
// rendered by the same process are groupped together).
@@ -246,9 +253,13 @@ class TaskManagerModel : public URLRequestJobTracker::JobObserver,
void Clear(); // Removes all items.
void NotifyResourceTypeStats(
- base::ProcessId renderer_handle,
+ base::ProcessId renderer_id,
const WebKit::WebCache::ResourceTypeStats& stats);
+ void NotifyV8HeapStats(base::ProcessId renderer_id,
+ size_t v8_memory_allocated,
+ size_t v8_memory_used);
+
private:
friend class base::RefCountedThreadSafe<TaskManagerModel>;
FRIEND_TEST(TaskManagerTest, RefreshCalled);
diff --git a/chrome/browser/task_manager_resource_providers.cc b/chrome/browser/task_manager_resource_providers.cc
index 5aba2db..20100c0 100644
--- a/chrome/browser/task_manager_resource_providers.cc
+++ b/chrome/browser/task_manager_resource_providers.cc
@@ -47,7 +47,10 @@
TaskManagerTabContentsResource::TaskManagerTabContentsResource(
TabContents* tab_contents)
: tab_contents_(tab_contents),
- 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 as when the TabContents is closed the process
// becomes NULL and the TaskManager still needs it.
process_ = tab_contents_->process()->process().handle();
@@ -91,6 +94,10 @@ void TaskManagerTabContentsResource::Refresh() {
tab_contents_->render_view_host()->Send(new ViewMsg_GetCacheResourceStats);
pending_stats_update_ = true;
}
+ if (!pending_v8_memory_allocated_update_) {
+ tab_contents_->render_view_host()->Send(new ViewMsg_GetV8HeapStats);
+ pending_v8_memory_allocated_update_ = true;
+ }
}
WebKit::WebCache::ResourceTypeStats
@@ -98,12 +105,27 @@ WebKit::WebCache::ResourceTypeStats
return stats_;
}
+size_t TaskManagerTabContentsResource::GetV8MemoryAllocated() const {
+ return v8_memory_allocated_;
+}
+
+size_t TaskManagerTabContentsResource::GetV8MemoryUsed() const {
+ return v8_memory_used_;
+}
+
void TaskManagerTabContentsResource::NotifyResourceTypeStats(
const WebKit::WebCache::ResourceTypeStats& stats) {
stats_ = stats;
pending_stats_update_ = false;
}
+void TaskManagerTabContentsResource::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;
+}
+
SkBitmap TaskManagerTabContentsResource::GetIcon() const {
return tab_contents_->GetFavIcon();
}
diff --git a/chrome/browser/task_manager_resource_providers.h b/chrome/browser/task_manager_resource_providers.h
index ae3bf100..b374a65 100644
--- a/chrome/browser/task_manager_resource_providers.h
+++ b/chrome/browser/task_manager_resource_providers.h
@@ -35,6 +35,10 @@ class TaskManagerTabContentsResource : public TaskManager::Resource {
virtual bool ReportsCacheStats() const { return true; }
virtual WebKit::WebCache::ResourceTypeStats GetWebCoreCacheStats() const;
+ virtual bool ReportsV8MemoryStats() const { return true; }
+ virtual size_t GetV8MemoryAllocated() const;
+ virtual size_t GetV8MemoryUsed() const;
+
// TabContents always provide the network usage.
bool SupportNetworkUsage() const { return true; }
void SetSupportNetworkUsage() { }
@@ -44,18 +48,24 @@ class TaskManagerTabContentsResource : public TaskManager::Resource {
virtual void NotifyResourceTypeStats(
const WebKit::WebCache::ResourceTypeStats& stats);
+ virtual void NotifyV8HeapStats(size_t v8_memory_allocated,
+ size_t v8_memory_used);
+
private:
TabContents* tab_contents_;
base::ProcessHandle process_;
int pid_;
// The stats_ field holds information about resource usage in the renderer
- // process and so it is updated asynchronously. A query to any of the
- // GetWebCore*CacheSize() functions will send an IPC to the renderer asking
- // for an update unless a query is already outstanding.
+ // process and so it is updated asynchronously by the Refresh() call.
WebKit::WebCache::ResourceTypeStats stats_;
// 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_;
+
DISALLOW_COPY_AND_ASSIGN(TaskManagerTabContentsResource);
};
diff --git a/chrome/browser/views/task_manager_view.cc b/chrome/browser/views/task_manager_view.cc
index 468562e..bcfb422 100644
--- a/chrome/browser/views/task_manager_view.cc
+++ b/chrome/browser/views/task_manager_view.cc
@@ -133,6 +133,11 @@ std::wstring TaskManagerTableModel::GetText(int row, int col_id) {
return std::wstring();
return model_->GetResourceSqliteMemoryUsed(row);
+ case IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN:
+ if (!model_->IsResourceFirstInGroup(row))
+ return std::wstring();
+ return model_->GetResourceV8MemoryAllocatedSize(row);
+
default:
return model_->GetResourceStatsValue(row, col_id);
}
@@ -330,6 +335,10 @@ void TaskManagerView::Init() {
columns_.push_back(TableColumn(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN,
TableColumn::RIGHT, -1, 0));
columns_.back().sortable = true;
+ columns_.push_back(
+ TableColumn(IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN,
+ TableColumn::RIGHT, -1, 0));
+ columns_.back().sortable = true;
tab_table_ = new views::GroupTableView(table_model_.get(), columns_,
views::ICON_AND_TEXT, false, true,
@@ -347,6 +356,8 @@ void TaskManagerView::Init() {
false);
tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_SQLITE_MEMORY_USED_COLUMN,
false);
+ tab_table_->SetColumnVisibility(
+ IDS_TASK_MANAGER_JAVASCRIPT_MEMORY_ALLOCATED_COLUMN, false);
tab_table_->SetColumnVisibility(IDS_TASK_MANAGER_GOATS_TELEPORTED_COLUMN,
false);
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 373a914..2ad32ab 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+ // Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -550,6 +550,9 @@ IPC_BEGIN_MESSAGES(View)
IPC_MESSAGE_CONTROL0(ViewMsg_GetRendererTcmalloc)
#endif
+ // Asks the renderer to send back V8 heap stats.
+ IPC_MESSAGE_CONTROL0(ViewMsg_GetV8HeapStats)
+
// Notifies the renderer about ui theme changes
IPC_MESSAGE_ROUTED0(ViewMsg_ThemeChanged)
@@ -1449,6 +1452,11 @@ IPC_BEGIN_MESSAGES(ViewHost)
std::string /* tcmalloc debug output */)
#endif
+ // Sends back stats about the V8 heap.
+ IPC_MESSAGE_CONTROL2(ViewHostMsg_V8HeapStats,
+ int /* size of heap (allocated from the OS) */,
+ int /* bytes in use */)
+
// Request for a DNS prefetch of the names in the array.
// NameList is typedef'ed std::vector<std::string>
IPC_MESSAGE_CONTROL1(ViewHostMsg_DnsPrefetch,
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 8f3bac5..323d0f0 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -4,6 +4,8 @@
#include "chrome/renderer/render_thread.h"
+#include <v8.h>
+
#include <algorithm>
#include <map>
#include <vector>
@@ -310,6 +312,7 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewMsg_GetRendererTcmalloc,
OnGetRendererTcmalloc)
#endif
+ IPC_MESSAGE_HANDLER(ViewMsg_GetV8HeapStats, OnGetV8HeapStats)
IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
OnGetCacheResourceStats)
IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_UpdatedScripts,
@@ -416,6 +419,13 @@ void RenderThread::OnGetRendererTcmalloc() {
}
#endif
+void RenderThread::OnGetV8HeapStats() {
+ v8::HeapStatistics heap_stats;
+ v8::V8::GetHeapStatistics(&heap_stats);
+ Send(new ViewHostMsg_V8HeapStats(heap_stats.total_heap_size(),
+ heap_stats.used_heap_size()));
+}
+
void RenderThread::InformHostOfCacheStats() {
EnsureWebKitInitialized();
WebCache::UsageStats stats;
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index dece3ee..d7f15a1 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -192,6 +192,7 @@ class RenderThread : public RenderThreadBase,
// Send tcmalloc info to browser.
void OnGetRendererTcmalloc();
+ void OnGetV8HeapStats();
void OnExtensionMessageInvoke(const std::string& function_name,
const ListValue& args);