| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/status/memory_menu_button.h" | 5 #include "chrome/browser/chromeos/status/memory_menu_button.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | |
| 8 #include "base/process_util.h" // GetSystemMemoryInfo | 7 #include "base/process_util.h" // GetSystemMemoryInfo |
| 9 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
| 10 #include "chrome/browser/chromeos/status/status_area_host.h" | 9 #include "chrome/browser/chromeos/status/status_area_host.h" |
| 11 #include "chrome/browser/memory_purger.h" | 10 #include "chrome/browser/memory_purger.h" |
| 12 #include "chrome/common/render_messages.h" | |
| 13 #include "content/browser/renderer_host/render_process_host.h" | |
| 14 #include "grit/generated_resources.h" | 11 #include "grit/generated_resources.h" |
| 15 #include "ui/base/l10n/l10n_util.h" | 12 #include "ui/base/l10n/l10n_util.h" |
| 16 #include "views/widget/widget.h" | 13 #include "views/widget/widget.h" |
| 17 | 14 |
| 18 #if defined(USE_TCMALLOC) | |
| 19 #include "third_party/tcmalloc/chromium/src/google/heap-profiler.h" | |
| 20 #endif | |
| 21 | |
| 22 #if defined(USE_TCMALLOC) | |
| 23 const char kProfileDumpFilePrefix[] = "/tmp/chrome_tcmalloc"; | |
| 24 #endif | |
| 25 | |
| 26 namespace { | 15 namespace { |
| 27 | 16 |
| 28 // views::MenuItemView item ids | 17 // views::MenuItemView item ids |
| 29 enum { | 18 enum { |
| 30 MEM_TOTAL_ITEM, | 19 MEM_TOTAL_ITEM, |
| 31 MEM_FREE_ITEM, | 20 MEM_FREE_ITEM, |
| 32 MEM_BUFFERS_ITEM, | 21 MEM_BUFFERS_ITEM, |
| 33 MEM_CACHE_ITEM, | 22 MEM_CACHE_ITEM, |
| 34 SHMEM_ITEM, | 23 SHMEM_ITEM, |
| 35 PURGE_MEMORY_ITEM, | 24 PURGE_MEMORY_ITEM, |
| 36 #if defined(USE_TCMALLOC) | |
| 37 TOGGLE_PROFILING_ITEM, | |
| 38 DUMP_PROFILING_ITEM, | |
| 39 #endif | |
| 40 }; | 25 }; |
| 41 | 26 |
| 42 } // namespace | 27 } // namespace |
| 43 | 28 |
| 44 namespace chromeos { | 29 namespace chromeos { |
| 45 | 30 |
| 46 // Delay between updates, in seconds. | 31 // Delay between updates, in seconds. |
| 47 const int kUpdateIntervalSeconds = 5; | 32 const int kUpdateIntervalSeconds = 5; |
| 48 | 33 |
| 49 MemoryMenuButton::MemoryMenuButton(StatusAreaHost* host) | 34 MemoryMenuButton::MemoryMenuButton(StatusAreaHost* host) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 case MEM_FREE_ITEM: | 75 case MEM_FREE_ITEM: |
| 91 return StringPrintf(L"%d MB free", mem_free_ / 1024); | 76 return StringPrintf(L"%d MB free", mem_free_ / 1024); |
| 92 case MEM_BUFFERS_ITEM: | 77 case MEM_BUFFERS_ITEM: |
| 93 return StringPrintf(L"%d MB buffers", mem_buffers_ / 1024); | 78 return StringPrintf(L"%d MB buffers", mem_buffers_ / 1024); |
| 94 case MEM_CACHE_ITEM: | 79 case MEM_CACHE_ITEM: |
| 95 return StringPrintf(L"%d MB cache", mem_cache_ / 1024); | 80 return StringPrintf(L"%d MB cache", mem_cache_ / 1024); |
| 96 case SHMEM_ITEM: | 81 case SHMEM_ITEM: |
| 97 return StringPrintf(L"%d MB shmem", shmem_ / 1024); | 82 return StringPrintf(L"%d MB shmem", shmem_ / 1024); |
| 98 case PURGE_MEMORY_ITEM: | 83 case PURGE_MEMORY_ITEM: |
| 99 return L"Purge memory"; | 84 return L"Purge memory"; |
| 100 #if defined(USE_TCMALLOC) | |
| 101 case TOGGLE_PROFILING_ITEM: | |
| 102 if (!IsHeapProfilerRunning()) | |
| 103 return L"Start profiling"; | |
| 104 else | |
| 105 return L"Stop profiling"; | |
| 106 case DUMP_PROFILING_ITEM: | |
| 107 return L"Dump profile"; | |
| 108 #endif | |
| 109 default: | 85 default: |
| 110 return std::wstring(); | 86 return std::wstring(); |
| 111 } | 87 } |
| 112 } | 88 } |
| 113 | 89 |
| 114 bool MemoryMenuButton::IsCommandEnabled(int id) const { | 90 bool MemoryMenuButton::IsCommandEnabled(int id) const { |
| 115 switch (id) { | 91 switch (id) { |
| 116 case PURGE_MEMORY_ITEM: | 92 case PURGE_MEMORY_ITEM: |
| 117 return true; | 93 return true; |
| 118 #if defined(USE_TCMALLOC) | |
| 119 case TOGGLE_PROFILING_ITEM: | |
| 120 case DUMP_PROFILING_ITEM: | |
| 121 return true; | |
| 122 #endif | |
| 123 default: | 94 default: |
| 124 return false; | 95 return false; |
| 125 } | 96 } |
| 126 } | 97 } |
| 127 | 98 |
| 128 namespace { | |
| 129 FilePath::StringType GetFilePath(base::ProcessId pid) { | |
| 130 int int_pid = static_cast<int>(pid); | |
| 131 FilePath::StringType filepath = StringPrintf( | |
| 132 FILE_PATH_LITERAL("%s.%d.heap"), | |
| 133 FILE_PATH_LITERAL(kProfileDumpFilePrefix), int_pid); | |
| 134 return filepath; | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 void MemoryMenuButton::SendCommandToRenderers(int id) { | |
| 139 #if defined(USE_TCMALLOC) | |
| 140 // Use the "is running" value for this process to determine whether to | |
| 141 // start or stop profiling on the renderer processes. | |
| 142 bool started = IsHeapProfilerRunning(); | |
| 143 for (RenderProcessHost::iterator it = RenderProcessHost::AllHostsIterator(); | |
| 144 !it.IsAtEnd(); it.Advance()) { | |
| 145 switch (id) { | |
| 146 case TOGGLE_PROFILING_ITEM: | |
| 147 it.GetCurrentValue()->Send(new ViewMsg_SetTcmallocHeapProfiling( | |
| 148 started, std::string(kProfileDumpFilePrefix))); | |
| 149 break; | |
| 150 case DUMP_PROFILING_ITEM: | |
| 151 it.GetCurrentValue()->Send(new ViewMsg_WriteTcmallocHeapProfile( | |
| 152 GetFilePath(base::GetProcId(it.GetCurrentValue()->GetHandle())))); | |
| 153 break; | |
| 154 default: | |
| 155 NOTREACHED(); | |
| 156 } | |
| 157 } | |
| 158 #endif | |
| 159 } | |
| 160 | |
| 161 void MemoryMenuButton::ExecuteCommand(int id) { | 99 void MemoryMenuButton::ExecuteCommand(int id) { |
| 162 switch (id) { | 100 switch (id) { |
| 163 case PURGE_MEMORY_ITEM: | 101 case PURGE_MEMORY_ITEM: |
| 164 MemoryPurger::PurgeAll(); | 102 MemoryPurger::PurgeAll(); |
| 165 break; | 103 break; |
| 166 #if defined(USE_TCMALLOC) | |
| 167 case TOGGLE_PROFILING_ITEM: { | |
| 168 if (!IsHeapProfilerRunning()) | |
| 169 HeapProfilerStart(kProfileDumpFilePrefix); | |
| 170 else | |
| 171 HeapProfilerStop(); | |
| 172 SendCommandToRenderers(id); | |
| 173 break; | |
| 174 } | |
| 175 case DUMP_PROFILING_ITEM: { | |
| 176 char* profile = GetHeapProfile(); | |
| 177 if (profile) { | |
| 178 FilePath::StringType filepath = | |
| 179 GetFilePath(base::GetProcId(base::GetCurrentProcId())); | |
| 180 VLOG(0) << "Writing browser heap profile dump to: " << filepath; | |
| 181 file_util::WriteFile(FilePath(filepath), profile, strlen(profile)); | |
| 182 delete profile; | |
| 183 } | |
| 184 SendCommandToRenderers(id); | |
| 185 break; | |
| 186 } | |
| 187 #endif | |
| 188 default: | 104 default: |
| 189 NOTREACHED(); | 105 NOTREACHED(); |
| 190 break; | 106 break; |
| 191 } | 107 } |
| 192 } | 108 } |
| 193 | 109 |
| 194 int MemoryMenuButton::horizontal_padding() { | 110 int MemoryMenuButton::horizontal_padding() { |
| 195 return 3; | 111 return 3; |
| 196 } | 112 } |
| 197 | 113 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 218 | 134 |
| 219 void MemoryMenuButton::EnsureMenu() { | 135 void MemoryMenuButton::EnsureMenu() { |
| 220 // Just rebuild the menu each time to ensure the labels are up-to-date. | 136 // Just rebuild the menu each time to ensure the labels are up-to-date. |
| 221 menu_.reset(new views::MenuItemView(this)); | 137 menu_.reset(new views::MenuItemView(this)); |
| 222 // Text for these items will be set by GetLabel(). | 138 // Text for these items will be set by GetLabel(). |
| 223 menu_->AppendDelegateMenuItem(MEM_TOTAL_ITEM); | 139 menu_->AppendDelegateMenuItem(MEM_TOTAL_ITEM); |
| 224 menu_->AppendDelegateMenuItem(MEM_FREE_ITEM); | 140 menu_->AppendDelegateMenuItem(MEM_FREE_ITEM); |
| 225 menu_->AppendDelegateMenuItem(MEM_BUFFERS_ITEM); | 141 menu_->AppendDelegateMenuItem(MEM_BUFFERS_ITEM); |
| 226 menu_->AppendDelegateMenuItem(MEM_CACHE_ITEM); | 142 menu_->AppendDelegateMenuItem(MEM_CACHE_ITEM); |
| 227 menu_->AppendDelegateMenuItem(SHMEM_ITEM); | 143 menu_->AppendDelegateMenuItem(SHMEM_ITEM); |
| 144 // TODO(jamescook): Dump heap profiles? |
| 228 menu_->AppendSeparator(); | 145 menu_->AppendSeparator(); |
| 229 menu_->AppendDelegateMenuItem(PURGE_MEMORY_ITEM); | 146 menu_->AppendDelegateMenuItem(PURGE_MEMORY_ITEM); |
| 230 #if defined(USE_TCMALLOC) | |
| 231 menu_->AppendSeparator(); | |
| 232 menu_->AppendDelegateMenuItem(TOGGLE_PROFILING_ITEM); | |
| 233 if (IsHeapProfilerRunning()) | |
| 234 menu_->AppendDelegateMenuItem(DUMP_PROFILING_ITEM); | |
| 235 #endif | |
| 236 } | 147 } |
| 237 | 148 |
| 238 } // namespace chromeos | 149 } // namespace chromeos |
| OLD | NEW |