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/extensions/extension_process_manager.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "components/nacl/common/nacl_process_type.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_child_process_host_iterator.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/child_process_data.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/bindings_policy.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "extensions/browser/view_type_utils.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/zygote_host_linux.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPrintf;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserChildProcessHostIterator;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProcessMemoryInformation::GetRendererTypeNameInEnglish(
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RendererProcessType type) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_NORMAL:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Tab";
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_CHROME:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Tab (Chrome)";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_EXTENSION:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Extension";
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_DEVTOOLS:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Devtools";
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_INTERSTITIAL:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Interstitial";
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_NOTIFICATION:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Notification";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_BACKGROUND_APP:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Background App";
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case RENDERER_UNKNOWN:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown renderer process type!";
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Unknown";
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ProcessMemoryInformation::GetFullTypeNameInEnglish(
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int process_type,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RendererProcessType rtype) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (process_type == content::PROCESS_TYPE_RENDERER)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetRendererTypeNameInEnglish(rtype);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return content::GetProcessTypeNameInEnglish(process_type);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessMemoryInformation::ProcessMemoryInformation()
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : pid(0),
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_processes(0),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_diagnostics(false),
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process_type(content::PROCESS_TYPE_UNKNOWN),
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      renderer_type(RENDERER_UNKNOWN) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessMemoryInformation::~ProcessMemoryInformation() {}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ProcessMemoryInformation::operator<(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProcessMemoryInformation& rhs) const {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return working_set.priv < rhs.working_set.priv;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData::ProcessData() {}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData::ProcessData(const ProcessData& rhs)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : name(rhs.name),
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      process_name(rhs.process_name),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      processes(rhs.processes) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData::~ProcessData() {}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProcessData& ProcessData::operator=(const ProcessData& rhs) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name = rhs.name;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  process_name = rhs.process_name;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  processes = rhs.processes;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return *this;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// About threading:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This operation will hit no fewer than 3 threads.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The BrowserChildProcessHostIterator can only be accessed from the IO thread.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The RenderProcessHostIterator can only be accessed from the UI thread.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This operation can take 30-100ms to complete.  We never want to have
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one task run for that long on the UI or IO threads.  So, we run the
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expensive parts of this operation over on the file thread.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::StartFetch(UserMetricsMode user_metrics_mode) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This might get called from the UI or FILE threads, but should not be
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // getting called from the IO thread.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  user_metrics_mode_ = user_metrics_mode;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In order to process this request, we need to use the plugin information.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // However, plugin process information is only available from the IO thread.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::IO, FROM_HERE,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&MemoryDetails::CollectChildInfoOnIOThread, this));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MemoryDetails::~MemoryDetails() {}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string MemoryDetails::ToLogString() {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string log;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.reserve(4096);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessMemoryInformationList processes = ChromeBrowser()->processes;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sort by memory consumption, low to high.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(processes.begin(), processes.end());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Print from high to low.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ProcessMemoryInformationList::reverse_iterator iter1 =
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          processes.rbegin();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter1 != processes.rend();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter1) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log += ProcessMemoryInformation::GetFullTypeNameInEnglish(
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            iter1->process_type, iter1->renderer_type);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!iter1->titles.empty()) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log += " [";
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (std::vector<string16>::const_iterator iter2 =
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               iter1->titles.begin();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           iter2 != iter1->titles.end(); ++iter2) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (iter2 != iter1->titles.begin())
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          log += "|";
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        log += UTF16ToUTF8(*iter2);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      log += "]";
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    log += StringPrintf(" %d MB private, %d MB shared",
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        static_cast<int>(iter1->working_set.priv) / 1024,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        static_cast<int>(iter1->working_set.shared) / 1024);
166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_CHROMEOS)
167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    log += StringPrintf(", %d MB swapped",
168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                        static_cast<int>(iter1->working_set.swapped) / 1024);
169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif
170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    log += "\n";
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return log;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::CollectChildInfoOnIOThread() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<ProcessMemoryInformation> child_info;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Collect the list of child processes. A 0 |handle| means that
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the process is being launched, so we skip it.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessMemoryInformation info;
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!iter.GetData().handle)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.pid = base::GetProcId(iter.GetData().handle);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!info.pid)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info.process_type = iter.GetData().process_type;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.renderer_type = ProcessMemoryInformation::RENDERER_UNKNOWN;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    info.titles.push_back(iter.GetData().name);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    child_info.push_back(info);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now go do expensive memory lookups from the file thread.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::FILE, FROM_HERE,
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&MemoryDetails::CollectProcessData, this, child_info));
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::CollectChildInfoOnUIThread() {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const pid_t zygote_pid = content::ZygoteHost::GetInstance()->GetPid();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const pid_t sandbox_helper_pid =
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::ZygoteHost::GetInstance()->GetSandboxHelperPid();
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessData* const chrome_browser = ChromeBrowser();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get more information about the process.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t index = 0; index < chrome_browser->processes.size();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index++) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check if it's a renderer, if so get the list of page titles in it and
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // check if it's a diagnostics-related process.  We skip about:memory pages.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Iterate the RenderProcessHosts to find the tab contents.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessMemoryInformation& process =
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome_browser->processes[index];
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    RenderWidgetHost::List widgets = RenderWidgetHost::GetRenderWidgetHosts();
222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    for (size_t i = 0; i < widgets.size(); ++i) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::RenderProcessHost* render_process_host =
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          widgets[i]->GetProcess();
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(render_process_host);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Ignore processes that don't have a connection, such as crashed tabs.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!render_process_host->HasConnection() ||
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          process.pid != base::GetProcId(render_process_host->GetHandle())) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process.process_type = content::PROCESS_TYPE_RENDERER;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Profile* profile =
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Profile::FromBrowserContext(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              render_process_host->GetBrowserContext());
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExtensionService* extension_service = profile->GetExtensionService();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions::ProcessMap* extension_process_map = NULL;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // No extensions on Android. So extension_service can be NULL.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (extension_service)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extension_process_map = extension_service->process_map();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The RenderProcessHost may host multiple WebContentses.  Any
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // of them which contain diagnostics information make the whole
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // process be considered a diagnostics process.
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!widgets[i]->IsRenderView())
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        continue;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      RenderViewHost* host = RenderViewHost::From(widgets[i]);
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      WebContents* contents = WebContents::FromRenderViewHost(host);
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GURL url;
250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (contents) {
251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        url = contents->GetURL();
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SiteData* site_data =
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            &chrome_browser->site_data[contents->GetBrowserContext()];
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SiteDetails::CollectSiteInfo(contents, site_data);
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      extensions::ViewType type = extensions::GetViewType(contents);
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (host->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) {
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type = ProcessMemoryInformation::RENDERER_CHROME;
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      } else if (extension_process_map &&
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                 extension_process_map->Contains(host->GetProcess()->GetID())) {
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        // For our purposes, don't count processes containing only hosted apps
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        // as extension processes. See also: crbug.com/102533.
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        std::set<std::string> extension_ids =
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            extension_process_map->GetExtensionsInProcess(
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            host->GetProcess()->GetID());
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        for (std::set<std::string>::iterator iter = extension_ids.begin();
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             iter != extension_ids.end(); ++iter) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const Extension* extension =
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              extension_service->GetExtensionById(*iter, false);
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          if (extension && !extension->is_hosted_app()) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            process.renderer_type =
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ProcessMemoryInformation::RENDERER_EXTENSION;
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            break;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (extension_process_map &&
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          extension_process_map->Contains(host->GetProcess()->GetID())) {
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        const Extension* extension =
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            extension_service->extensions()->GetByID(url.host());
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        if (extension) {
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          string16 title = UTF8ToUTF16(extension->name());
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          process.titles.push_back(title);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          process.renderer_type =
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              ProcessMemoryInformation::RENDERER_EXTENSION;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          continue;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!contents) {
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type =
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            ProcessMemoryInformation::RENDERER_INTERSTITIAL;
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        continue;
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (type == extensions::VIEW_TYPE_BACKGROUND_CONTENTS) {
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.titles.push_back(UTF8ToUTF16(url.spec()));
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type =
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            ProcessMemoryInformation::RENDERER_BACKGROUND_APP;
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        continue;
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (type == extensions::VIEW_TYPE_NOTIFICATION) {
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.titles.push_back(UTF8ToUTF16(url.spec()));
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type =
306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            ProcessMemoryInformation::RENDERER_NOTIFICATION;
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        continue;
308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Since we have a WebContents and and the renderer type hasn't been
311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // set yet, it must be a normal tabbed renderer.
312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (process.renderer_type == ProcessMemoryInformation::RENDERER_UNKNOWN)
313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.renderer_type = ProcessMemoryInformation::RENDERER_NORMAL;
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      string16 title = contents->GetTitle();
316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (!title.length())
317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        title = l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      process.titles.push_back(title);
319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // We need to check the pending entry as well as the virtual_url to
321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // see if it's a chrome://memory URL (we don't want to count these in
322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // the total memory usage of the browser).
323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      //
324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // When we reach here, chrome://memory will be the pending entry since
325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // we haven't responded with any data such that it would be committed.
326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // If you have another chrome://memory tab open (which would be
327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // committed), we don't want to count it either, so we also check the
328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // last committed entry.
329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      //
330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      // Either the pending or last committed entries can be NULL.
331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const NavigationEntry* pending_entry =
332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          contents->GetController().GetPendingEntry();
333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      const NavigationEntry* last_committed_entry =
334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          contents->GetController().GetLastCommittedEntry();
335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if ((last_committed_entry &&
336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           LowerCaseEqualsASCII(last_committed_entry->GetVirtualURL().spec(),
337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                chrome::kChromeUIMemoryURL)) ||
338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          (pending_entry &&
339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           LowerCaseEqualsASCII(pending_entry->GetVirtualURL().spec(),
340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                chrome::kChromeUIMemoryURL))) {
341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        process.is_diagnostics = true;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (process.pid == zygote_pid) {
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process.process_type = content::PROCESS_TYPE_ZYGOTE;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (process.pid == sandbox_helper_pid) {
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      process.process_type = content::PROCESS_TYPE_SANDBOX_HELPER;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get rid of other Chrome processes that are from a different profile.
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t index = 0; index < chrome_browser->processes.size();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index++) {
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (chrome_browser->processes[index].process_type ==
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::PROCESS_TYPE_UNKNOWN) {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome_browser->processes.erase(
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chrome_browser->processes.begin() + index);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      index--;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (user_metrics_mode_ == UPDATE_USER_METRICS)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateHistograms();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnDetailsAvailable();
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MemoryDetails::UpdateHistograms() {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reports a set of memory metrics to UMA.
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Memory is measured in KB.
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProcessData& browser = *ChromeBrowser();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t aggregate_memory = 0;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int chrome_count = 0;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int extension_count = 0;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int plugin_count = 0;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pepper_plugin_count = 0;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pepper_plugin_broker_count = 0;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int renderer_count = 0;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int other_count = 0;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int worker_count = 0;
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int process_limit = content::RenderProcessHost::GetMaxRendererProcessCount();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t index = 0; index < browser.processes.size(); index++) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int sample = static_cast<int>(browser.processes[index].working_set.priv);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aggregate_memory += sample;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (browser.processes[index].process_type) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_BROWSER:
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Browser", sample);
3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_RENDERER: {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProcessMemoryInformation::RendererProcessType renderer_type =
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            browser.processes[index].renderer_type;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switch (renderer_type) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case ProcessMemoryInformation::RENDERER_EXTENSION:
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            UMA_HISTOGRAM_MEMORY_KB("Memory.Extension", sample);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            extension_count++;
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case ProcessMemoryInformation::RENDERER_CHROME:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            UMA_HISTOGRAM_MEMORY_KB("Memory.Chrome", sample);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            chrome_count++;
4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case ProcessMemoryInformation::RENDERER_UNKNOWN:
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            NOTREACHED() << "Unknown renderer process type.";
4077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case ProcessMemoryInformation::RENDERER_NORMAL:
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          default:
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // TODO(erikkay): Should we bother splitting out the other subtypes?
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer", sample);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            renderer_count++;
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_PLUGIN:
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Plugin", sample);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        plugin_count++;
4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_WORKER:
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Worker", sample);
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        worker_count++;
4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_UTILITY:
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Utility", sample);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_count++;
4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_ZYGOTE:
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Zygote", sample);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_count++;
4317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_SANDBOX_HELPER:
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.SandboxHelper", sample);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_count++;
4357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_GPU:
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.Gpu", sample);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        other_count++;
4397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_PPAPI_PLUGIN:
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPlugin", sample);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pepper_plugin_count++;
4437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case content::PROCESS_TYPE_PPAPI_BROKER:
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.PepperPluginBroker", sample);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pepper_plugin_broker_count++;
4477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PROCESS_TYPE_NACL_LOADER:
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClient", sample);
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        other_count++;
4517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case PROCESS_TYPE_NACL_BROKER:
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        UMA_HISTOGRAM_MEMORY_KB("Memory.NativeClientBroker", sample);
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        other_count++;
4557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTREACHED();
4587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_MEMORY_KB("Memory.BackingStore",
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          RenderWidgetHost::BackingStoreMemorySize() / 1024);
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Chrome OS exposes system-wide graphics driver memory which has historically
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // been a source of leak/bloat.
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::SystemMemoryInfoKB meminfo;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (base::GetSystemMemoryInfo(&meminfo) && meminfo.gem_size != -1)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UMA_HISTOGRAM_MEMORY_MB("Memory.Graphics", meminfo.gem_size / 1024 / 1024);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.ProcessLimit", process_limit);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount",
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<int>(browser.processes.size()));
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.ChromeProcessCount", chrome_count);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.ExtensionProcessCount", extension_count);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.OtherProcessCount", other_count);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.PluginProcessCount", plugin_count);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginProcessCount",
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pepper_plugin_count);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.PepperPluginBrokerProcessCount",
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pepper_plugin_broker_count);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Memory.WorkerProcessCount", worker_count);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(viettrungluu): Do we want separate counts for the other
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (platform-specific) process types?
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int total_sample = static_cast<int>(aggregate_memory / 1000);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_MEMORY_MB("Memory.Total", total_sample);
4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Predict the number of processes needed when isolating all sites and when
4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // isolating only HTTPS sites.
4927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int all_renderer_count = renderer_count + chrome_count + extension_count;
4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int non_renderer_count = browser.processes.size() - all_renderer_count;
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  SiteDetails::UpdateHistograms(browser.site_data, all_renderer_count,
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                non_renderer_count);
4967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_CHROMEOS)
4977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  UpdateSwapHistograms();
4987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
4997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
5017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_CHROMEOS)
5037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MemoryDetails::UpdateSwapHistograms() {
504ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UMA_HISTOGRAM_BOOLEAN("Memory.Swap.HaveSwapped", swap_data_.num_writes > 0);
505ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (swap_data_.num_writes == 0)
506ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return;
507ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
508ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Only record swap info when any swaps have happened, to give us more
509ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // detail in the histograms.
5107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const ProcessData& browser = *ChromeBrowser();
5117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  size_t aggregate_memory = 0;
5127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (size_t index = 0; index < browser.processes.size(); index++) {
5137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    int sample = static_cast<int>(browser.processes[index].working_set.swapped);
5147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    aggregate_memory += sample;
5157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    switch (browser.processes[index].process_type) {
5167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_BROWSER:
5177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Browser", sample);
5187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_RENDERER: {
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        ProcessMemoryInformation::RendererProcessType renderer_type =
5217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            browser.processes[index].renderer_type;
5227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        switch (renderer_type) {
5237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          case ProcessMemoryInformation::RENDERER_EXTENSION:
5247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Extension", sample);
5257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
5267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          case ProcessMemoryInformation::RENDERER_CHROME:
5277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Chrome", sample);
5287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
5297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          case ProcessMemoryInformation::RENDERER_UNKNOWN:
5307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            NOTREACHED() << "Unknown renderer process type.";
5317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
5327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          case ProcessMemoryInformation::RENDERER_NORMAL:
5337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          default:
5347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Renderer", sample);
5357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            continue;
5367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
5377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      }
5387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_PLUGIN:
5397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Plugin", sample);
5407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_WORKER:
5427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Worker", sample);
5437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_UTILITY:
5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Utility", sample);
5467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_ZYGOTE:
5487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Zygote", sample);
5497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_SANDBOX_HELPER:
5517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.SandboxHelper", sample);
5527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_GPU:
5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.Gpu", sample);
5557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_PPAPI_PLUGIN:
5577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.PepperPlugin", sample);
5587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::PROCESS_TYPE_PPAPI_BROKER:
5607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.PepperPluginBroker", sample);
5617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case PROCESS_TYPE_NACL_LOADER:
5637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.NativeClient", sample);
5647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case PROCESS_TYPE_NACL_BROKER:
5667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        UMA_HISTOGRAM_MEMORY_KB("Memory.Swap.NativeClientBroker", sample);
5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      default:
5697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        NOTREACHED();
5707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        continue;
5717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
5727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
5737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
5747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int total_sample = static_cast<int>(aggregate_memory / 1000);
5757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  UMA_HISTOGRAM_MEMORY_MB("Memory.Swap.Total", total_sample);
576ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
577ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.CompressedDataSize",
578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              swap_data_.compr_data_size / (1024 * 1024),
579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              1, 4096, 50);
580ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.OriginalDataSize",
581ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              swap_data_.orig_data_size / (1024 * 1024),
582ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              1, 4096, 50);
583ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.MemUsedTotal",
584ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              swap_data_.mem_used_total / (1024 * 1024),
585ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                              1, 4096, 50);
586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.NumReads",
587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              swap_data_.num_reads,
588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              1, 100000000, 100);
589a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UMA_HISTOGRAM_CUSTOM_COUNTS("Memory.Swap.NumWrites",
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              swap_data_.num_writes,
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              1, 100000000, 100);
592ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
593ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (swap_data_.orig_data_size > 0 && swap_data_.compr_data_size > 0) {
594ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UMA_HISTOGRAM_CUSTOM_COUNTS(
595ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        "Memory.Swap.CompressionRatio",
596ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        swap_data_.orig_data_size / swap_data_.compr_data_size,
597ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        1, 20, 20);
598ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
602