• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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