1//===-- MemoryGauge.cpp -----------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "MemoryGauge.h" 11#include "lldb/lldb-forward.h" 12#include <assert.h> 13#include <cmath> 14#include <mach/mach.h> 15#include <mach/task.h> 16#include <mach/mach_traps.h> 17 18using namespace lldb_perf; 19 20MemoryStats::MemoryStats (mach_vm_size_t virtual_size, 21 mach_vm_size_t resident_size, 22 mach_vm_size_t max_resident_size) : 23 m_virtual_size (virtual_size), 24 m_resident_size (resident_size), 25 m_max_resident_size (max_resident_size) 26{ 27} 28 29MemoryStats::MemoryStats (const MemoryStats& rhs) : 30 m_virtual_size (rhs.m_virtual_size), 31 m_resident_size (rhs.m_resident_size), 32 m_max_resident_size (rhs.m_max_resident_size) 33{ 34} 35 36 37MemoryStats& 38MemoryStats::operator = (const MemoryStats& rhs) 39{ 40 if (this != &rhs) 41 { 42 m_virtual_size = rhs.m_virtual_size; 43 m_resident_size = rhs.m_resident_size; 44 m_max_resident_size = rhs.m_max_resident_size; 45 } 46 return *this; 47} 48 49MemoryStats& 50MemoryStats::operator += (const MemoryStats& rhs) 51{ 52 m_virtual_size += rhs.m_virtual_size; 53 m_resident_size += rhs.m_resident_size; 54 m_max_resident_size += rhs.m_max_resident_size; 55 return *this; 56} 57 58MemoryStats 59MemoryStats::operator - (const MemoryStats& rhs) 60{ 61 return MemoryStats(m_virtual_size - rhs.m_virtual_size, 62 m_resident_size - rhs.m_resident_size, 63 m_max_resident_size - rhs.m_max_resident_size); 64} 65 66MemoryStats 67MemoryStats::operator + (const MemoryStats& rhs) 68{ 69 return MemoryStats(m_virtual_size + rhs.m_virtual_size, 70 m_resident_size + rhs.m_resident_size, 71 m_max_resident_size + rhs.m_max_resident_size); 72} 73 74MemoryStats 75MemoryStats::operator / (size_t n) 76{ 77 MemoryStats result(*this); 78 result.m_virtual_size /= n; 79 result.m_resident_size /= n; 80 result.m_max_resident_size /= n; 81 return result; 82} 83 84MemoryStats 85MemoryStats::operator * (const MemoryStats& rhs) 86{ 87 return MemoryStats(m_virtual_size * rhs.m_virtual_size, 88 m_resident_size * rhs.m_resident_size, 89 m_max_resident_size * rhs.m_max_resident_size); 90} 91 92Results::ResultSP 93MemoryStats::GetResult (const char *name, const char *description) const 94{ 95 std::unique_ptr<Results::Dictionary> dict_ap (new Results::Dictionary (name, NULL)); 96 dict_ap->AddUnsigned("resident", NULL, GetResidentSize()); 97 dict_ap->AddUnsigned("max_resident", NULL, GetMaxResidentSize()); 98 return Results::ResultSP(dict_ap.release()); 99} 100 101MemoryGauge::ValueType 102MemoryGauge::Now () 103{ 104 task_t task = mach_task_self(); 105 mach_task_basic_info_data_t taskBasicInfo; 106 mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT; 107 auto task_info_ret = task_info(task, MACH_TASK_BASIC_INFO, (task_info_t) & taskBasicInfo, &count); 108 if (task_info_ret == KERN_SUCCESS) { 109 return MemoryStats(taskBasicInfo.virtual_size, taskBasicInfo.resident_size, taskBasicInfo.resident_size_max); 110 } 111 return 0; 112} 113 114MemoryGauge::MemoryGauge () : 115 m_state(MemoryGauge::State::eNeverUsed), 116 m_start(), 117 m_delta() 118{ 119} 120 121void 122MemoryGauge::Start () 123{ 124 m_state = MemoryGauge::State::eCounting; 125 m_start = Now(); 126} 127 128MemoryGauge::ValueType 129MemoryGauge::Stop () 130{ 131 m_stop = Now(); 132 assert(m_state == MemoryGauge::State::eCounting && "cannot stop a non-started gauge"); 133 m_state = MemoryGauge::State::eStopped; 134 m_delta = m_stop - m_start; 135 return m_delta; 136} 137 138 139MemoryGauge::ValueType 140MemoryGauge::GetDeltaValue () const 141{ 142 assert(m_state == MemoryGauge::State::eStopped && "gauge must be used before you can evaluate it"); 143 return m_delta; 144} 145 146template <> 147Results::ResultSP 148lldb_perf::GetResult (const char *description, MemoryStats value) 149{ 150 return value.GetResult (NULL, description); 151} 152 153MemoryStats 154sqrt (const MemoryStats& arg) 155{ 156 long double virt_size = arg.GetVirtualSize(); 157 long double resident_size = arg.GetResidentSize(); 158 long double max_resident_size = arg.GetMaxResidentSize(); 159 160 virt_size = sqrtl(virt_size); 161 resident_size = sqrtl(resident_size); 162 max_resident_size = sqrtl(max_resident_size); 163 164 return MemoryStats(virt_size,resident_size,max_resident_size); 165} 166