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
MemoryStats(mach_vm_size_t virtual_size,mach_vm_size_t resident_size,mach_vm_size_t max_resident_size)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
MemoryStats(const MemoryStats & rhs)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&
operator =(const MemoryStats & rhs)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&
operator +=(const MemoryStats & rhs)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
operator -(const MemoryStats & rhs)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
operator +(const MemoryStats & rhs)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
operator /(size_t n)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
operator *(const MemoryStats & rhs)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
GetResult(const char * name,const char * description) const93 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
Now()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
MemoryGauge()114 MemoryGauge::MemoryGauge () :
115 m_state(MemoryGauge::State::eNeverUsed),
116 m_start(),
117 m_delta()
118 {
119 }
120
121 void
Start()122 MemoryGauge::Start ()
123 {
124 m_state = MemoryGauge::State::eCounting;
125 m_start = Now();
126 }
127
128 MemoryGauge::ValueType
Stop()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
GetDeltaValue() const140 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
GetResult(const char * description,MemoryStats value)148 lldb_perf::GetResult (const char *description, MemoryStats value)
149 {
150 return value.GetResult (NULL, description);
151 }
152
153 MemoryStats
sqrt(const MemoryStats & arg)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