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

Side by Side 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: Fix bad merge. Created 5 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/site_details.h » ('j') | chrome/browser/site_details.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/memory_details.h" 5 #include "chrome/browser/memory_details.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 } 209 }
210 210
211 void MemoryDetails::CollectChildInfoOnUIThread() { 211 void MemoryDetails::CollectChildInfoOnUIThread() {
212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
213 213
214 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 214 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
215 const pid_t zygote_pid = content::ZygoteHost::GetInstance()->GetPid(); 215 const pid_t zygote_pid = content::ZygoteHost::GetInstance()->GetPid();
216 #endif 216 #endif
217 217
218 ProcessData* const chrome_browser = ChromeBrowser(); 218 ProcessData* const chrome_browser = ChromeBrowser();
219
220 // First pass, collate the widgets by process ID.
221 std::map<base::ProcessId, std::vector<RenderWidgetHost*>> widgets_by_pid;
222 scoped_ptr<content::RenderWidgetHostIterator> widget_it(
223 RenderWidgetHost::GetRenderWidgetHosts());
224 while (content::RenderWidgetHost* widget = widget_it->GetNextHost()) {
225 // Ignore processes that don't have a connection, such as crashed tabs.
226 if (!widget->GetProcess()->HasConnection())
227 continue;
228 base::ProcessId pid = base::GetProcId(widget->GetProcess()->GetHandle());
229 widgets_by_pid[pid].push_back(widget);
230 }
231
219 // Get more information about the process. 232 // Get more information about the process.
220 for (size_t index = 0; index < chrome_browser->processes.size(); 233 for (ProcessMemoryInformation& process : chrome_browser->processes) {
221 index++) { 234 // If there's at least one widget in the process, it is some kind of
222 // Check if it's a renderer, if so get the list of page titles in it and 235 // renderer process belonging to this browser. All these widgets will share
223 // check if it's a diagnostics-related process. We skip about:memory pages. 236 // a RenderProcessHost.
224 // Iterate the RenderProcessHosts to find the tab contents. 237 content::RenderProcessHost* render_process_host = nullptr;
225 ProcessMemoryInformation& process = 238 if (!widgets_by_pid[process.pid].empty()) {
226 chrome_browser->processes[index]; 239 // Mark it as a normal renderer process, if we don't refine it to some
240 // other |renderer_type| later.
241 process.process_type = content::PROCESS_TYPE_RENDERER;
242 process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL;
243 render_process_host = widgets_by_pid[process.pid].front()->GetProcess();
244 }
227 245
228 scoped_ptr<content::RenderWidgetHostIterator> widgets(
229 RenderWidgetHost::GetRenderWidgetHosts());
230 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
231 content::RenderProcessHost* render_process_host =
232 widget->GetProcess();
233 DCHECK(render_process_host);
234 // Ignore processes that don't have a connection, such as crashed tabs.
235 if (!render_process_host->HasConnection() ||
236 process.pid != base::GetProcId(render_process_host->GetHandle())) {
237 continue;
238 }
239
240 // The RenderProcessHost may host multiple WebContentses. Any
241 // of them which contain diagnostics information make the whole
242 // process be considered a diagnostics process.
243 RenderViewHost* host = RenderViewHost::From(widget);
244 if (!host)
245 continue;
246
247 process.process_type = content::PROCESS_TYPE_RENDERER;
248 bool is_extension = false;
249 #if defined(ENABLE_EXTENSIONS) 246 #if defined(ENABLE_EXTENSIONS)
247 // Determine if this is an extension process.
248 bool process_is_for_extensions = false;
249 if (render_process_host) {
250 content::BrowserContext* context = 250 content::BrowserContext* context =
251 render_process_host->GetBrowserContext(); 251 render_process_host->GetBrowserContext();
252 extensions::ExtensionRegistry* extension_registry = 252 extensions::ExtensionRegistry* extension_registry =
253 extensions::ExtensionRegistry::Get(context); 253 extensions::ExtensionRegistry::Get(context);
254 extensions::ProcessMap* extension_process_map = 254 extensions::ProcessMap* extension_process_map =
255 extensions::ProcessMap::Get(context); 255 extensions::ProcessMap::Get(context);
256 is_extension = extension_process_map->Contains( 256 process_is_for_extensions =
257 host->GetProcess()->GetID()); 257 extension_process_map->Contains(render_process_host->GetID());
258
259 // For our purposes, don't count processes containing only hosted apps
260 // as extension processes. See also: crbug.com/102533.
261 std::set<std::string> extension_ids =
262 extension_process_map->GetExtensionsInProcess(
263 render_process_host->GetID());
264 for (std::set<std::string>::iterator iter = extension_ids.begin();
Lei Zhang 2015/10/30 07:17:48 convert to range-based for loop?
ncarter (slow) 2015/10/30 18:13:23 Done.
265 iter != extension_ids.end(); ++iter) {
266 const Extension* extension =
267 extension_registry->enabled_extensions().GetByID(*iter);
268 if (extension && !extension->is_hosted_app()) {
269 process.renderer_type = ProcessMemoryInformation::RENDERER_EXTENSION;
270 break;
271 }
272 }
273 }
258 #endif 274 #endif
259 275
260 WebContents* contents = WebContents::FromRenderViewHost(host); 276 // Use the list of widgets to iterate over the WebContents instances whose
261 GURL url; 277 // main RenderFrameHosts are in |process|. Refine our determination of the
262 if (contents) { 278 // |process.renderer_type|, and record the page titles.
263 url = contents->GetURL(); 279 for (content::RenderWidgetHost* widget : widgets_by_pid[process.pid]) {
264 SiteData* site_data = 280 DCHECK_EQ(render_process_host, widget->GetProcess());
265 &chrome_browser->site_data[contents->GetBrowserContext()]; 281
266 SiteDetails::CollectSiteInfo(contents, site_data); 282 RenderViewHost* rvh = RenderViewHost::From(widget);
283 if (!rvh)
284 continue;
285
286 WebContents* contents = WebContents::FromRenderViewHost(rvh);
287
288 // Assume that an RVH without a web contents is an interstitial.
289 if (!contents) {
290 process.renderer_type = ProcessMemoryInformation::RENDERER_INTERSTITIAL;
291 continue;
267 } 292 }
293
294 // If this is a RVH for a subframe; skip it to avoid double-counting the
295 // WebContents.
296 if (rvh != contents->GetRenderViewHost())
297 continue;
298
299 // The rest of this block will happen only once per WebContents.
300 GURL page_url = contents->GetLastCommittedURL();
301 SiteData* site_data =
Lei Zhang 2015/10/30 07:17:49 Make this a reference and call SiteDetails::Collec
ncarter (slow) 2015/10/30 18:13:24 Done.
302 &chrome_browser->site_data[contents->GetBrowserContext()];
303 SiteDetails::CollectSiteInfo(contents, site_data);
304
305 bool is_webui =
306 rvh->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI;
307
308 if (is_webui) {
309 process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME;
310 }
311
268 #if defined(ENABLE_EXTENSIONS) 312 #if defined(ENABLE_EXTENSIONS)
Lei Zhang 2015/10/30 07:17:49 I'm probably to blame for the #if ugliness in the
ncarter (slow) 2015/10/30 18:13:23 Thanks!
269 extensions::ViewType type = extensions::GetViewType(contents); 313 if (!is_webui && process_is_for_extensions) {
270 #endif
271 if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) {
272 process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME;
273 } else if (is_extension) {
274 #if defined(ENABLE_EXTENSIONS)
275 // For our purposes, don't count processes containing only hosted apps
276 // as extension processes. See also: crbug.com/102533.
277 std::set<std::string> extension_ids =
278 extension_process_map->GetExtensionsInProcess(
279 host->GetProcess()->GetID());
280 for (std::set<std::string>::iterator iter = extension_ids.begin();
281 iter != extension_ids.end(); ++iter) {
282 const Extension* extension =
283 extension_registry->enabled_extensions().GetByID(*iter);
284 if (extension && !extension->is_hosted_app()) {
285 process.renderer_type =
286 ProcessMemoryInformation::RENDERER_EXTENSION;
287 break;
288 }
289 }
290 #endif
291 }
292 #if defined(ENABLE_EXTENSIONS)
293 if (is_extension) {
294 const Extension* extension = 314 const Extension* extension =
295 extension_registry->enabled_extensions().GetByID(url.host()); 315 extensions::ExtensionRegistry::Get(
316 render_process_host->GetBrowserContext())
317 ->enabled_extensions()
318 .GetByID(page_url.host());
296 if (extension) { 319 if (extension) {
297 base::string16 title = base::UTF8ToUTF16(extension->name()); 320 base::string16 title = base::UTF8ToUTF16(extension->name());
298 process.titles.push_back(title); 321 process.titles.push_back(title);
299 process.renderer_type = 322 process.renderer_type =
300 ProcessMemoryInformation::RENDERER_EXTENSION; 323 ProcessMemoryInformation::RENDERER_EXTENSION;
301 continue; 324 continue;
302 } 325 }
303 } 326 }
304 #endif
305 327
306 if (!contents) { 328 extensions::ViewType type = extensions::GetViewType(contents);
307 process.renderer_type =
308 ProcessMemoryInformation::RENDERER_INTERSTITIAL;
309 continue;
310 }
311
312 #if defined(ENABLE_EXTENSIONS)
313 if (type == extensions::VIEW_TYPE_BACKGROUND_CONTENTS) { 329 if (type == extensions::VIEW_TYPE_BACKGROUND_CONTENTS) {
314 process.titles.push_back(base::UTF8ToUTF16(url.spec())); 330 process.titles.push_back(base::UTF8ToUTF16(page_url.spec()));
315 process.renderer_type = 331 process.renderer_type =
316 ProcessMemoryInformation::RENDERER_BACKGROUND_APP; 332 ProcessMemoryInformation::RENDERER_BACKGROUND_APP;
317 continue; 333 continue;
318 } 334 }
319 #endif 335 #endif
320 336
321 // Since we have a WebContents and and the renderer type hasn't been
322 // set yet, it must be a normal tabbed renderer.
323 if (process.renderer_type == ProcessMemoryInformation::RENDERER_UNKNOWN)
324 process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL;
325
326 base::string16 title = contents->GetTitle(); 337 base::string16 title = contents->GetTitle();
327 if (!title.length()) 338 if (!title.length())
328 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE); 339 title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
329 process.titles.push_back(title); 340 process.titles.push_back(title);
330 341
342 // The presence of a single WebContents with a diagnostics page will make
Lei Zhang 2015/10/30 07:17:49 typo continuing onto next line: make\nmake
ncarter (slow) 2015/10/30 18:13:24 Done.
343 // make the whole process be considered a diagnostics process.
344 //
331 // We need to check the pending entry as well as the virtual_url to 345 // We need to check the pending entry as well as the virtual_url to
332 // see if it's a chrome://memory URL (we don't want to count these in 346 // see if it's a chrome://memory URL (we don't want to count these in
333 // the total memory usage of the browser). 347 // the total memory usage of the browser).
334 // 348 //
335 // When we reach here, chrome://memory will be the pending entry since 349 // When we reach here, chrome://memory will be the pending entry since
336 // we haven't responded with any data such that it would be committed. 350 // we haven't responded with any data such that it would be committed.
337 // If you have another chrome://memory tab open (which would be 351 // If you have another chrome://memory tab open (which would be
338 // committed), we don't want to count it either, so we also check the 352 // committed), we don't want to count it either, so we also check the
339 // last committed entry. 353 // last committed entry.
340 // 354 //
(...skipping 15 matching lines...) Expand all
356 } 370 }
357 371
358 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 372 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
359 if (process.pid == zygote_pid) { 373 if (process.pid == zygote_pid) {
360 process.process_type = content::PROCESS_TYPE_ZYGOTE; 374 process.process_type = content::PROCESS_TYPE_ZYGOTE;
361 } 375 }
362 #endif 376 #endif
363 } 377 }
364 378
365 // Get rid of other Chrome processes that are from a different profile. 379 // Get rid of other Chrome processes that are from a different profile.
366 for (size_t index = 0; index < chrome_browser->processes.size(); 380 auto is_unknown = [](ProcessMemoryInformation& process) {
367 index++) { 381 return process.process_type == content::PROCESS_TYPE_UNKNOWN;
368 if (chrome_browser->processes[index].process_type == 382 };
369 content::PROCESS_TYPE_UNKNOWN) { 383 auto& vector = chrome_browser->processes;
370 chrome_browser->processes.erase( 384 vector.erase(std::remove_if(vector.begin(), vector.end(), is_unknown),
371 chrome_browser->processes.begin() + index); 385 vector.end());
372 index--;
373 }
374 }
375 386
376 OnDetailsAvailable(); 387 OnDetailsAvailable();
377 } 388 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/site_details.h » ('j') | chrome/browser/site_details.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698