| Index: ios/chrome/browser/memory/memory_metrics.cc
|
| diff --git a/ios/chrome/browser/memory/memory_metrics.cc b/ios/chrome/browser/memory/memory_metrics.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..360c533f396221b3f8b5d072599a09895d2a625a
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/memory/memory_metrics.cc
|
| @@ -0,0 +1,89 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ios/chrome/browser/memory/memory_metrics.h"
|
| +
|
| +#include <mach/mach.h>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/process/process_handle.h"
|
| +#include "base/process/process_metrics.h"
|
| +
|
| +#ifdef ARCH_CPU_64_BITS
|
| +#define cr_vm_region vm_region_64
|
| +#else
|
| +#define cr_vm_region vm_region
|
| +#endif
|
| +
|
| +namespace {
|
| +// The number of pages returned by host_statistics and vm_region are a count
|
| +// of pages of 4096 bytes even when running on arm64 but the constants that
|
| +// are exposed (vm_page_size, VM_PAGE_SIZE, host_page_size) are all equals to
|
| +// 16384 bytes. So we define our own constant here to convert from page count
|
| +// to bytes.
|
| +const uint64_t kVMPageSize = 4096;
|
| +}
|
| +
|
| +namespace memory_util {
|
| +
|
| +uint64 GetFreePhysicalBytes() {
|
| + vm_statistics_data_t vmstat;
|
| + mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
|
| + kern_return_t result =
|
| + host_statistics(mach_host_self(), HOST_VM_INFO,
|
| + reinterpret_cast<host_info_t>(&vmstat), &count);
|
| + if (result != KERN_SUCCESS) {
|
| + LOG(ERROR) << "Calling host_statistics failed.";
|
| + return 0;
|
| + }
|
| + return vmstat.free_count * kVMPageSize;
|
| +}
|
| +
|
| +uint64 GetRealMemoryUsedInBytes() {
|
| + base::ProcessHandle process_handle = base::GetCurrentProcessHandle();
|
| + scoped_ptr<base::ProcessMetrics> process_metrics(
|
| + base::ProcessMetrics::CreateProcessMetrics(process_handle));
|
| + return static_cast<uint64>(process_metrics->GetWorkingSetSize());
|
| +}
|
| +
|
| +uint64 GetDirtyVMBytes() {
|
| + // Iterate over all VM regions and sum their dirty pages.
|
| + unsigned int total_dirty_pages = 0;
|
| + vm_size_t vm_size = 0;
|
| + kern_return_t result;
|
| + for (vm_address_t address = MACH_VM_MIN_ADDRESS;; address += vm_size) {
|
| + vm_region_extended_info_data_t info;
|
| + mach_msg_type_number_t info_count = VM_REGION_EXTENDED_INFO_COUNT;
|
| + mach_port_t object_name;
|
| + result = cr_vm_region(
|
| + mach_task_self(), &address, &vm_size, VM_REGION_EXTENDED_INFO,
|
| + reinterpret_cast<vm_region_info_t>(&info), &info_count, &object_name);
|
| + if (result == KERN_INVALID_ADDRESS) {
|
| + // The end of the address space has been reached.
|
| + break;
|
| + } else if (result != KERN_SUCCESS) {
|
| + LOG(ERROR) << "Calling vm_region failed with code: " << result;
|
| + break;
|
| + } else {
|
| + total_dirty_pages += info.pages_dirtied;
|
| + }
|
| + }
|
| + return total_dirty_pages * kVMPageSize;
|
| +}
|
| +
|
| +uint64 GetInternalVMBytes() {
|
| + task_vm_info_data_t task_vm_info;
|
| + mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
|
| + kern_return_t result =
|
| + task_info(mach_task_self(), TASK_VM_INFO,
|
| + reinterpret_cast<task_info_t>(&task_vm_info), &count);
|
| + if (result != KERN_SUCCESS) {
|
| + LOG(ERROR) << "Calling task_info failed.";
|
| + return 0;
|
| + }
|
| +
|
| + return static_cast<uint64>(task_vm_info.internal);
|
| +}
|
| +
|
| +} // namespace memory_util
|
|
|