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 18 using namespace lldb_perf; 19 20 MemoryStats::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 29 MemoryStats::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 37 MemoryStats& 38 MemoryStats::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 49 MemoryStats& 50 MemoryStats::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 58 MemoryStats 59 MemoryStats::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 66 MemoryStats 67 MemoryStats::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 74 MemoryStats 75 MemoryStats::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 84 MemoryStats 85 MemoryStats::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 92 Results::ResultSP 93 MemoryStats::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 101 MemoryGauge::ValueType 102 MemoryGauge::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 114 MemoryGauge::MemoryGauge () : 115 m_state(MemoryGauge::State::eNeverUsed), 116 m_start(), 117 m_delta() 118 { 119 } 120 121 void 122 MemoryGauge::Start () 123 { 124 m_state = MemoryGauge::State::eCounting; 125 m_start = Now(); 126 } 127 128 MemoryGauge::ValueType 129 MemoryGauge::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 139 MemoryGauge::ValueType 140 MemoryGauge::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 146 template <> 147 Results::ResultSP 148 lldb_perf::GetResult (const char *description, MemoryStats value) 149 { 150 return value.GetResult (NULL, description); 151 } 152 153 MemoryStats 154 sqrt (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