OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ios/chrome/browser/memory/memory_metrics.h" |
| 6 |
| 7 #include <mach/mach.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "base/process/process_handle.h" |
| 11 #include "base/process/process_metrics.h" |
| 12 |
| 13 #ifdef ARCH_CPU_64_BITS |
| 14 #define cr_vm_region vm_region_64 |
| 15 #else |
| 16 #define cr_vm_region vm_region |
| 17 #endif |
| 18 |
| 19 namespace { |
| 20 // The number of pages returned by host_statistics and vm_region are a count |
| 21 // of pages of 4096 bytes even when running on arm64 but the constants that |
| 22 // are exposed (vm_page_size, VM_PAGE_SIZE, host_page_size) are all equals to |
| 23 // 16384 bytes. So we define our own constant here to convert from page count |
| 24 // to bytes. |
| 25 const uint64_t kVMPageSize = 4096; |
| 26 } |
| 27 |
| 28 namespace memory_util { |
| 29 |
| 30 uint64 GetFreePhysicalBytes() { |
| 31 vm_statistics_data_t vmstat; |
| 32 mach_msg_type_number_t count = HOST_VM_INFO_COUNT; |
| 33 kern_return_t result = |
| 34 host_statistics(mach_host_self(), HOST_VM_INFO, |
| 35 reinterpret_cast<host_info_t>(&vmstat), &count); |
| 36 if (result != KERN_SUCCESS) { |
| 37 LOG(ERROR) << "Calling host_statistics failed."; |
| 38 return 0; |
| 39 } |
| 40 return vmstat.free_count * kVMPageSize; |
| 41 } |
| 42 |
| 43 uint64 GetRealMemoryUsedInBytes() { |
| 44 base::ProcessHandle process_handle = base::GetCurrentProcessHandle(); |
| 45 scoped_ptr<base::ProcessMetrics> process_metrics( |
| 46 base::ProcessMetrics::CreateProcessMetrics(process_handle)); |
| 47 return static_cast<uint64>(process_metrics->GetWorkingSetSize()); |
| 48 } |
| 49 |
| 50 uint64 GetDirtyVMBytes() { |
| 51 // Iterate over all VM regions and sum their dirty pages. |
| 52 unsigned int total_dirty_pages = 0; |
| 53 vm_size_t vm_size = 0; |
| 54 kern_return_t result; |
| 55 for (vm_address_t address = MACH_VM_MIN_ADDRESS;; address += vm_size) { |
| 56 vm_region_extended_info_data_t info; |
| 57 mach_msg_type_number_t info_count = VM_REGION_EXTENDED_INFO_COUNT; |
| 58 mach_port_t object_name; |
| 59 result = cr_vm_region( |
| 60 mach_task_self(), &address, &vm_size, VM_REGION_EXTENDED_INFO, |
| 61 reinterpret_cast<vm_region_info_t>(&info), &info_count, &object_name); |
| 62 if (result == KERN_INVALID_ADDRESS) { |
| 63 // The end of the address space has been reached. |
| 64 break; |
| 65 } else if (result != KERN_SUCCESS) { |
| 66 LOG(ERROR) << "Calling vm_region failed with code: " << result; |
| 67 break; |
| 68 } else { |
| 69 total_dirty_pages += info.pages_dirtied; |
| 70 } |
| 71 } |
| 72 return total_dirty_pages * kVMPageSize; |
| 73 } |
| 74 |
| 75 uint64 GetInternalVMBytes() { |
| 76 task_vm_info_data_t task_vm_info; |
| 77 mach_msg_type_number_t count = TASK_VM_INFO_COUNT; |
| 78 kern_return_t result = |
| 79 task_info(mach_task_self(), TASK_VM_INFO, |
| 80 reinterpret_cast<task_info_t>(&task_vm_info), &count); |
| 81 if (result != KERN_SUCCESS) { |
| 82 LOG(ERROR) << "Calling task_info failed."; |
| 83 return 0; |
| 84 } |
| 85 |
| 86 return static_cast<uint64>(task_vm_info.internal); |
| 87 } |
| 88 |
| 89 } // namespace memory_util |
OLD | NEW |