| //===-- MemoryGauge.cpp -----------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "MemoryGauge.h" |
| #include "lldb/lldb-forward.h" |
| #include <assert.h> |
| #include <cmath> |
| #include <mach/mach.h> |
| #include <mach/mach_traps.h> |
| #include <mach/task.h> |
| |
| using namespace lldb_perf; |
| |
| MemoryStats::MemoryStats(mach_vm_size_t virtual_size, |
| mach_vm_size_t resident_size, |
| mach_vm_size_t max_resident_size) |
| : m_virtual_size(virtual_size), m_resident_size(resident_size), |
| m_max_resident_size(max_resident_size) {} |
| |
| MemoryStats::MemoryStats(const MemoryStats &rhs) |
| : m_virtual_size(rhs.m_virtual_size), m_resident_size(rhs.m_resident_size), |
| m_max_resident_size(rhs.m_max_resident_size) {} |
| |
| MemoryStats &MemoryStats::operator=(const MemoryStats &rhs) { |
| if (this != &rhs) { |
| m_virtual_size = rhs.m_virtual_size; |
| m_resident_size = rhs.m_resident_size; |
| m_max_resident_size = rhs.m_max_resident_size; |
| } |
| return *this; |
| } |
| |
| MemoryStats &MemoryStats::operator+=(const MemoryStats &rhs) { |
| m_virtual_size += rhs.m_virtual_size; |
| m_resident_size += rhs.m_resident_size; |
| m_max_resident_size += rhs.m_max_resident_size; |
| return *this; |
| } |
| |
| MemoryStats MemoryStats::operator-(const MemoryStats &rhs) { |
| return MemoryStats(m_virtual_size - rhs.m_virtual_size, |
| m_resident_size - rhs.m_resident_size, |
| m_max_resident_size - rhs.m_max_resident_size); |
| } |
| |
| MemoryStats MemoryStats::operator+(const MemoryStats &rhs) { |
| return MemoryStats(m_virtual_size + rhs.m_virtual_size, |
| m_resident_size + rhs.m_resident_size, |
| m_max_resident_size + rhs.m_max_resident_size); |
| } |
| |
| MemoryStats MemoryStats::operator/(size_t n) { |
| MemoryStats result(*this); |
| result.m_virtual_size /= n; |
| result.m_resident_size /= n; |
| result.m_max_resident_size /= n; |
| return result; |
| } |
| |
| MemoryStats MemoryStats::operator*(const MemoryStats &rhs) { |
| return MemoryStats(m_virtual_size * rhs.m_virtual_size, |
| m_resident_size * rhs.m_resident_size, |
| m_max_resident_size * rhs.m_max_resident_size); |
| } |
| |
| Results::ResultSP MemoryStats::GetResult(const char *name, |
| const char *description) const { |
| std::unique_ptr<Results::Dictionary> dict_ap( |
| new Results::Dictionary(name, NULL)); |
| dict_ap->AddUnsigned("resident", NULL, GetResidentSize()); |
| dict_ap->AddUnsigned("max_resident", NULL, GetMaxResidentSize()); |
| return Results::ResultSP(dict_ap.release()); |
| } |
| |
| MemoryGauge::ValueType MemoryGauge::Now() { |
| task_t task = mach_task_self(); |
| mach_task_basic_info_data_t taskBasicInfo; |
| mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT; |
| auto task_info_ret = task_info(task, MACH_TASK_BASIC_INFO, |
| (task_info_t)&taskBasicInfo, &count); |
| if (task_info_ret == KERN_SUCCESS) { |
| return MemoryStats(taskBasicInfo.virtual_size, taskBasicInfo.resident_size, |
| taskBasicInfo.resident_size_max); |
| } |
| return 0; |
| } |
| |
| MemoryGauge::MemoryGauge() |
| : m_state(MemoryGauge::State::eNeverUsed), m_start(), m_delta() {} |
| |
| void MemoryGauge::Start() { |
| m_state = MemoryGauge::State::eCounting; |
| m_start = Now(); |
| } |
| |
| MemoryGauge::ValueType MemoryGauge::Stop() { |
| m_stop = Now(); |
| assert(m_state == MemoryGauge::State::eCounting && |
| "cannot stop a non-started gauge"); |
| m_state = MemoryGauge::State::eStopped; |
| m_delta = m_stop - m_start; |
| return m_delta; |
| } |
| |
| MemoryGauge::ValueType MemoryGauge::GetDeltaValue() const { |
| assert(m_state == MemoryGauge::State::eStopped && |
| "gauge must be used before you can evaluate it"); |
| return m_delta; |
| } |
| |
| template <> |
| Results::ResultSP lldb_perf::GetResult(const char *description, |
| MemoryStats value) { |
| return value.GetResult(NULL, description); |
| } |
| |
| MemoryStats sqrt(const MemoryStats &arg) { |
| long double virt_size = arg.GetVirtualSize(); |
| long double resident_size = arg.GetResidentSize(); |
| long double max_resident_size = arg.GetMaxResidentSize(); |
| |
| virt_size = sqrtl(virt_size); |
| resident_size = sqrtl(resident_size); |
| max_resident_size = sqrtl(max_resident_size); |
| |
| return MemoryStats(virt_size, resident_size, max_resident_size); |
| } |