MemoryGauge.cpp revision 0b10ef61ea60e24fe7736cd98bd5fb45efe9c816
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