15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/memory_details.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_version_info.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "components/nacl/common/nacl_process_type.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_child_process_host_iterator.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/child_process_data.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/public/browser/render_widget_host_iterator.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/bindings_policy.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/zygote_host_linux.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/extension_service.h"
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_system.h"
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/process_manager.h"
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/process_map.h"
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/view_type_utils.h"
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/extension.h"
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPrintf;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserChildProcessHostIterator;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProcessMemoryInformation::GetRendererTypeNameInEnglish(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RendererProcessType type) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_NORMAL:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Tab";
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_CHROME:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Tab (Chrome)";
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_EXTENSION:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Extension";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_DEVTOOLS:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Devtools";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_INTERSTITIAL:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Interstitial";
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_BACKGROUND_APP:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Background App";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_UNKNOWN:
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown renderer process type!";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Unknown";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProcessMemoryInformation::GetFullTypeNameInEnglish(
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int process_type,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RendererProcessType rtype) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (process_type == content::PROCESS_TYPE_RENDERER)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetRendererTypeNameInEnglish(rtype);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return content::GetProcessTypeNameInEnglish(process_type);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessMemoryInformation::ProcessMemoryInformation()
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : pid(0),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_processes(0),
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_diagnostics(false),
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process_type(content::PROCESS_TYPE_UNKNOWN),
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      renderer_type(RENDERER_UNKNOWN) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessMemoryInformation::~ProcessMemoryInformation() {}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProcessMemoryInformation::operator<(
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProcessMemoryInformation& rhs) const {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return working_set.priv < rhs.working_set.priv;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData::ProcessData() {}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData::ProcessData(const ProcessData& rhs)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : name(rhs.name),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      process_name(rhs.process_name),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      processes(rhs.processes) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData::~ProcessData() {}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData& ProcessData::operator=(const ProcessData& rhs) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name = rhs.name;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  process_name = rhs.process_name;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processes = rhs.processes;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *this;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMemoryGrowthTracker::MemoryGrowthTracker() {}
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
119116680a4aac90f2aa7413d9095a592090648e557Ben MurdochMemoryGrowthTracker::~MemoryGrowthTracker() {}
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool MemoryGrowthTracker::UpdateSample(
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::ProcessId pid,
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int sample,
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int* diff) {
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |sample| is memory usage in kB.
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const base::TimeTicks current_time = base::TimeTicks::Now();
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::map<base::ProcessId, int>::iterator found_size = memory_sizes_.find(pid);
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (found_size != memory_sizes_.end()) {
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const int last_size = found_size->second;
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::map<base::ProcessId, base::TimeTicks>::iterator found_time =
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        times_.find(pid);
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::TimeTicks last_time = found_time->second;
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (last_time < (current_time - base::TimeDelta::FromMinutes(30))) {
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // Note that it is undefined how division of a negative integer gets
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // rounded. |*diff| may have a difference of 1 from the correct number
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // if |sample| < |last_size|. We ignore it as 1 is small enough.
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *diff = ((sample - last_size) * 30 /
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               (current_time - last_time).InMinutes());
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      found_size->second = sample;
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      found_time->second = current_time;
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return true;
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Skip if a last record is found less than 30 minutes ago.
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Not reporting if it's the first record for |pid|.
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    times_[pid] = current_time;
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    memory_sizes_[pid] = sample;
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return false;
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// About threading:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This operation will hit no fewer than 3 threads.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The BrowserChildProcessHostIterator can only be accessed from the IO thread.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The RenderProcessHostIterator can only be accessed from the UI thread.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This operation can take 30-100ms to complete.  We never want to have
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one task run for that long on the UI or IO threads.  So, we run the
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expensive parts of this operation over on the file thread.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::StartFetch(UserMetricsMode user_metrics_mode) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This might get called from the UI or FILE threads, but should not be
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // getting called from the IO thread.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_metrics_mode_ = user_metrics_mode;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In order to process this request, we need to use the plugin information.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // However, plugin process information is only available from the IO thread.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&MemoryDetails::CollectChildInfoOnIOThread, this));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MemoryDetails::~MemoryDetails() {}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string MemoryDetails::ToLogString() {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string log;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.reserve(4096);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessMemoryInformationList processes = ChromeBrowser()->processes;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sort by memory consumption, low to high.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(processes.begin(), processes.end());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Print from high to low.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ProcessMemoryInformationList::reverse_iterator iter1 =
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          processes.rbegin();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter1 != processes.rend();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter1) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log += ProcessMemoryInformation::GetFullTypeNameInEnglish(
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            iter1->process_type, iter1->renderer_type);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!iter1->titles.empty()) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log += " [";
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      for (std::vector<base::string16>::const_iterator iter2 =
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               iter1->titles.begin();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           iter2 != iter1->titles.end(); ++iter2) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (iter2 != iter1->titles.begin())
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          log += "|";
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        log += base::UTF16ToUTF8(*iter2);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log += "]";
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    log += StringPrintf(" %d MB private, %d MB shared",
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        static_cast<int>(iter1->working_set.priv) / 1024,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        static_cast<int>(iter1->working_set.shared) / 1024);
206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_CHROMEOS)
207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    log += StringPrintf(", %d MB swapped",
208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        static_cast<int>(iter1->working_set.swapped) / 1024);
209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    log += "\n";
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return log;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid MemoryDetails::SetMemoryGrowthTracker(
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    MemoryGrowthTracker* memory_growth_tracker) {
217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  memory_growth_tracker_ = memory_growth_tracker;
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::CollectChildInfoOnIOThread() {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ProcessMemoryInformation> child_info;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Collect the list of child processes. A 0 |handle| means that
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the process is being launched, so we skip it.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessMemoryInformation info;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!iter.GetData().handle)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.pid = base::GetProcId(iter.GetData().handle);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!info.pid)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info.process_type = iter.GetData().process_type;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.renderer_type = ProcessMemoryInformation::RENDERER_UNKNOWN;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.titles.push_back(iter.GetData().name);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child_info.push_back(info);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now go do expensive memory lookups from the file thread.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE, FROM_HERE,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&MemoryDetails::CollectProcessData, this, child_info));
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::CollectChildInfoOnUIThread() {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const pid_t zygote_pid = content::ZygoteHost::GetInstance()->GetPid();
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessData* const chrome_browser = ChromeBrowser();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get more information about the process.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t index = 0; index < chrome_browser->processes.size();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index++) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check if it's a renderer, if so get the list of page titles in it and
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // check if it's a diagnostics-related process.  We skip about:memory pages.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Iterate the RenderProcessHosts to find the tab contents.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessMemoryInformation& process =
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome_browser->processes[index];
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    scoped_ptr<content::RenderWidgetHostIterator> widgets(
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        RenderWidgetHost::GetRenderWidgetHosts());
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::RenderProcessHost* render_process_host =
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          widget->GetProcess();
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(render_process_host);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Ignore processes that don't have a connection, such as crashed tabs.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!render_process_host->HasConnection() ||
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          process.pid != base::GetProcId(render_process_host->GetHandle())) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The RenderProcessHost may host multiple WebContentses.  Any
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // of them which contain diagnostics information make the whole
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // process be considered a diagnostics process.
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      if (!widget->IsRenderView())
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        continue;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      process.process_type = content::PROCESS_TYPE_RENDERER;
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bool is_extension = false;
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      RenderViewHost* host = RenderViewHost::From(widget);
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      content::BrowserContext* context =
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          render_process_host->GetBrowserContext();
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ExtensionService* extension_service =
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          extensions::ExtensionSystem::Get(context)->extension_service();
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extensions::ProcessMap* extension_process_map =
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          extensions::ProcessMap::Get(context);
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      is_extension = extension_process_map->Contains(
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          host->GetProcess()->GetID());
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WebContents* contents = WebContents::FromRenderViewHost(host);
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GURL url;
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (contents) {
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        url = contents->GetURL();
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SiteData* site_data =
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            &chrome_browser->site_data[contents->GetBrowserContext()];
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SiteDetails::CollectSiteInfo(contents, site_data);
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      extensions::ViewType type = extensions::GetViewType(contents);
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) {
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME;
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      } else if (is_extension) {
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        // For our purposes, don't count processes containing only hosted apps
312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        // as extension processes. See also: crbug.com/102533.
313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        std::set<std::string> extension_ids =
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            extension_process_map->GetExtensionsInProcess(
315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            host->GetProcess()->GetID());
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        for (std::set<std::string>::iterator iter = extension_ids.begin();
317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             iter != extension_ids.end(); ++iter) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const Extension* extension =
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              extension_service->GetExtensionById(*iter, false);
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          if (extension && !extension->is_hosted_app()) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            process.renderer_type =
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ProcessMemoryInformation::RENDERER_EXTENSION;
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            break;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (is_extension) {
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        const Extension* extension =
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            extension_service->extensions()->GetByID(url.host());
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        if (extension) {
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::string16 title = base::UTF8ToUTF16(extension->name());
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          process.titles.push_back(title);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          process.renderer_type =
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              ProcessMemoryInformation::RENDERER_EXTENSION;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          continue;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!contents) {
343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type =
344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            ProcessMemoryInformation::RENDERER_INTERSTITIAL;
345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        continue;
346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS)
349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (type == extensions::VIEW_TYPE_BACKGROUND_CONTENTS) {
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        process.titles.push_back(base::UTF8ToUTF16(url.spec()));
351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type =
352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            ProcessMemoryInformation::RENDERER_BACKGROUND_APP;
353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        continue;
354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Since we have a WebContents and and the renderer type hasn't been
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // set yet, it must be a normal tabbed renderer.
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (process.renderer_type == ProcessMemoryInformation::RENDERER_UNKNOWN)
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL;
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::string16 title = contents->GetTitle();
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!title.length())
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      process.titles.push_back(title);
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // We need to check the pending entry as well as the virtual_url to
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // see if it's a chrome://memory URL (we don't want to count these in
369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // the total memory usage of the browser).
370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      //
371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // When we reach here, chrome://memory will be the pending entry since
372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // we haven't responded with any data such that it would be committed.
373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // If you have another chrome://memory tab open (which would be
374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // committed), we don't want to count it either, so we also check the
375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // last committed entry.
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      //
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Either the pending or last committed entries can be NULL.
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const NavigationEntry* pending_entry =
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          contents->GetController().GetPendingEntry();
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const NavigationEntry* last_committed_entry =
381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          contents->GetController().GetLastCommittedEntry();
382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if ((last_committed_entry &&
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           LowerCaseEqualsASCII(last_committed_entry->GetVirtualURL().spec(),
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                chrome::kChromeUIMemoryURL)) ||
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          (pending_entry &&
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           LowerCaseEqualsASCII(pending_entry->GetVirtualURL().spec(),
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                chrome::kChromeUIMemoryURL))) {
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.is_diagnostics = true;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process.pid == zygote_pid) {
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process.process_type = content::PROCESS_TYPE_ZYGOTE;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get rid of other Chrome processes that are from a different profile.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t index = 0; index < chrome_browser->processes.size();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index++) {
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (chrome_browser->processes[index].process_type ==
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::PROCESS_TYPE_UNKNOWN) {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome_browser->processes.erase(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chrome_browser->processes.begin() + index);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index--;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (user_metrics_mode_ == UPDATE_USER_METRICS)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateHistograms();
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnDetailsAvailable();
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::UpdateHistograms() {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reports a set of memory metrics to UMA.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Memory is measured in KB.
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProcessData& browser = *ChromeBrowser();
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t aggregate_memory = 0;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int chrome_count = 0;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int extension_count = 0;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int plugin_count = 0;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pepper_plugin_count = 0;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pepper_plugin_broker_count = 0;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int renderer_count = 0;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int other_count = 0;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int worker_count = 0;
4307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_limit = content::RenderProcessHost::GetMaxRendererProcessCount();
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t index = 0; index < browser.processes.size(); index++) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int sample = static_cast<int>(browser.processes[index].working_set.priv);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aggregate_memory += sample;
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (browser.processes[index].process_type) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_BROWSER:
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample);
4377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_RENDERER: {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProcessMemoryInformation::RendererProcessType renderer_type =
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            browser.processes[index].renderer_type;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switch (renderer_type) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case ProcessMemoryInformation::RENDERER_EXTENSION:
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            UMA_HISTOGRAM_MEMORY_KB("Memory.Extension", sample);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            extension_count++;
4457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case ProcessMemoryInformation::RENDERER_CHROME:
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            UMA_HISTOGRAM_MEMORY_KB("Memory.Chrome", sample);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            chrome_count++;
4497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case ProcessMemoryInformation::RENDERER_UNKNOWN:
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NOTREACHED() << "Unknown renderer process type.";
4527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case ProcessMemoryInformation::RENDERER_NORMAL:
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          default:
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // TODO(erikkay): Should we bother splitting out the other subtypes?
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample);
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            int diff;
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            if (memory_growth_tracker_ &&
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                memory_growth_tracker_->UpdateSample(
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    browser.processes[index].pid, sample, &diff)) {
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              if (diff < 0)
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                UMA_HISTOGRAM_MEMORY_KB("Memory.RendererShrinkIn30Min", -diff);
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              else
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                UMA_HISTOGRAM_MEMORY_KB("Memory.RendererGrowthIn30Min", diff);
465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            }
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            renderer_count++;
4677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_PLUGIN:
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        plugin_count++;
4737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_UTILITY:
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_count++;
4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_ZYGOTE:
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_count++;
4817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_SANDBOX_HELPER:
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_count++;
4857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_GPU:
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_count++;
4897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_PPAPI_PLUGIN:
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPlugin", sample);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pepper_plugin_count++;
4937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_PPAPI_BROKER:
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPluginBroker", sample);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pepper_plugin_broker_count++;
4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PROCESS_TYPE_NACL_LOADER:
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        other_count++;
5017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PROCESS_TYPE_NACL_BROKER:
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample);
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        other_count++;
5057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Chrome OS exposes system-wide graphics driver memory which has historically
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // been a source of leak/bloat.
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SystemMemoryInfoKB meminfo;
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (base::GetSystemMemoryInfo(&meminfo) && meminfo.gem_size != -1)
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UMA_HISTOGRAM_MEMORY_MB("Memory.Graphics", meminfo.gem_size / 1024 / 1024);
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.ProcessLimit", process_limit);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount",
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<int>(browser.processes.size()));
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.ExtensionProcessCount", extension_count);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.OtherProcessCount", other_count);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginProcessCount",
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pepper_plugin_count);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginBrokerProcessCount",
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pepper_plugin_broker_count);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(viettrungluu): Do we want separate counts for the other
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (platform-specific) process types?
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int total_sample = static_cast<int>(aggregate_memory / 1000);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample);
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_CHROMEOS)
5397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  UpdateSwapHistograms();
5407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
5417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
5427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_CHROMEOS)
5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryDetails::UpdateSwapHistograms() {
545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Memory.Swap.HaveSwapped", swap_info_.num_writes > 0);
546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (swap_info_.num_writes == 0)
547ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
548ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
549ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Only record swap info when any swaps have happened, to give us more
550ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // detail in the histograms.
5517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const ProcessData& browser = *ChromeBrowser();
5527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  size_t aggregate_memory = 0;
5537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (size_t index = 0; index < browser.processes.size(); index++) {
5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int sample = static_cast<int>(browser.processes[index].working_set.swapped);
5557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    aggregate_memory += sample;
5567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    switch (browser.processes[index].process_type) {
5577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_BROWSER:
5587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Browser", sample);
5597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_RENDERER: {
5617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        ProcessMemoryInformation::RendererProcessType renderer_type =
5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            browser.processes[index].renderer_type;
5637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        switch (renderer_type) {
5647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          case ProcessMemoryInformation::RENDERER_EXTENSION:
5657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Extension", sample);
5667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          case ProcessMemoryInformation::RENDERER_CHROME:
5687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Chrome", sample);
5697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
5707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          case ProcessMemoryInformation::RENDERER_UNKNOWN:
5717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            NOTREACHED() << "Unknown renderer process type.";
5727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
5737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          case ProcessMemoryInformation::RENDERER_NORMAL:
5747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          default:
5757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Renderer", sample);
5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
5777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
5787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
5797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_PLUGIN:
5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Plugin", sample);
5817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_UTILITY:
5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Utility", sample);
5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_ZYGOTE:
5867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Zygote", sample);
5877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_SANDBOX_HELPER:
5897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.SandboxHelper", sample);
5907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_GPU:
5927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Gpu", sample);
5937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_PPAPI_PLUGIN:
5957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.PepperPlugin", sample);
5967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_PPAPI_BROKER:
5987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.PepperPluginBroker", sample);
5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case PROCESS_TYPE_NACL_LOADER:
6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.NativeClient", sample);
6027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
6037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case PROCESS_TYPE_NACL_BROKER:
6047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.NativeClientBroker", sample);
6057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
6067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      default:
6077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        NOTREACHED();
6087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
6097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int total_sample = static_cast<int>(aggregate_memory / 1000);
6137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  UMA_HISTOGRAM_MEMORY_MB("Memory.Swap.Total", total_sample);
614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
615ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.CompressedDataSize",
616424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                              swap_info_.compr_data_size / (1024 * 1024),
617ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              1, 4096, 50);
618ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.OriginalDataSize",
619424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                              swap_info_.orig_data_size / (1024 * 1024),
620ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              1, 4096, 50);
621ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.MemUsedTotal",
622424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                              swap_info_.mem_used_total / (1024 * 1024),
623ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              1, 4096, 50);
624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.NumReads",
625424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                              swap_info_.num_reads,
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              1, 100000000, 100);
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.NumWrites",
628424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                              swap_info_.num_writes,
629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              1, 100000000, 100);
630ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
631424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (swap_info_.orig_data_size > 0 && swap_info_.compr_data_size > 0) {
632ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UMA_HISTOGRAM_CUSTOM_COUNTS(
633ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        "Memory.Swap.CompressionRatio",
634424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        swap_info_.orig_data_size / swap_info_.compr_data_size,
635ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        1, 20, 20);
636ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
640