Home | History | Annotate | Download | only in lib
      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