summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorperia@chromium.org <peria@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-01 07:08:21 +0000
committerperia@chromium.org <peria@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-01 07:08:21 +0000
commit0d9b30458af1e2c7c4282f876e6556af3ede4c99 (patch)
tree29601215a86f6d1973ef7919dafe370d4497e9bd
parent7361110ac1e6673f9a92c73bae1c0505fcf74ac1 (diff)
downloadchromium_src-0d9b30458af1e2c7c4282f876e6556af3ede4c99.zip
chromium_src-0d9b30458af1e2c7c4282f876e6556af3ede4c99.tar.gz
chromium_src-0d9b30458af1e2c7c4282f876e6556af3ede4c99.tar.bz2
Add information of V8 heap memories, in chrome://memory-internals
BUG=168642 TEST=Manual Review URL: https://chromiumcodereview.appspot.com/17449003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209373 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/resources/memory_internals/memory_internals.js8
-rw-r--r--chrome/browser/resources/memory_internals/snapshot_view.css17
-rw-r--r--chrome/browser/resources/memory_internals/snapshot_view.html12
-rw-r--r--chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc171
-rw-r--r--chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h12
5 files changed, 173 insertions, 47 deletions
diff --git a/chrome/browser/resources/memory_internals/memory_internals.js b/chrome/browser/resources/memory_internals/memory_internals.js
index 233feb8..c448a6b 100644
--- a/chrome/browser/resources/memory_internals/memory_internals.js
+++ b/chrome/browser/resources/memory_internals/memory_internals.js
@@ -64,9 +64,15 @@ var MainView = (function() {
case 'process-info':
value = process['type'] + '<br>' + process['titles'].join('<br>');
break;
- case 'process-memory':
+ case 'process-memory-private':
value = process['memory_private'];
break;
+ case 'process-memory-v8':
+ if (process['v8_alloc'] !== undefined) {
+ value = 'Used : ' + process['v8_used'] + '<br>' +
+ 'Allocated : ' + process['v8_alloc'];
+ }
+ break;
}
var col = row.insertCell(-1);
col.innerHTML = value;
diff --git a/chrome/browser/resources/memory_internals/snapshot_view.css b/chrome/browser/resources/memory_internals/snapshot_view.css
index 3b24f73..4e57b21 100644
--- a/chrome/browser/resources/memory_internals/snapshot_view.css
+++ b/chrome/browser/resources/memory_internals/snapshot_view.css
@@ -17,11 +17,14 @@
}
#snapshot-view .header th {
- border-bottom: 1px solid rgb(181, 198, 222);
padding: 0.35em 0.5em 0;
vertical-align: bottom;
}
+#snapshot-view .bottom th {
+ border-bottom: 1px solid rgb(181, 198, 222);
+}
+
#snapshot-view .process-id {
text-align: right;
width: 4em;
@@ -33,8 +36,18 @@
#snapshot-view .process-memory {
border-left: 1px solid rgb(181, 198, 222);
+ width: 16em;
+}
+
+#snapshot-view .process-memory-private {
+ border-left: 1px solid rgb(181, 198, 222);
+ text-align: right;
+ width: 6em;
+}
+
+#snapshot-view .process-memory-v8 {
text-align: right;
- width: 7em;
+ width: 10em;
}
#snapshot-view #process-template {
diff --git a/chrome/browser/resources/memory_internals/snapshot_view.html b/chrome/browser/resources/memory_internals/snapshot_view.html
index 0a5ecb6..43d041d 100644
--- a/chrome/browser/resources/memory_internals/snapshot_view.html
+++ b/chrome/browser/resources/memory_internals/snapshot_view.html
@@ -7,11 +7,15 @@
<table id="snapshot-view">
<tr class="header">
- <th class="process-id">PID
- <th class="process-info">Name
- <th class="process-memory">Private Memory [KB]
+ <th rowspan="2" class="process-id">PID
+ <th rowspan="2" class="process-info">Name
+ <th colspan="2" class="process-memory">Memory [KB]
+ <tr class="header bottom">
+ <th class="process-memory-private">Private
+ <th class="process-memory-v8">V8
<tr id="process-template">
<td class="process-id">
<td class="process-info">
- <td class="process-memory">
+ <td class="process-memory-private">
+ <td class="process-memory-v8">
</table>
diff --git a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
index d55e6a8..accb3a5 100644
--- a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
+++ b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.cc
@@ -4,42 +4,38 @@
#include "chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h"
+#include <set>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/strings/string16.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
#include "base/sys_info.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/defaults.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/memory_details.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
#include "chrome/browser/ui/webui/memory_internals/memory_internals_handler.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_set.h"
-#include "content/public/browser/url_data_source.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/render_messages.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_view_host.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
-#include "grit/chromium_strings.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/webui/jstemplate_builder.h"
-#include "ui/webui/web_ui_util.h"
using content::BrowserThread;
namespace {
-class BrowserProcessDetails : public MemoryDetails {
+class ProcessDetails : public MemoryDetails {
public:
typedef base::Callback<void(const ProcessData&)> DataCallback;
- explicit BrowserProcessDetails(const DataCallback& callback)
+ explicit ProcessDetails(const DataCallback& callback)
: callback_(callback) {}
+ // MemoryDetails:
virtual void OnDetailsAvailable() OVERRIDE {
const std::vector<ProcessData>& browser_processes = processes();
// [0] means Chrome.
@@ -47,16 +43,75 @@ class BrowserProcessDetails : public MemoryDetails {
}
private:
- virtual ~BrowserProcessDetails() {}
+ virtual ~ProcessDetails() {}
DataCallback callback_;
- DISALLOW_COPY_AND_ASSIGN(BrowserProcessDetails);
+ DISALLOW_COPY_AND_ASSIGN(ProcessDetails);
};
} // namespace
-MemoryInternalsProxy::MemoryInternalsProxy() {}
+class RendererDetails : public content::NotificationObserver {
+ 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());
+ }
+ virtual ~RendererDetails() {}
+
+ void Request() {
+ for (std::set<content::WebContents*>::iterator iter = web_contents_.begin();
+ iter != web_contents_.end(); ++iter)
+ (*iter)->GetRenderViewHost()->Send(new ChromeViewMsg_GetV8HeapStats);
+ }
+ void AddWebContents(content::WebContents* content) {
+ web_contents_.insert(content);
+ }
+ void Clear() {
+ web_contents_.clear();
+ }
+ void RemoveWebContents() {
+ // We don't have to detect which content is the caller of this method.
+ if (!web_contents_.empty())
+ web_contents_.erase(web_contents_.begin());
+ }
+ int IsClean() {
+ return web_contents_.empty();
+ }
+
+ private:
+ // NotificationObserver:
+ virtual 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());
+ }
+
+ V8DataCallback callback_;
+ content::NotificationRegistrar registrar_;
+ std::set<content::WebContents*> web_contents_; // This class does not own
+
+ DISALLOW_COPY_AND_ASSIGN(RendererDetails);
+};
+
+MemoryInternalsProxy::MemoryInternalsProxy()
+ : information_(new base::DictionaryValue()),
+ renderer_details_(new RendererDetails(
+ base::Bind(&MemoryInternalsProxy::OnV8MemoryUpdate, this))) {
+}
void MemoryInternalsProxy::Attach(MemoryInternalsHandler* handler) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
@@ -71,7 +126,7 @@ void MemoryInternalsProxy::Detach() {
void MemoryInternalsProxy::GetInfo(const base::ListValue* list) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- scoped_refptr<BrowserProcessDetails> browsers(new BrowserProcessDetails(
+ scoped_refptr<ProcessDetails> browsers(new ProcessDetails(
base::Bind(&MemoryInternalsProxy::OnDetailsAvailable, this)));
browsers->StartFetch(MemoryDetails::SKIP_USER_METRICS);
}
@@ -86,42 +141,80 @@ void MemoryInternalsProxy::UpdateUIOnUIThread(const string16& update) {
handler_->OnUpdate(update);
}
+void MemoryInternalsProxy::OnV8MemoryUpdate(const base::ProcessId pid,
+ const size_t v8_allocated,
+ const size_t v8_used) {
+ base::ListValue* processes;
+ if (!information_->GetList("processes", &processes))
+ return;
+
+ const size_t size = processes->GetSize();
+ for (size_t i = 0; i < size; ++i) {
+ base::DictionaryValue* process;
+ processes->GetDictionary(i, &process);
+ int id;
+ if (!process->GetInteger("pid", &id) || id != static_cast<int>(pid))
+ continue;
+ process->SetInteger("v8_alloc", v8_allocated);
+ process->SetInteger("v8_used", v8_used);
+ break;
+ }
+
+ renderer_details_->RemoveWebContents();
+ if (renderer_details_->IsClean())
+ CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", information_);
+}
+
+void MemoryInternalsProxy::RequestV8MemoryUpdate() {
+ renderer_details_->Clear();
+#if !defined(OS_ANDROID)
+ for (TabContentsIterator iter; !iter.done(); iter.Next())
+ renderer_details_->AddWebContents(*iter);
+#endif
+
+ // if no contents are shown, update UI.
+ if (renderer_details_->IsClean())
+ CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", information_);
+
+ renderer_details_->Request();
+}
+
void MemoryInternalsProxy::OnDetailsAvailable(const ProcessData& browser) {
- base::DictionaryValue details;
+ information_->Clear();
// System information, which is independent from processes.
- details.SetInteger("uptime", base::SysInfo::Uptime());
- details.SetString("os", base::SysInfo::OperatingSystemName());
- details.SetString("os_version", base::SysInfo::OperatingSystemVersion());
+ information_->SetInteger("uptime", base::SysInfo::Uptime());
+ information_->SetString("os", base::SysInfo::OperatingSystemName());
+ information_->SetString("os_version",
+ base::SysInfo::OperatingSystemVersion());
base::ListValue* processes = new ListValue();
base::ListValue* extensions = new ListValue();
- details.Set("processes", processes);
- details.Set("extensions", extensions);
+ information_->Set("processes", processes);
+ information_->Set("extensions", extensions);
for (ProcessMemoryInformationList::const_iterator
iter = browser.processes.begin();
iter != browser.processes.end(); ++iter) {
- base::DictionaryValue* info = new DictionaryValue();
+ base::DictionaryValue* process = new DictionaryValue();
+ if (iter->process_type == content::PROCESS_TYPE_RENDERER &&
+ iter->renderer_type == ProcessMemoryInformation::RENDERER_EXTENSION)
+ extensions->Append(process);
+ else
+ processes->Append(process);
// Information from MemoryDetails.
- info->SetInteger("pid", iter->pid);
- info->SetString("type",
+ process->SetInteger("pid", iter->pid);
+ process->SetString("type",
ProcessMemoryInformation::GetFullTypeNameInEnglish(
iter->process_type, iter->renderer_type));
- info->SetInteger("memory_private", iter->working_set.priv);
+ process->SetInteger("memory_private", iter->working_set.priv);
base::ListValue* titles = new ListValue();
- info->Set("titles", titles);
+ process->Set("titles", titles);
for (size_t i = 0; i < iter->titles.size(); ++i)
titles->AppendString(iter->titles[i]);
-
- if (iter->process_type == content::PROCESS_TYPE_RENDERER &&
- iter->renderer_type == ProcessMemoryInformation::RENDERER_EXTENSION)
- extensions->Append(info);
- else
- processes->Append(info);
}
- CallJavaScriptFunctionOnUIThread("g_main_view.onSetSnapshot", &details);
+ RequestV8MemoryUpdate();
}
void MemoryInternalsProxy::CallJavaScriptFunctionOnUIThread(
diff --git a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h
index f3e4b84..5c5ee78 100644
--- a/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h
+++ b/chrome/browser/ui/webui/memory_internals/memory_internals_proxy.h
@@ -9,10 +9,12 @@
#include "base/memory/ref_counted.h"
#include "base/strings/string16.h"
+#include "base/values.h"
#include "chrome/browser/memory_details.h"
#include "content/public/browser/browser_thread.h"
class MemoryInternalsHandler;
+class RendererDetails;
namespace base {
class ListValue;
@@ -21,7 +23,7 @@ class Value;
class MemoryInternalsProxy
: public base::RefCountedThreadSafe<
- MemoryInternalsProxy, content::BrowserThread::DeleteOnUIThread> {
+ MemoryInternalsProxy, content::BrowserThread::DeleteOnUIThread> {
public:
MemoryInternalsProxy();
@@ -43,6 +45,12 @@ class MemoryInternalsProxy
// Sends a message from IO thread to update UI on UI thread.
void UpdateUIOnUIThread(const string16& update);
+ // Measure memory usage of V8.
+ void OnV8MemoryUpdate(const base::ProcessId pid,
+ const size_t v8_allocated,
+ const size_t v8_used);
+ void RequestV8MemoryUpdate();
+
// Convert memory information into DictionaryValue format.
void OnDetailsAvailable(const ProcessData& browser);
@@ -51,6 +59,8 @@ class MemoryInternalsProxy
base::Value* args);
MemoryInternalsHandler* handler_;
+ base::DictionaryValue* information_;
+ RendererDetails* renderer_details_;
DISALLOW_COPY_AND_ASSIGN(MemoryInternalsProxy);
};