Index: chrome/browser/memory_details.cc |
diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc |
index d9e95823f99a9a595afd322916c66e4178ae01c7..b5de7283b6878c2be489480f5d61163cc9ffc624 100644 |
--- a/chrome/browser/memory_details.cc |
+++ b/chrome/browser/memory_details.cc |
@@ -39,8 +39,10 @@ using base::StringPrintf; |
using content::BrowserChildProcessHostIterator; |
using content::BrowserThread; |
using content::NavigationEntry; |
+using content::RenderProcessHost; |
using content::RenderViewHost; |
using content::RenderWidgetHost; |
+using content::SiteInstance; |
using content::WebContents; |
using extensions::Extension; |
@@ -93,6 +95,10 @@ bool ProcessMemoryInformation::operator<( |
return working_set.priv < rhs.working_set.priv; |
} |
+SiteData::SiteData() {} |
+ |
+SiteData::~SiteData() {} |
+ |
ProcessData::ProcessData() {} |
ProcessData::ProcessData(const ProcessData& rhs) |
@@ -250,8 +256,10 @@ void MemoryDetails::CollectChildInfoOnUIThread() { |
RenderViewHost::From(const_cast<RenderWidgetHost*>(widget)); |
WebContents* contents = WebContents::FromRenderViewHost(host); |
GURL url; |
- if (contents) |
+ if (contents) { |
url = contents->GetURL(); |
+ CollectSiteInfo(contents); |
+ } |
extensions::ViewType type = extensions::GetViewType(contents); |
if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) { |
process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME; |
@@ -367,6 +375,58 @@ void MemoryDetails::CollectChildInfoOnUIThread() { |
OnDetailsAvailable(); |
} |
+void MemoryDetails::CollectSiteInfo(WebContents* contents) { |
darin (slow to review)
2013/06/12 04:40:48
nit: It is perhaps expanding the scope of this cla
Charlie Reis
2013/06/12 18:59:16
It's kind of intermediate data to report process c
|
+ ProcessData* const chrome_browser = ChromeBrowser(); |
+ |
+ // Keep track of data for each BrowserContext separately, since tabs in |
+ // different BrowserContexts can't share processes. |
+ content::BrowserContext* browser_context = contents->GetBrowserContext(); |
+ SiteData* site_data = &chrome_browser->site_data[browser_context]; |
+ |
+ // Find the BrowsingInstance this WebContents belongs to by iterating over |
+ // the "primary" SiteInstances of each BrowsingInstance we've seen so far. |
+ SiteInstance* instance = contents->GetSiteInstance(); |
+ SiteInstance* primary = NULL; |
+ for (size_t i = 0; i < site_data->instances.size(); ++i) { |
+ if (instance->IsRelatedSiteInstance(site_data->instances[i])) { |
+ primary = site_data->instances[i]; |
+ break; |
+ } |
+ } |
+ if (!primary) { |
+ // Remember this as the "primary" SiteInstance of a new BrowsingInstance. |
+ primary = instance; |
+ site_data->instances.push_back(instance); |
+ } |
+ |
+ // Now keep track of how many sites we have in this BrowsingInstance (and |
+ // overall), including sites in iframes. |
+ std::set<GURL> sites_in_tab = contents->GetSitesInTab(); |
+ for (std::set<GURL>::iterator iter = sites_in_tab.begin(); |
+ iter != sites_in_tab.end(); ++iter) { |
+ // Skip about:blank, since we won't usually give it its own process. |
+ // Because about:blank has no host, its site URL will be blank. |
+ if (iter->is_empty()) |
+ continue; |
+ |
+ // Make sure we don't overcount process-per-site sites, like the NTP. |
+ if (RenderProcessHost::ShouldUseProcessPerSite(browser_context, *iter) && |
+ site_data->sites.find(*iter) != site_data->sites.end()) { |
+ continue; |
+ } |
+ |
+ site_data->sites.insert(*iter); |
+ site_data->instance_site_map[primary->GetId()].insert(*iter); |
+ |
+ // Also keep track of how things would look if we only isolated HTTPS sites. |
+ // In this model, all HTTP sites are grouped into one "http://" site. HTTPS |
+ // and other schemes (e.g., chrome:) are still isolated. |
+ GURL https_site = iter->SchemeIs("http") ? GURL("http://") : *iter; |
+ site_data->https_sites.insert(https_site); |
+ site_data->instance_https_site_map[primary->GetId()].insert(https_site); |
+ } |
+} |
+ |
void MemoryDetails::UpdateHistograms() { |
// Reports a set of memory metrics to UMA. |
// Memory is measured in KB. |
@@ -381,6 +441,7 @@ void MemoryDetails::UpdateHistograms() { |
int renderer_count = 0; |
int other_count = 0; |
int worker_count = 0; |
+ int process_limit = RenderProcessHost::GetMaxRendererProcessCount(); |
for (size_t index = 0; index < browser.processes.size(); index++) { |
int sample = static_cast<int>(browser.processes[index].working_set.priv); |
aggregate_memory += sample; |
@@ -467,6 +528,7 @@ void MemoryDetails::UpdateHistograms() { |
UMA_HISTOGRAM_MEMORY_MB("Memory.Graphics", meminfo.gem_size / 1024 / 1024); |
#endif |
+ UMA_HISTOGRAM_COUNTS_100("Memory.ProcessLimit", process_limit); |
UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount", |
static_cast<int>(browser.processes.size())); |
UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count); |
@@ -484,4 +546,74 @@ void MemoryDetails::UpdateHistograms() { |
int total_sample = static_cast<int>(aggregate_memory / 1000); |
UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample); |
+ |
+ // Sum the number of sites and SiteInstances in each BrowserContext. |
+ int num_sites = 0; |
+ int num_https_sites = 0; |
+ int num_browsing_instances = 0; |
+ int num_isolated_site_instances = 0; |
+ int num_isolated_https_site_instances = 0; |
+ for (BrowserContextSiteDataMap::const_iterator i = browser.site_data.begin(); |
+ i != browser.site_data.end(); ++i) { |
+ num_sites += i->second.sites.size(); |
+ num_https_sites += i->second.https_sites.size(); |
+ num_browsing_instances += i->second.instance_site_map.size(); |
+ for (BrowsingInstanceSiteMap::const_iterator iter = |
+ i->second.instance_site_map.begin(); |
+ iter != i->second.instance_site_map.end(); ++iter) { |
+ num_isolated_site_instances += iter->second.size(); |
+ } |
+ for (BrowsingInstanceSiteMap::const_iterator iter = |
+ i->second.instance_https_site_map.begin(); |
+ iter != i->second.instance_https_site_map.end(); ++iter) { |
+ num_isolated_https_site_instances += iter->second.size(); |
+ } |
+ } |
+ |
+ // Predict the number of processes needed when isolating all sites and when |
+ // isolating only HTTPS sites. |
+ int process_count_lower_bound = num_sites; |
+ int process_count_upper_bound = num_sites + process_limit - 1; |
+ int process_count_estimate = std::min( |
+ num_isolated_site_instances, process_count_upper_bound); |
+ |
+ int process_count_https_lower_bound = num_https_sites; |
+ int process_count_https_upper_bound = num_https_sites + process_limit - 1; |
+ int process_count_https_estimate = std::min( |
+ num_isolated_https_site_instances, process_count_https_upper_bound); |
+ |
+ // Just renderer process count: |
+ int all_renderer_count = renderer_count + chrome_count + extension_count; |
+ UMA_HISTOGRAM_COUNTS_100("SiteIsolation.CurrentRendererProcessCount", |
+ all_renderer_count); |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.BrowsingInstanceCount", |
+ num_browsing_instances); |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.IsolateAllSitesProcessCountNoLimit", |
+ num_isolated_site_instances); |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.IsolateAllSitesProcessCountLowerBound", |
+ process_count_lower_bound); |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.IsolateAllSitesProcessCountEstimate", |
+ process_count_estimate); |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.IsolateHttpsSitesProcessCountNoLimit", |
+ num_isolated_https_site_instances); |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.IsolateHttpsSitesProcessCountLowerBound", |
+ process_count_https_lower_bound); |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.IsolateHttpsSitesProcessCountEstimate", |
+ process_count_https_estimate); |
+ |
+ // Total process count: |
+ int non_renderer_count = browser.processes.size() - all_renderer_count; |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.IsolateAllSitesTotalProcessCountEstimate", |
+ process_count_estimate + non_renderer_count); |
+ UMA_HISTOGRAM_COUNTS_100( |
+ "SiteIsolation.IsolateHttpsSitesTotalProcessCountEstimate", |
+ process_count_https_estimate + non_renderer_count); |
} |