Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Unified Diff: chrome/browser/memory_details.cc

Issue 1406133002: Several Site Details / Memory metrics fixes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@no_isolate_apps4
Patch Set: thestig's fixes. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/site_details.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/memory_details.cc
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc
index fbf669df4f29a3cfcb225535bc60878d2b9483b5..b210f92597e57fe45fabff785ec7533ec143cbfb 100644
--- a/chrome/browser/memory_details.cc
+++ b/chrome/browser/memory_details.cc
@@ -216,83 +216,102 @@ void MemoryDetails::CollectChildInfoOnUIThread() {
#endif
ProcessData* const chrome_browser = ChromeBrowser();
- // Get more information about the process.
- for (size_t index = 0; index < chrome_browser->processes.size();
- index++) {
- // Check if it's a renderer, if so get the list of page titles in it and
- // check if it's a diagnostics-related process. We skip about:memory pages.
- // Iterate the RenderProcessHosts to find the tab contents.
- ProcessMemoryInformation& process =
- chrome_browser->processes[index];
-
- scoped_ptr<content::RenderWidgetHostIterator> widgets(
- RenderWidgetHost::GetRenderWidgetHosts());
- while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
- content::RenderProcessHost* render_process_host =
- widget->GetProcess();
- DCHECK(render_process_host);
- // Ignore processes that don't have a connection, such as crashed tabs.
- if (!render_process_host->HasConnection() ||
- process.pid != base::GetProcId(render_process_host->GetHandle())) {
- continue;
- }
- // The RenderProcessHost may host multiple WebContentses. Any
- // of them which contain diagnostics information make the whole
- // process be considered a diagnostics process.
- RenderViewHost* host = RenderViewHost::From(widget);
- if (!host)
- continue;
+ // First pass, collate the widgets by process ID.
+ std::map<base::ProcessId, std::vector<RenderWidgetHost*>> widgets_by_pid;
+ scoped_ptr<content::RenderWidgetHostIterator> widget_it(
+ RenderWidgetHost::GetRenderWidgetHosts());
+ while (content::RenderWidgetHost* widget = widget_it->GetNextHost()) {
+ // Ignore processes that don't have a connection, such as crashed tabs.
+ if (!widget->GetProcess()->HasConnection())
+ continue;
+ base::ProcessId pid = base::GetProcId(widget->GetProcess()->GetHandle());
+ widgets_by_pid[pid].push_back(widget);
+ }
+ // Get more information about the process.
+ for (ProcessMemoryInformation& process : chrome_browser->processes) {
+ // If there's at least one widget in the process, it is some kind of
+ // renderer process belonging to this browser. All these widgets will share
+ // a RenderProcessHost.
+ content::RenderProcessHost* render_process_host = nullptr;
+ if (!widgets_by_pid[process.pid].empty()) {
+ // Mark it as a normal renderer process, if we don't refine it to some
+ // other |renderer_type| later.
process.process_type = content::PROCESS_TYPE_RENDERER;
- bool is_extension = false;
+ process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL;
+ render_process_host = widgets_by_pid[process.pid].front()->GetProcess();
+ }
+
#if defined(ENABLE_EXTENSIONS)
+ // Determine if this is an extension process.
+ bool process_is_for_extensions = false;
+ if (render_process_host) {
content::BrowserContext* context =
render_process_host->GetBrowserContext();
extensions::ExtensionRegistry* extension_registry =
extensions::ExtensionRegistry::Get(context);
- extensions::ProcessMap* extension_process_map =
+ extensions::ProcessMap* process_map =
extensions::ProcessMap::Get(context);
- is_extension = extension_process_map->Contains(
- host->GetProcess()->GetID());
-#endif
+ int rph_id = render_process_host->GetID();
+ process_is_for_extensions = process_map->Contains(rph_id);
- WebContents* contents = WebContents::FromRenderViewHost(host);
- GURL url;
- if (contents) {
- url = contents->GetURL();
- SiteData* site_data =
- &chrome_browser->site_data[contents->GetBrowserContext()];
- SiteDetails::CollectSiteInfo(contents, site_data);
+ // For our purposes, don't count processes containing only hosted apps
+ // as extension processes. See also: crbug.com/102533.
+ for (auto& extension_id : process_map->GetExtensionsInProcess(rph_id)) {
+ const Extension* extension =
+ extension_registry->enabled_extensions().GetByID(extension_id);
+ if (extension && !extension->is_hosted_app()) {
+ process.renderer_type = ProcessMemoryInformation::RENDERER_EXTENSION;
+ break;
+ }
}
-#if defined(ENABLE_EXTENSIONS)
- extensions::ViewType type = extensions::GetViewType(contents);
+ }
#endif
- if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) {
+
+ // Use the list of widgets to iterate over the WebContents instances whose
+ // main RenderFrameHosts are in |process|. Refine our determination of the
+ // |process.renderer_type|, and record the page titles.
+ for (content::RenderWidgetHost* widget : widgets_by_pid[process.pid]) {
+ DCHECK_EQ(render_process_host, widget->GetProcess());
+
+ RenderViewHost* rvh = RenderViewHost::From(widget);
+ if (!rvh)
+ continue;
+
+ WebContents* contents = WebContents::FromRenderViewHost(rvh);
+
+ // Assume that an RVH without a web contents is an interstitial.
+ if (!contents) {
+ process.renderer_type = ProcessMemoryInformation::RENDERER_INTERSTITIAL;
+ continue;
+ }
+
+ // If this is a RVH for a subframe; skip it to avoid double-counting the
+ // WebContents.
+ if (rvh != contents->GetRenderViewHost())
+ continue;
+
+ // The rest of this block will happen only once per WebContents.
+ GURL page_url = contents->GetLastCommittedURL();
+ SiteData& site_data =
+ chrome_browser->site_data[contents->GetBrowserContext()];
+ SiteDetails::CollectSiteInfo(contents, &site_data);
+
+ bool is_webui =
+ rvh->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI;
+
+ if (is_webui) {
process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME;
- } else if (is_extension) {
-#if defined(ENABLE_EXTENSIONS)
- // For our purposes, don't count processes containing only hosted apps
- // as extension processes. See also: crbug.com/102533.
- std::set<std::string> extension_ids =
- extension_process_map->GetExtensionsInProcess(
- host->GetProcess()->GetID());
- for (std::set<std::string>::iterator iter = extension_ids.begin();
- iter != extension_ids.end(); ++iter) {
- const Extension* extension =
- extension_registry->enabled_extensions().GetByID(*iter);
- if (extension && !extension->is_hosted_app()) {
- process.renderer_type =
- ProcessMemoryInformation::RENDERER_EXTENSION;
- break;
- }
- }
-#endif
}
+
#if defined(ENABLE_EXTENSIONS)
- if (is_extension) {
+ if (!is_webui && process_is_for_extensions) {
const Extension* extension =
- extension_registry->enabled_extensions().GetByID(url.host());
+ extensions::ExtensionRegistry::Get(
+ render_process_host->GetBrowserContext())
+ ->enabled_extensions()
+ .GetByID(page_url.host());
if (extension) {
base::string16 title = base::UTF8ToUTF16(extension->name());
process.titles.push_back(title);
@@ -301,33 +320,24 @@ void MemoryDetails::CollectChildInfoOnUIThread() {
continue;
}
}
-#endif
-
- if (!contents) {
- process.renderer_type =
- ProcessMemoryInformation::RENDERER_INTERSTITIAL;
- continue;
- }
-#if defined(ENABLE_EXTENSIONS)
+ extensions::ViewType type = extensions::GetViewType(contents);
if (type == extensions::VIEW_TYPE_BACKGROUND_CONTENTS) {
- process.titles.push_back(base::UTF8ToUTF16(url.spec()));
+ process.titles.push_back(base::UTF8ToUTF16(page_url.spec()));
process.renderer_type =
ProcessMemoryInformation::RENDERER_BACKGROUND_APP;
continue;
}
#endif
- // Since we have a WebContents and and the renderer type hasn't been
- // set yet, it must be a normal tabbed renderer.
- if (process.renderer_type == ProcessMemoryInformation::RENDERER_UNKNOWN)
- process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL;
-
base::string16 title = contents->GetTitle();
if (!title.length())
title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
process.titles.push_back(title);
+ // The presence of a single WebContents with a diagnostics page will make
+ // the whole process be considered a diagnostics process.
+ //
// We need to check the pending entry as well as the virtual_url to
// see if it's a chrome://memory URL (we don't want to count these in
// the total memory usage of the browser).
@@ -363,15 +373,12 @@ void MemoryDetails::CollectChildInfoOnUIThread() {
}
// Get rid of other Chrome processes that are from a different profile.
- for (size_t index = 0; index < chrome_browser->processes.size();
- index++) {
- if (chrome_browser->processes[index].process_type ==
- content::PROCESS_TYPE_UNKNOWN) {
- chrome_browser->processes.erase(
- chrome_browser->processes.begin() + index);
- index--;
- }
- }
+ auto is_unknown = [](ProcessMemoryInformation& process) {
+ return process.process_type == content::PROCESS_TYPE_UNKNOWN;
+ };
+ auto& vector = chrome_browser->processes;
+ vector.erase(std::remove_if(vector.begin(), vector.end(), is_unknown),
+ vector.end());
OnDetailsAvailable();
}
« no previous file with comments | « no previous file | chrome/browser/site_details.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698