Much more cleanup on the performance testing infrastructure:

- Added new abtract Results class to keep CoreFoundation out of the tests. There are many subclasses for different settings:
    Results::Result::Dictionary
    Results::Result::Array
    Results::Result::Unsigned
    Results::Result::Double
    Results::Result::String
- Gauge<T> can now write themselves out via a templatized write to results function:
    template <class T>
    Results::ResultSP GetResult (const char *description, T value);
  
- There are four specializations of this so far:
    template <>
    Results::ResultSP GetResult (const char *description, double value);

    template <>
    Results::ResultSP GetResult (const char *description, uint64_t value);

    template <>
    Results::ResultSP GetResult (const char *description, std::string value);

    template <>
    Results::ResultSP GetResult (const char *description, MemoryStats value);
- Don't emit the virtual memory reading from the task info call as it really doesn't mean much as it includes way too much (shared cache + other stuff we don't have control over)
- Fixed other test cases to build correctly and use the new classes

llvm-svn: 177696
This commit is contained in:
Greg Clayton 2013-03-22 02:31:35 +00:00
parent 0a9875abfe
commit 880afc5728
19 changed files with 1189 additions and 377 deletions

View File

@ -1,10 +1,26 @@
#!/bin/bash
mkdir llvm-build
if [ -d "llvm-build" ]; then
echo "Using existing 'llvm-build' directory..."
else
mkdir llvm-build
fi
cd llvm-build
svn co --revision 176809 http://llvm.org/svn/llvm-project/llvm/trunk llvm
( cd llvm/tools ; svn co --revision 176809 http://llvm.org/svn/llvm-project/cfe/trunk clang )
mkdir build
cd build
../llvm/configure --enable-targets=x86_64,arm --build=x86_64-apple-darwin10 --enable-optimized --disable-assertions
make -j8
if [ -d "llvm" ]; then
echo "Using existing 'llvm' directory..."
else
svn co --revision 176809 http://llvm.org/svn/llvm-project/llvm/trunk llvm
( cd llvm/tools ; svn co --revision 176809 http://llvm.org/svn/llvm-project/cfe/trunk clang )
fi
if [ ! -d "build" ]; then
mkdir build
cd build
../llvm/configure --enable-targets=x86_64,arm --build=x86_64-apple-darwin10 --disable-optimized --disable-assertions --enable-libcpp
make -j8 DEBUG_SYMBOLS=1
fi

View File

@ -7,14 +7,12 @@
//
//===----------------------------------------------------------------------===//
#include <CoreFoundation/CoreFoundation.h>
#include "lldb-perf/lib/Timer.h"
#include "lldb-perf/lib/Metric.h"
#include "lldb-perf/lib/Measurement.h"
#include "lldb-perf/lib/Results.h"
#include "lldb-perf/lib/TestCase.h"
#include "lldb-perf/lib/Xcode.h"
#include <iostream>
#include <unistd.h>
#include <fstream>
@ -24,11 +22,15 @@ using namespace lldb_perf;
class ClangTest : public TestCase
{
public:
ClangTest () : TestCase()
ClangTest () :
TestCase(),
m_set_bp_main_by_name(CreateTimeMeasurement([this] () -> void
{
m_target.BreakpointCreateByName("main");
m_target.BreakpointCreateByName("malloc");
}, "breakpoint1-relative-time", "Elapsed time to set a breakpoint at main by name, run and hit the breakpoint.")),
m_delta_memory("breakpoint1-memory-delta", "Memory increase that occurs due to setting a breakpoint at main by name.")
{
m_set_bp_main_by_name = CreateTimeMeasurement([this] () -> void {
m_target.BreakpointCreateByName("main");
}, "break at \"main\"", "time set a breakpoint at main by name, run and hit the breakpoint");
}
virtual
@ -39,13 +41,10 @@ public:
virtual bool
Setup (int argc, const char** argv)
{
SetVerbose(true);
m_app_path.assign(argv[1]);
m_out_path.assign(argv[2]);
m_target = m_debugger.CreateTarget(m_app_path.c_str());
m_set_bp_main_by_name();
const char *clang_argv[] = { "clang --version", NULL };
SBLaunchInfo launch_info(clang_argv);
return Launch (launch_info);
return true;
}
void
@ -59,71 +58,53 @@ public:
switch (counter)
{
case 0:
m_target.BreakpointCreateByLocation("fmts_tester.mm", 68);
next_action.Continue();
{
m_total_memory.Start();
m_target = m_debugger.CreateTarget(m_app_path.c_str());
const char *clang_argv[] = { "clang --version", NULL };
m_delta_memory.Start();
m_set_bp_main_by_name();
m_delta_memory.Stop();
SBLaunchInfo launch_info(clang_argv);
Launch (launch_info);
}
break;
case 1:
DoTest ();
next_action.Continue();
next_action.StepOver(m_thread);
break;
case 2:
DoTest ();
next_action.Continue();
next_action.StepOver(m_thread);
break;
case 3:
DoTest ();
next_action.Continue();
break;
case 4:
DoTest ();
next_action.Continue();
break;
case 5:
DoTest ();
next_action.Continue();
break;
case 6:
DoTest ();
next_action.Continue();
break;
case 7:
DoTest ();
next_action.Continue();
break;
case 8:
DoTest ();
next_action.Continue();
break;
case 9:
DoTest ();
next_action.Continue();
break;
case 10:
DoTest ();
next_action.Continue();
next_action.StepOver(m_thread);
break;
default:
m_total_memory.Stop();
next_action.Kill();
break;
}
}
void
Results ()
WriteResults (Results &results)
{
CFCMutableArray array;
m_set_bp_main_by_name.Write(array);
Results::Dictionary& results_dict = results.GetDictionary();
m_set_bp_main_by_name.WriteAverageValue(results);
m_delta_memory.WriteAverageValue(results);
CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, array.get(), kCFPropertyListXMLFormat_v1_0, 0, NULL);
results_dict.Add ("breakpoint1-memory-total",
"The total memory that the current process is using after setting the first breakpoint.",
m_total_memory.GetStopValue().GetResult(NULL, NULL));
CFURLRef file = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)m_out_path.c_str(), m_out_path.size(), FALSE);
CFURLWriteDataAndPropertiesToResource(file,xmlData,NULL,NULL);
results.Write(m_out_path.c_str());
}
private:
// C++ formatters
TimeMeasurement<std::function<void()>> m_set_bp_main_by_name;
MemoryMeasurement<std::function<void()>> m_delta_memory;
MemoryGauge m_total_memory;
std::string m_app_path;
std::string m_out_path;

View File

@ -22,7 +22,7 @@ public:
virtual
~StepTest() {}
virtual void
virtual bool
Setup (int argc, const char **argv)
{
m_app_path.assign(argv[1]);
@ -33,14 +33,29 @@ public:
const char* file_arg = m_app_path.c_str();
const char* empty = nullptr;
const char* args[] = {file_arg, empty};
SBLaunchInfo launch_info (args);
Launch (args,".");
return Launch (launch_info);
}
private:
void
DoOneStep (int sequence)
{
}
void
WriteResults (Results &results)
{
// results.Write(m_out_path.c_str());
}
private:
virtual void
TestStep (int counter, ActionWanted &next_action)
{
}
@ -61,7 +76,7 @@ int main(int argc, const char * argv[])
return -1;
}
StepTest skt;
TestCase::Run(skt,argc,argv);
StepTest test;
TestCase::Run(test,argc,argv);
return 0;
}

View File

@ -197,27 +197,21 @@ public:
}
}
void
Results ()
virtual void
WriteResults (Results &results)
{
CFCMutableArray array;
m_dump_std_vector_measurement.Write(array);
m_dump_std_list_measurement.Write(array);
m_dump_std_map_measurement.Write(array);
m_dump_std_string_measurement.Write(array);
m_dump_nsstring_measurement.Write(array);
m_dump_nsarray_measurement.Write(array);
m_dump_nsdictionary_measurement.Write(array);
m_dump_nsset_measurement.Write(array);
m_dump_nsbundle_measurement.Write(array);
m_dump_nsdate_measurement.Write(array);
CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, array.get(), kCFPropertyListXMLFormat_v1_0, 0, NULL);
m_dump_std_vector_measurement.WriteAverageValue(results);
m_dump_std_list_measurement.WriteAverageValue(results);
m_dump_std_map_measurement.WriteAverageValue(results);
m_dump_std_string_measurement.WriteAverageValue(results);
CFURLRef file = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)m_out_path.c_str(), m_out_path.size(), FALSE);
CFURLWriteDataAndPropertiesToResource(file,xmlData,NULL,NULL);
m_dump_nsstring_measurement.WriteAverageValue(results);
m_dump_nsarray_measurement.WriteAverageValue(results);
m_dump_nsdictionary_measurement.WriteAverageValue(results);
m_dump_nsset_measurement.WriteAverageValue(results);
m_dump_nsbundle_measurement.WriteAverageValue(results);
m_dump_nsdate_measurement.WriteAverageValue(results);
results.Write(m_out_path.c_str());
}
private:

View File

@ -179,21 +179,15 @@ public:
}
}
void
Results ()
virtual void
WriteResults (Results &results)
{
CFCMutableArray array;
m_fetch_frames_measurement.Write(array);
m_file_line_bp_measurement.Write(array);
m_fetch_modules_measurement.Write(array);
m_fetch_vars_measurement.Write(array);
m_run_expr_measurement.Write(array);
CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, array.get(), kCFPropertyListXMLFormat_v1_0, 0, NULL);
CFURLRef file = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)m_out_path.c_str(), m_out_path.size(), FALSE);
CFURLWriteDataAndPropertiesToResource(file,xmlData,NULL,NULL);
m_fetch_frames_measurement.WriteAverageValue(results);
m_file_line_bp_measurement.WriteAverageValue(results);
m_fetch_modules_measurement.WriteAverageValue(results);
m_fetch_vars_measurement.WriteAverageValue(results);
m_run_expr_measurement.WriteAverageValue(results);
results.Write(m_out_path.c_str());
}
private:

View File

@ -0,0 +1,52 @@
//===-- Gauge.cpp -----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Gauge.h"
template <>
lldb_perf::Results::ResultSP
lldb_perf::GetResult (const char *description, double value)
{
if (description && description[0])
{
std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
value_dict_ap->AddString("description", NULL, description);
value_dict_ap->AddDouble("value", NULL, value);
return Results::ResultSP (value_dict_ap.release());
}
return Results::ResultSP (new Results::Double (NULL, NULL, value));
}
template <>
lldb_perf::Results::ResultSP
lldb_perf::GetResult (const char *description, uint64_t value)
{
if (description && description[0])
{
std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
value_dict_ap->AddString("description", NULL, description);
value_dict_ap->AddUnsigned("value", NULL, value);
return Results::ResultSP (value_dict_ap.release());
}
return Results::ResultSP (new Results::Unsigned (NULL, NULL, value));
}
template <>
lldb_perf::Results::ResultSP
lldb_perf::GetResult (const char *description, std::string value)
{
if (description && description[0])
{
std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
value_dict_ap->AddString("description", NULL, description);
value_dict_ap->AddString("value", NULL, value.c_str());
return Results::ResultSP (value_dict_ap.release());
}
return Results::ResultSP (new Results::String (NULL, NULL, value.c_str()));
}

View File

@ -11,15 +11,20 @@
#define PerfTestDriver_Gauge_h
#include <functional>
#include <string>
#include "Results.h"
class CFCMutableDictionary;
namespace lldb_perf {
template <class TASizeType>
template <class T>
class Gauge
{
public:
typedef TASizeType SizeType;
public:
typedef T ValueType;
Gauge ()
{}
@ -30,22 +35,32 @@ public:
virtual void
Start () = 0;
virtual SizeType
virtual ValueType
Stop () = 0;
virtual SizeType
GetValue () = 0;
template <typename F, typename... Args>
SizeType
Measure (F f,Args... args)
{
Start();
f(args...);
return Stop();
}
virtual ValueType
GetStartValue () const = 0;
virtual ValueType
GetStopValue () const = 0;
virtual ValueType
GetDeltaValue () const = 0;
};
template <class T>
Results::ResultSP GetResult (const char *description, T value);
template <>
Results::ResultSP GetResult (const char *description, double value);
template <>
Results::ResultSP GetResult (const char *description, uint64_t value);
template <>
Results::ResultSP GetResult (const char *description, std::string value);
}
#endif

View File

@ -17,28 +17,35 @@
namespace lldb_perf
{
template <typename GaugeType, typename Action>
class Measurement : public WriteToPList
template <typename GaugeType, typename Callable>
class Measurement : public WriteResults
{
public:
Measurement () :
m_gauge (),
m_action (),
m_callable (),
m_metric ()
{
}
Measurement (Action act, const char* name = NULL, const char* desc = NULL) :
Measurement (Callable callable, const char* name, const char* desc) :
m_gauge (),
m_action (act),
m_metric (Metric<typename GaugeType::SizeType>(name, desc))
m_callable (callable),
m_metric (Metric<typename GaugeType::ValueType>(name, desc))
{
}
template <typename GaugeType_Rhs, typename Action_Rhs>
Measurement (const Measurement<GaugeType_Rhs, Action_Rhs>& rhs) :
Measurement (const char* name, const char* desc) :
m_gauge (),
m_callable (),
m_metric (Metric<typename GaugeType::ValueType>(name, desc))
{
}
template <typename GaugeType_Rhs, typename Callable_Rhs>
Measurement (const Measurement<GaugeType_Rhs, Callable_Rhs>& rhs) :
m_gauge(rhs.GetGauge()),
m_action(rhs.GetAction()),
m_callable(rhs.GetCallable()),
m_metric(rhs.GetMetric())
{
}
@ -47,13 +54,15 @@ public:
void
operator () (Args... args)
{
m_metric.Append (m_gauge.Measure(m_action, args...));
m_gauge.Start();
m_callable(args...);
m_metric.Append (m_gauge.Stop());
}
virtual const Action&
GetAction () const
virtual const Callable&
GetCallable () const
{
return m_action;
return m_callable;
}
virtual const GaugeType&
@ -62,7 +71,7 @@ public:
return m_gauge;
}
virtual const Metric<typename GaugeType::SizeType>&
virtual const Metric<typename GaugeType::ValueType>&
GetMetric () const
{
return m_metric;
@ -74,7 +83,7 @@ public:
m_gauge.Start();
}
typename GaugeType::SizeType
typename GaugeType::ValueType
Stop ()
{
auto value = m_gauge.Stop();
@ -83,42 +92,63 @@ public:
}
virtual void
Write (CFCMutableArray& parent)
Write (CFCMutableDictionary& parent)
{
m_metric.Write(parent);
}
void
WriteStartValue (Results &results)
{
auto metric = GetMetric ();
results.GetDictionary().Add(metric.GetName(), metric.GetDescription(), lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetStartValue()));
}
void
WriteStopValue (Results &results)
{
auto metric = GetMetric ();
results.GetDictionary().Add(metric.GetName(), metric.GetDescription(), lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetStopValue()));
}
void
WriteAverageValue (Results &results)
{
auto metric = GetMetric ();
results.GetDictionary().Add(metric.GetName(), metric.GetDescription(), lldb_perf::GetResult<typename GaugeType::ValueType> (NULL, metric.GetAverage()));
}
protected:
GaugeType m_gauge;
Action m_action;
Metric<typename GaugeType::SizeType> m_metric;
Callable m_callable;
Metric<typename GaugeType::ValueType> m_metric;
};
template <typename Action>
class TimeMeasurement : public Measurement<TimeGauge,Action>
template <typename Callable>
class TimeMeasurement : public Measurement<TimeGauge,Callable>
{
public:
TimeMeasurement () :
Measurement<TimeGauge,Action> ()
Measurement<TimeGauge,Callable> ()
{
}
TimeMeasurement (Action act,
TimeMeasurement (Callable callable,
const char* name = NULL,
const char* descr = NULL) :
Measurement<TimeGauge,Action> (act, name, descr)
Measurement<TimeGauge,Callable> (callable, name, descr)
{
}
template <typename Action_Rhs>
TimeMeasurement (const TimeMeasurement<Action_Rhs>& rhs) :
Measurement<TimeGauge,Action>(rhs)
template <typename Callable_Rhs>
TimeMeasurement (const TimeMeasurement<Callable_Rhs>& rhs) :
Measurement<TimeGauge,Callable>(rhs)
{
}
template <typename GaugeType_Rhs, typename Action_Rhs>
TimeMeasurement (const Measurement<GaugeType_Rhs, Action_Rhs>& rhs) :
Measurement<GaugeType_Rhs,Action_Rhs>(rhs)
template <typename GaugeType_Rhs, typename Callable_Rhs>
TimeMeasurement (const Measurement<GaugeType_Rhs, Callable_Rhs>& rhs) :
Measurement<GaugeType_Rhs,Callable_Rhs>(rhs)
{
}
@ -126,29 +156,39 @@ public:
void
operator () (Args... args)
{
Measurement<TimeGauge,Action>::operator()(args...);
Measurement<TimeGauge,Callable>::operator()(args...);
}
};
template <typename Action>
class MemoryMeasurement : public Measurement<MemoryGauge,Action>
template <typename Callable>
class MemoryMeasurement : public Measurement<MemoryGauge,Callable>
{
public:
MemoryMeasurement () : Measurement<MemoryGauge,Action> ()
MemoryMeasurement () : Measurement<MemoryGauge,Callable> ()
{
}
MemoryMeasurement (Action act, const char* name = NULL, const char* descr = NULL) : Measurement<MemoryGauge,Action> (act, name, descr)
MemoryMeasurement (Callable callable,
const char* name,
const char* descr) :
Measurement<MemoryGauge,Callable> (callable, name, descr)
{
}
MemoryMeasurement (const char* name, const char* descr) :
Measurement<MemoryGauge,Callable> (name, descr)
{
}
template <typename Callable_Rhs>
MemoryMeasurement (const MemoryMeasurement<Callable_Rhs>& rhs) :
Measurement<MemoryGauge,Callable>(rhs)
{
}
template <typename Action_Rhs>
MemoryMeasurement (const MemoryMeasurement<Action_Rhs>& rhs) : Measurement<MemoryGauge,Action>(rhs)
{
}
template <typename GaugeType_Rhs, typename Action_Rhs>
MemoryMeasurement (const Measurement<GaugeType_Rhs, Action_Rhs>& rhs) : Measurement<GaugeType_Rhs,Action_Rhs>(rhs)
template <typename GaugeType_Rhs, typename Callable_Rhs>
MemoryMeasurement (const Measurement<GaugeType_Rhs, Callable_Rhs>& rhs) :
Measurement<GaugeType_Rhs,Callable_Rhs>(rhs)
{
}
@ -156,7 +196,7 @@ public:
void
operator () (Args... args)
{
Measurement<MemoryGauge,Action>::operator()(args...);
Measurement<MemoryGauge,Callable>::operator()(args...);
}
};

View File

@ -70,7 +70,16 @@ MemoryStats::operator / (size_t n)
return *this;
}
MemoryGauge::SizeType
Results::ResultSP
MemoryStats::GetResult (const char *name, const char *description) const
{
std::unique_ptr<Results::Dictionary> dict_ap (new Results::Dictionary (name, NULL));
dict_ap->AddUnsigned("resident", NULL, GetResidentSize());
dict_ap->AddUnsigned("max_resident", NULL, GetMaxResidentSize());
return Results::ResultSP(dict_ap.release());
}
MemoryGauge::ValueType
MemoryGauge::Now ()
{
task_t task = mach_task_self();
@ -84,8 +93,9 @@ MemoryGauge::Now ()
}
MemoryGauge::MemoryGauge () :
m_state(MemoryGauge::State::eNeverUsed),
m_start(),
m_state(MemoryGauge::State::eNeverUsed)
m_delta()
{
}
@ -96,18 +106,27 @@ MemoryGauge::Start ()
m_start = Now();
}
MemoryGauge::SizeType
MemoryGauge::ValueType
MemoryGauge::Stop ()
{
auto stop = Now();
m_stop = Now();
assert(m_state == MemoryGauge::State::eCounting && "cannot stop a non-started gauge");
m_state = MemoryGauge::State::eStopped;
return (m_value = stop-m_start);
m_delta = m_stop - m_start;
return m_delta;
}
MemoryGauge::SizeType
MemoryGauge::GetValue ()
MemoryGauge::ValueType
MemoryGauge::GetDeltaValue () const
{
assert(m_state == MemoryGauge::State::eStopped && "gauge must be used before you can evaluate it");
return m_value;
return m_delta;
}
template <>
Results::ResultSP
lldb_perf::GetResult (const char *description, MemoryStats value)
{
return value.GetResult (NULL, description);
}

View File

@ -11,11 +11,12 @@
#define __PerfTestDriver__MemoryGauge__
#include "Gauge.h"
#include "Results.h"
#include <mach/task_info.h>
namespace lldb_perf
{
namespace lldb_perf {
class MemoryStats
{
public:
@ -37,19 +38,19 @@ public:
operator / (size_t rhs);
mach_vm_size_t
GetVirtualSize ()
GetVirtualSize () const
{
return m_virtual_size;
}
mach_vm_size_t
GetResidentSize ()
GetResidentSize () const
{
return m_resident_size;
}
mach_vm_size_t
GetMaxResidentSize ()
GetMaxResidentSize () const
{
return m_max_resident_size;
}
@ -72,6 +73,8 @@ public:
m_max_resident_size = mrs;
}
Results::ResultSP
GetResult (const char *name, const char *description) const;
private:
mach_vm_size_t m_virtual_size;
mach_vm_size_t m_resident_size;
@ -91,11 +94,23 @@ public:
void
Start ();
SizeType
ValueType
Stop ();
SizeType
GetValue ();
virtual ValueType
GetStartValue() const
{
return m_start;
}
virtual ValueType
GetStopValue() const
{
return m_stop;
}
virtual ValueType
GetDeltaValue() const;
private:
enum class State
@ -105,14 +120,19 @@ private:
eStopped
};
SizeType
ValueType
Now ();
SizeType m_start;
State m_state;
SizeType m_value;
ValueType m_start;
ValueType m_stop;
ValueType m_delta;
};
}
#endif /* defined(__PerfTestDriver__MemoryGauge__) */
template <>
Results::ResultSP
GetResult (const char *description, MemoryStats value);
} // namespace lldb_perf
#endif // #ifndef __PerfTestDriver__MemoryGauge__

View File

@ -18,14 +18,16 @@ using namespace lldb_perf;
template <class T>
Metric<T>::Metric () : Metric ("")
{}
{
}
template <class T>
Metric<T>::Metric (const char* n, const char* d) :
m_name(n ? n : ""),
m_description(d ? d : ""),
m_dataset ()
{}
m_name(n ? n : ""),
m_description(d ? d : ""),
m_dataset ()
{
}
template <class T>
void
@ -59,32 +61,32 @@ Metric<T>::GetAverage () const
}
template <>
void Metric<double>::WriteImpl (CFCMutableArray& parent, identity<double>)
void Metric<double>::WriteImpl (CFCMutableDictionary& parent_dict, const char *name, const char *description, double value)
{
assert(name && name[0]);
CFCMutableDictionary dict;
dict.AddValueCString(CFCString("name").get(), GetName(), true);
dict.AddValueCString(CFCString("description").get(),GetDescription(), true);
dict.AddValueDouble(CFCString("value").get(),this->GetAverage(), true);
parent.AppendValue(dict.get(), true);
if (description && description[0])
dict.AddValueCString(CFCString("description").get(),description, true);
dict.AddValueDouble(CFCString("value").get(),value, true);
parent_dict.AddValue(CFCString(name).get(), dict.get(), true);
}
template <>
void Metric<MemoryStats>::WriteImpl (CFCMutableArray& parent, identity<MemoryStats>)
void Metric<MemoryStats>::WriteImpl (CFCMutableDictionary& parent_dict, const char *name, const char *description, MemoryStats value)
{
CFCMutableDictionary dict;
dict.AddValueCString(CFCString("name").get(), GetName(), true);
dict.AddValueCString(CFCString("description").get(), GetDescription(), true);
CFCMutableDictionary value;
if (description && description[0])
dict.AddValueCString(CFCString("description").get(),description, true);
CFCMutableDictionary value_dict;
// don't write out the "virtual size", it doesn't mean anything useful as it includes
// all of the shared cache and many other things that make it way too big to be useful
//value_dict.AddValueUInt64(CFCString("virtual").get(), value.GetVirtualSize(), true);
value_dict.AddValueUInt64(CFCString("resident").get(), value.GetResidentSize(), true);
value_dict.AddValueUInt64(CFCString("max_resident").get(), value.GetMaxResidentSize(), true);
dict.AddValue(CFCString("value").get(),value_dict.get(), true);
auto avg = this->GetAverage();
value.AddValueUInt64(CFCString("virtual").get(), avg.GetVirtualSize(), true);
value.AddValueUInt64(CFCString("resident").get(), avg.GetResidentSize(), true);
value.AddValueUInt64(CFCString("max_resident").get(), avg.GetMaxResidentSize(), true);
dict.AddValue(CFCString("value").get(), value.get(), true);
parent.AppendValue(dict.get(), true);
parent_dict.AddValue(CFCString(name).get(), dict.get(), true);
}
template class lldb_perf::Metric<double>;

View File

@ -14,24 +14,24 @@
#include <string>
#include <mach/task_info.h>
#include "CFCMutableArray.h"
#include "CFCMutableDictionary.h"
namespace lldb_perf {
class MemoryStats;
class WriteToPList
class WriteResults
{
public:
virtual void
Write (CFCMutableArray& parent) = 0;
Write (CFCMutableDictionary& parent) = 0;
virtual
~WriteToPList () {}
~WriteResults () {}
};
template <class ValueType>
class Metric : public WriteToPList
class Metric : public WriteResults
{
public:
Metric ();
@ -50,32 +50,31 @@ public:
GetSum () const;
const char*
GetName ()
GetName () const
{
if (m_name.empty())
return NULL;
return m_name.c_str();
}
const char*
GetDescription ()
GetDescription () const
{
if (m_description.empty())
return NULL;
return m_description.c_str();
}
virtual void
Write (CFCMutableArray& parent)
Write (CFCMutableDictionary& parent)
{
WriteImpl(parent, identity<ValueType>());
WriteImpl(parent, GetName(), GetDescription(), GetAverage());
}
static void WriteImpl (CFCMutableDictionary& parent, const char *name, const char *description, double);
static void WriteImpl (CFCMutableDictionary& parent, const char *name, const char *description, MemoryStats);
private:
template<typename T>
struct identity { typedef T type; };
void WriteImpl (CFCMutableArray& parent, identity<double>);
void WriteImpl (CFCMutableArray& parent, identity<MemoryStats>);
std::string m_name;
std::string m_description;
std::vector<ValueType> m_dataset;

View File

@ -0,0 +1,267 @@
//===-- Results.cpp ---------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Results.h"
#include <assert.h>
#ifdef __APPLE__
#include "CFCMutableArray.h"
#include "CFCMutableDictionary.h"
#include "CFCReleaser.h"
#include "CFCString.h"
#endif
using namespace lldb_perf;
static void
AddResultToArray (CFCMutableArray &array, Results::Result *result);
static void
AddResultToDictionary (CFCMutableDictionary &parent_dict, const char *key, Results::Result *result);
static void
AddResultToArray (CFCMutableArray &parent_array, Results::Result *result)
{
switch (result->GetType())
{
case Results::Result::Type::Invalid:
break;
case Results::Result::Type::Array:
{
Results::Array *value = result->GetAsArray();
CFCMutableArray array;
value->ForEach([&array](const Results::ResultSP &value_sp) -> bool
{
AddResultToArray (array, value_sp.get());
return true;
});
parent_array.AppendValue(array.get(), true);
}
break;
case Results::Result::Type::Dictionary:
{
Results::Dictionary *value = result->GetAsDictionary();
CFCMutableDictionary dict;
value->ForEach([&dict](const std::string &key, const Results::ResultSP &value_sp) -> bool
{
AddResultToDictionary (dict, key.c_str(), value_sp.get());
return true;
});
if (result->GetDescription())
{
dict.AddValueCString(CFSTR("description"), result->GetDescription());
}
parent_array.AppendValue(dict.get(), true);
}
break;
case Results::Result::Type::Double:
{
double d = result->GetAsDouble()->GetValue();
CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &d));
if (cf_number.get())
parent_array.AppendValue(cf_number.get(), true);
}
break;
case Results::Result::Type::String:
{
CFCString cfstr (result->GetAsString()->GetValue());
if (cfstr.get())
parent_array.AppendValue(cfstr.get(), true);
}
break;
case Results::Result::Type::Unsigned:
{
uint64_t uval64 = result->GetAsUnsigned()->GetValue();
CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberSInt64Type, &uval64));
if (cf_number.get())
parent_array.AppendValue(cf_number.get(), true);
}
break;
default:
assert (!"unhandled result");
break;
}
}
static void
AddResultToDictionary (CFCMutableDictionary &parent_dict, const char *key, Results::Result *result)
{
assert (key && key[0]);
CFCString cf_key(key);
switch (result->GetType())
{
case Results::Result::Type::Invalid:
break;
case Results::Result::Type::Array:
{
Results::Array *value = result->GetAsArray();
CFCMutableArray array;
value->ForEach([&array](const Results::ResultSP &value_sp) -> bool
{
AddResultToArray (array, value_sp.get());
return true;
});
parent_dict.AddValue(cf_key.get(), array.get(), true);
}
break;
case Results::Result::Type::Dictionary:
{
Results::Dictionary *value = result->GetAsDictionary();
CFCMutableDictionary dict;
value->ForEach([&dict](const std::string &key, const Results::ResultSP &value_sp) -> bool
{
AddResultToDictionary (dict, key.c_str(), value_sp.get());
return true;
});
if (result->GetDescription())
{
dict.AddValueCString(CFSTR("description"), result->GetDescription());
}
parent_dict.AddValue(cf_key.get(), dict.get(), true);
}
break;
case Results::Result::Type::Double:
{
parent_dict.SetValueDouble(cf_key.get(), result->GetAsDouble()->GetValue(), true);
}
break;
case Results::Result::Type::String:
{
parent_dict.SetValueCString(cf_key.get(), result->GetAsString()->GetValue(), true);
}
break;
case Results::Result::Type::Unsigned:
{
parent_dict.SetValueUInt64 (cf_key.get(), result->GetAsUnsigned()->GetValue(), true);
}
break;
default:
assert (!"unhandled result");
break;
}
}
void
Results::Write (const char *out_path)
{
#ifdef __APPLE__
CFCMutableDictionary dict;
m_results.ForEach([&dict](const std::string &key, const ResultSP &value_sp) -> bool
{
AddResultToDictionary (dict, key.c_str(), value_sp.get());
return true;
});
CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, dict.get(), kCFPropertyListXMLFormat_v1_0, 0, NULL);
CFURLRef file = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)out_path, strlen(out_path), FALSE);
CFURLWriteDataAndPropertiesToResource(file, xmlData, NULL, NULL);
#endif
}
void
Results::Dictionary::AddUnsigned (const char *name, const char *description, uint64_t value)
{
assert (name && name[0]);
if (description && description[0])
{
std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
value_dict_ap->AddString("description", NULL, description);
value_dict_ap->AddUnsigned("value", NULL, value);
m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release());
}
else
m_dictionary[std::string(name)] = ResultSP (new Unsigned (name, description, value));
}
void
Results::Dictionary::AddDouble (const char *name, const char *description, double value)
{
assert (name && name[0]);
if (description && description[0])
{
std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
value_dict_ap->AddString("description", NULL, description);
value_dict_ap->AddDouble("value", NULL, value);
m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release());
}
else
m_dictionary[std::string(name)] = ResultSP (new Double (name, description, value));
}
void
Results::Dictionary::AddString (const char *name, const char *description, const char *value)
{
assert (name && name[0]);
if (description && description[0])
{
std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
value_dict_ap->AddString("description", NULL, description);
value_dict_ap->AddString("value", NULL, value);
m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release());
}
else
m_dictionary[std::string(name)] = ResultSP (new String (name, description, value));
}
void
Results::Dictionary::Add (const char *name, const char *description, const ResultSP &result_sp)
{
assert (name && name[0]);
if (description && description[0])
{
std::unique_ptr<Results::Dictionary> value_dict_ap (new Results::Dictionary ());
value_dict_ap->AddString("description", NULL, description);
value_dict_ap->Add("value", NULL, result_sp);
m_dictionary[std::string(name)] = ResultSP (value_dict_ap.release());
}
else
m_dictionary[std::string(name)] = result_sp;
}
void
Results::Dictionary::ForEach (const std::function <bool (const std::string &, const ResultSP &)> &callback)
{
collection::const_iterator pos, end = m_dictionary.end();
for (pos = m_dictionary.begin(); pos != end; ++pos)
{
if (callback (pos->first.c_str(), pos->second) == false)
return;
}
}
void
Results::Array::Append (const ResultSP &result_sp)
{
m_array.push_back (result_sp);
}
void
Results::Array::ForEach (const std::function <bool (const ResultSP &)> &callback)
{
collection::const_iterator pos, end = m_array.end();
for (pos = m_array.begin(); pos != end; ++pos)
{
if (callback (*pos) == false)
return;
}
}

View File

@ -0,0 +1,312 @@
//===-- Results.h -----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef __PerfTestDriver_Results_h__
#define __PerfTestDriver_Results_h__
#include <memory>
#include <map>
#include <string>
#include <vector>
namespace lldb_perf {
class Results
{
public:
class Array;
class Dictionary;
class Double;
class String;
class Unsigned;
class Result
{
public:
enum class Type
{
Invalid,
Array,
Dictionary,
Double,
String,
Unsigned
};
Result (Type type, const char *name, const char *description) :
m_name (),
m_description(),
m_type (type)
{
if (name && name[0])
m_name = name;
if (description && description[0])
m_description = description;
}
virtual
~Result()
{
}
virtual void
Write (Results &results) = 0;
Array *
GetAsArray ()
{
if (m_type == Type::Array)
return (Array *)this;
return NULL;
}
Dictionary *
GetAsDictionary ()
{
if (m_type == Type::Dictionary)
return (Dictionary *)this;
return NULL;
}
Double *
GetAsDouble ()
{
if (m_type == Type::Double)
return (Double *)this;
return NULL;
}
String *
GetAsString ()
{
if (m_type == Type::String)
return (String *)this;
return NULL;
}
Unsigned *
GetAsUnsigned ()
{
if (m_type == Type::Unsigned)
return (Unsigned *)this;
return NULL;
}
const char *
GetName() const
{
if (m_name.empty())
return NULL;
return m_name.c_str();
}
const char *
GetDescription() const
{
if (m_description.empty())
return NULL;
return m_description.c_str();
}
Type
GetType() const
{
return m_type;
}
protected:
std::string m_name;
std::string m_description;
Type m_type;
};
typedef std::shared_ptr<Result> ResultSP;
class Array : public Result
{
public:
Array (const char *name, const char *description) :
Result (Type::Array, name, description)
{
}
virtual
~Array()
{
}
void
Append (const ResultSP &result_sp);
void
ForEach (const std::function <bool (const ResultSP &)> &callback);
virtual void
Write (Results &results)
{
}
protected:
typedef std::vector<ResultSP> collection;
collection m_array;
};
class Dictionary : public Result
{
public:
Dictionary () :
Result (Type::Dictionary, NULL, NULL)
{
}
Dictionary (const char *name, const char *description) :
Result (Type::Dictionary, name, description)
{
}
virtual
~Dictionary()
{
}
virtual void
Write (Results &results)
{
}
void
ForEach (const std::function <bool (const std::string &, const ResultSP &)> &callback);
void
Add (const char *name, const char *description, const ResultSP &result_sp);
void
AddDouble (const char *name, const char *descriptiorn, double value);
void
AddUnsigned (const char *name, const char *description, uint64_t value);
void
AddString (const char *name, const char *description, const char *value);
protected:
typedef std::map<std::string, ResultSP> collection;
collection m_dictionary;
};
class String : public Result
{
public:
String (const char *name, const char *description, const char *value) :
Result (Type::String, name, description),
m_string ()
{
if (value && value[0])
m_string = value;
}
virtual
~String()
{
}
virtual void
Write (Results &results)
{
}
const char *
GetValue () const
{
return m_string.empty() ? NULL : m_string.c_str();
}
protected:
std::string m_string;
};
class Double : public Result
{
public:
Double (const char *name, const char *description, double value) :
Result (Type::Double, name, description),
m_double (value)
{
}
virtual
~Double()
{
}
virtual void
Write (Results &results)
{
}
double
GetValue () const
{
return m_double;
}
protected:
double m_double;
};
class Unsigned : public Result
{
public:
Unsigned (const char *name, const char *description, uint64_t value) :
Result (Type::Unsigned, name, description),
m_unsigned (value)
{
}
virtual
~Unsigned()
{
}
virtual void
Write (Results &results)
{
}
uint64_t
GetValue () const
{
return m_unsigned;
}
protected:
uint64_t m_unsigned;
};
Results () :
m_results ()
{
}
~Results()
{
}
Dictionary &
GetDictionary ()
{
return m_results;
}
void
Write (const char *path);
protected:
Dictionary m_results;
};
} // namespace lldb_perf
#endif // #ifndef __PerfTestDriver_Results_h__

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "TestCase.h"
#include "Results.h"
#include "Xcode.h"
using namespace lldb_perf;
@ -63,134 +64,167 @@ TestCase::GetVerbose ()
void
TestCase::Loop ()
{
SBEvent evt;
while (true)
{
m_listener.WaitForEvent (UINT32_MAX,evt);
StateType state = SBProcess::GetStateFromEvent (evt);
if (m_verbose)
printf("event = %s\n",SBDebugger::StateAsCString(state));
if (SBProcess::GetRestartedFromEvent(evt))
continue;
switch (state)
{
case eStateInvalid:
case eStateDetached:
case eStateCrashed:
case eStateUnloaded:
break;
case eStateExited:
return;
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateRunning:
case eStateStepping:
continue;
case eStateStopped:
case eStateSuspended:
{
bool fatal = false;
bool selected_thread = false;
for (auto thread_index = 0; thread_index < m_process.GetNumThreads(); thread_index++)
{
SBThread thread(m_process.GetThreadAtIndex(thread_index));
SBFrame frame(thread.GetFrameAtIndex(0));
bool select_thread = false;
StopReason stop_reason = thread.GetStopReason();
if (m_verbose) printf("tid = 0x%llx pc = 0x%llx ",thread.GetThreadID(),frame.GetPC());
switch (stop_reason)
{
case eStopReasonNone:
if (m_verbose) printf("none\n");
break;
case eStopReasonTrace:
select_thread = true;
if (m_verbose) printf("trace\n");
break;
case eStopReasonPlanComplete:
select_thread = true;
if (m_verbose) printf("plan complete\n");
break;
case eStopReasonThreadExiting:
if (m_verbose) printf("thread exiting\n");
break;
case eStopReasonExec:
if (m_verbose) printf("exec\n");
break;
case eStopReasonInvalid:
if (m_verbose) printf("invalid\n");
break;
case eStopReasonException:
select_thread = true;
if (m_verbose) printf("exception\n");
fatal = true;
break;
case eStopReasonBreakpoint:
select_thread = true;
if (m_verbose) printf("breakpoint id = %lld.%lld\n",thread.GetStopReasonDataAtIndex(0),thread.GetStopReasonDataAtIndex(1));
break;
case eStopReasonWatchpoint:
select_thread = true;
if (m_verbose) printf("watchpoint id = %lld\n",thread.GetStopReasonDataAtIndex(0));
break;
case eStopReasonSignal:
select_thread = true;
if (m_verbose) printf("signal %d\n",(int)thread.GetStopReasonDataAtIndex(0));
break;
}
if (select_thread && !selected_thread)
bool call_test_step = false;
if (m_process.IsValid())
{
SBEvent evt;
m_listener.WaitForEvent (UINT32_MAX, evt);
StateType state = SBProcess::GetStateFromEvent (evt);
if (m_verbose)
printf("event = %s\n",SBDebugger::StateAsCString(state));
if (SBProcess::GetRestartedFromEvent(evt))
continue;
switch (state)
{
case eStateInvalid:
case eStateDetached:
case eStateCrashed:
case eStateUnloaded:
break;
case eStateExited:
return;
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateRunning:
case eStateStepping:
continue;
case eStateStopped:
case eStateSuspended:
{
call_test_step = true;
bool fatal = false;
bool selected_thread = false;
for (auto thread_index = 0; thread_index < m_process.GetNumThreads(); thread_index++)
{
m_thread = thread;
selected_thread = m_process.SetSelectedThread(thread);
SBThread thread(m_process.GetThreadAtIndex(thread_index));
SBFrame frame(thread.GetFrameAtIndex(0));
bool select_thread = false;
StopReason stop_reason = thread.GetStopReason();
if (m_verbose) printf("tid = 0x%llx pc = 0x%llx ",thread.GetThreadID(),frame.GetPC());
switch (stop_reason)
{
case eStopReasonNone:
if (m_verbose)
printf("none\n");
break;
case eStopReasonTrace:
select_thread = true;
if (m_verbose)
printf("trace\n");
break;
case eStopReasonPlanComplete:
select_thread = true;
if (m_verbose)
printf("plan complete\n");
break;
case eStopReasonThreadExiting:
if (m_verbose)
printf("thread exiting\n");
break;
case eStopReasonExec:
if (m_verbose)
printf("exec\n");
break;
case eStopReasonInvalid:
if (m_verbose)
printf("invalid\n");
break;
case eStopReasonException:
select_thread = true;
if (m_verbose)
printf("exception\n");
fatal = true;
break;
case eStopReasonBreakpoint:
select_thread = true;
if (m_verbose)
printf("breakpoint id = %lld.%lld\n",thread.GetStopReasonDataAtIndex(0),thread.GetStopReasonDataAtIndex(1));
break;
case eStopReasonWatchpoint:
select_thread = true;
if (m_verbose)
printf("watchpoint id = %lld\n",thread.GetStopReasonDataAtIndex(0));
break;
case eStopReasonSignal:
select_thread = true;
if (m_verbose)
printf("signal %d\n",(int)thread.GetStopReasonDataAtIndex(0));
break;
}
if (select_thread && !selected_thread)
{
m_thread = thread;
selected_thread = m_process.SetSelectedThread(thread);
}
}
}
if (fatal)
{
if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
exit(1);
}
if (m_verbose)
printf("RUNNING STEP %d\n",m_step);
ActionWanted action;
TestStep(m_step, action);
m_step++;
SBError err;
switch (action.type)
{
case ActionWanted::Type::eContinue:
err = m_process.Continue();
break;
case ActionWanted::Type::eStepOut:
if (action.thread.IsValid() == false)
{
if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
if (m_verbose) printf("[finish invalid] I am gonna die at step %d\n",m_step);
exit(501);
}
m_process.SetSelectedThread(action.thread);
action.thread.StepOut();
break;
case ActionWanted::Type::eNext:
if (action.thread.IsValid() == false)
{
if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
if (m_verbose) printf("[next invalid] I am gonna die at step %d\n",m_step);
exit(500);
}
m_process.SetSelectedThread(action.thread);
action.thread.StepOver();
break;
case ActionWanted::Type::eKill:
if (m_verbose) printf("I want to die\n");
m_process.Kill();
return;
}
if (fatal)
{
if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
exit(1);
}
}
break;
}
}
else
{
call_test_step = true;
}
if (call_test_step)
{
if (m_verbose)
printf("RUNNING STEP %d\n",m_step);
ActionWanted action;
TestStep(m_step, action);
m_step++;
SBError err;
switch (action.type)
{
case ActionWanted::Type::eContinue:
err = m_process.Continue();
break;
case ActionWanted::Type::eStepOut:
if (action.thread.IsValid() == false)
{
if (m_verbose)
{
Xcode::RunCommand(m_debugger,"bt all",true);
printf("error: invalid thread for step out on step %d\n", m_step);
}
exit(501);
}
m_process.SetSelectedThread(action.thread);
action.thread.StepOut();
break;
case ActionWanted::Type::eStepOver:
if (action.thread.IsValid() == false)
{
if (m_verbose)
{
Xcode::RunCommand(m_debugger,"bt all",true);
printf("error: invalid thread for step over %d\n",m_step);
}
exit(500);
}
m_process.SetSelectedThread(action.thread);
action.thread.StepOver();
break;
case ActionWanted::Type::eKill:
if (m_verbose)
printf("kill\n");
m_process.Kill();
return;
}
}
}
if (GetVerbose()) printf("I am gonna die at step %d\n",m_step);
}
@ -200,6 +234,8 @@ TestCase::Run (TestCase& test, int argc, const char** argv)
if (test.Setup(argc, argv))
{
test.Loop();
test.Results();
Results results;
test.WriteResults(results);
}
}

View File

@ -13,8 +13,10 @@
#include "lldb/API/LLDB.h"
#include "Measurement.h"
namespace lldb_perf
{
namespace lldb_perf {
class Results;
class TestCase
{
public:
@ -24,7 +26,7 @@ public:
{
enum class Type
{
eNext,
eStepOver,
eContinue,
eStepOut,
eKill
@ -47,7 +49,7 @@ public:
void
StepOver (lldb::SBThread t)
{
type = Type::eNext;
type = Type::eStepOver;
thread = t;
}
@ -90,7 +92,7 @@ public:
GetVerbose ();
virtual void
Results () = 0;
WriteResults (Results &results) = 0;
template <typename G,typename A>
Measurement<G,A> CreateMeasurement (A a, const char* name = NULL, const char* description = NULL)

View File

@ -10,6 +10,9 @@
#include "Timer.h"
#include <assert.h>
#include "CFCMutableDictionary.h"
#include "CFCString.h"
using namespace lldb_perf;
TimeGauge::TimeType
@ -19,7 +22,7 @@ TimeGauge::Now ()
}
TimeGauge::TimeGauge () :
m_start(),
m_start(),
m_state(TimeGauge::State::eNeverUsed)
{
}
@ -34,15 +37,28 @@ TimeGauge::Start ()
double
TimeGauge::Stop ()
{
auto stop = Now();
m_stop = Now();
assert(m_state == TimeGauge::State::eCounting && "cannot stop a non-started clock");
m_state = TimeGauge::State::eStopped;
return (m_value = duration_cast<duration<double>>(stop-m_start).count());
m_delta = duration_cast<duration<double>>(m_stop-m_start).count();
return m_delta;
}
double
TimeGauge::GetValue ()
TimeGauge::GetStartValue () const
{
return (double)m_start.time_since_epoch().count() * (double)system_clock::period::num / (double)system_clock::period::den;
}
double
TimeGauge::GetStopValue () const
{
return (double)m_stop.time_since_epoch().count() * (double)system_clock::period::num / (double)system_clock::period::den;
}
double
TimeGauge::GetDeltaValue () const
{
assert(m_state == TimeGauge::State::eStopped && "clock must be used before you can evaluate it");
return m_value;
return m_delta;
}

View File

@ -20,22 +20,6 @@ namespace lldb_perf
{
class TimeGauge : public Gauge<double>
{
private:
enum class State
{
eNeverUsed,
eCounting,
eStopped
};
typedef high_resolution_clock::time_point TimeType;
TimeType m_start;
double m_value;
State m_state;
TimeType
Now ();
public:
TimeGauge ();
@ -50,8 +34,32 @@ public:
double
Stop ();
double
GetValue ();
virtual double
GetStartValue () const;
virtual double
GetStopValue () const;
virtual double
GetDeltaValue () const;
private:
enum class State
{
eNeverUsed,
eCounting,
eStopped
};
typedef high_resolution_clock::time_point TimeType;
TimeType m_start;
TimeType m_stop;
double m_delta;
State m_state;
TimeType
Now ();
};
}

View File

@ -28,6 +28,9 @@
26DBAD6316FA66DC008243D2 /* liblldbperf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E373916F4035D00FF10BB /* liblldbperf.a */; };
26DBAD6416FA66E0008243D2 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 264B3DE816F7E47600D1E7AB /* LLDB.framework */; };
26DBAD6516FA66EA008243D2 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E37DB16F7A03900FF10BB /* CoreFoundation.framework */; };
26DF762916FBCE7100B4CC2E /* Results.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DF762716FBCE7100B4CC2E /* Results.cpp */; };
26DF762A16FBCE7100B4CC2E /* Results.h in Headers */ = {isa = PBXBuildFile; fileRef = 26DF762816FBCE7100B4CC2E /* Results.h */; };
26DF764316FBF30E00B4CC2E /* Gauge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DF764216FBF30E00B4CC2E /* Gauge.cpp */; };
4C1E374E16F407C800FF10BB /* Gauge.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E374216F407C800FF10BB /* Gauge.h */; };
4C1E374F16F407C800FF10BB /* Measurement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E374316F407C800FF10BB /* Measurement.h */; };
4C1E375016F407C800FF10BB /* MemoryGauge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E374416F407C800FF10BB /* MemoryGauge.cpp */; };
@ -67,7 +70,6 @@
4CE3707516FB703B00BFD501 /* liblldbperf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E373916F4035D00FF10BB /* liblldbperf.a */; };
4CE3707616FB704300BFD501 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 264B3DE816F7E47600D1E7AB /* LLDB.framework */; };
4CE3707716FB704B00BFD501 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E37DB16F7A03900FF10BB /* CoreFoundation.framework */; };
4CE3708816FB70EB00BFD501 /* stepping-testcase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3708716FB70E100BFD501 /* stepping-testcase.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -201,6 +203,9 @@
26DBAD4816FA637D008243D2 /* build-clang.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-clang.sh"; sourceTree = "<group>"; };
26DBAD4916FA637D008243D2 /* lldb_perf_clang.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = lldb_perf_clang.cpp; sourceTree = "<group>"; };
26DBAD5916FA63B1008243D2 /* lldb-perf-clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-perf-clang"; sourceTree = BUILT_PRODUCTS_DIR; };
26DF762716FBCE7100B4CC2E /* Results.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Results.cpp; sourceTree = "<group>"; };
26DF762816FBCE7100B4CC2E /* Results.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Results.h; sourceTree = "<group>"; };
26DF764216FBF30E00B4CC2E /* Gauge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Gauge.cpp; sourceTree = "<group>"; };
4C1E373916F4035D00FF10BB /* liblldbperf.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblldbperf.a; sourceTree = BUILT_PRODUCTS_DIR; };
4C1E374216F407C800FF10BB /* Gauge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gauge.h; sourceTree = "<group>"; };
4C1E374316F407C800FF10BB /* Measurement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Measurement.h; sourceTree = "<group>"; };
@ -240,7 +245,7 @@
4C86C5C416F7A36A00844407 /* LLDB.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LLDB.framework; path = build/Debug/LLDB.framework; sourceTree = "<group>"; };
4C86C5C616F7A37800844407 /* LLDB.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LLDB.framework; path = build/Debug/LLDB.framework; sourceTree = "<group>"; };
4C86C5D116F7CC8900844407 /* format-tester */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "format-tester"; sourceTree = BUILT_PRODUCTS_DIR; };
4CE3705416FB6FA100BFD501 /* lldb-step-test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-step-test"; sourceTree = BUILT_PRODUCTS_DIR; };
4CE3705416FB6FA100BFD501 /* lldb-perf-step */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-perf-step"; sourceTree = BUILT_PRODUCTS_DIR; };
4CE3705616FB6FA100BFD501 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
4CE3705816FB6FA100BFD501 /* lldb_step_test.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = lldb_step_test.1; sourceTree = "<group>"; };
4CE3707216FB701000BFD501 /* lldb-perf-stepping.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lldb-perf-stepping.cpp"; path = "stepping/lldb-perf-stepping.cpp"; sourceTree = "<group>"; };
@ -356,7 +361,7 @@
4C1E37BA16F79E9D00FF10BB /* lldb-perf-formatters */,
4C86C5D116F7CC8900844407 /* format-tester */,
26DBAD5916FA63B1008243D2 /* lldb-perf-clang */,
4CE3705416FB6FA100BFD501 /* lldb-step-test */,
4CE3705416FB6FA100BFD501 /* lldb-perf-step */,
4CE3707C16FB70AD00BFD501 /* stepping-testcase */,
);
name = Products;
@ -366,11 +371,14 @@
isa = PBXGroup;
children = (
4C1E374216F407C800FF10BB /* Gauge.h */,
26DF764216FBF30E00B4CC2E /* Gauge.cpp */,
4C1E374316F407C800FF10BB /* Measurement.h */,
4C1E374416F407C800FF10BB /* MemoryGauge.cpp */,
4C1E374516F407C800FF10BB /* MemoryGauge.h */,
4C1E374616F407C800FF10BB /* Metric.cpp */,
4C1E374716F407C800FF10BB /* Metric.h */,
26DF762716FBCE7100B4CC2E /* Results.cpp */,
26DF762816FBCE7100B4CC2E /* Results.h */,
4C1E374816F407C800FF10BB /* TestCase.cpp */,
4C1E374916F407C800FF10BB /* TestCase.h */,
4C1E374A16F407C800FF10BB /* Timer.cpp */,
@ -493,6 +501,7 @@
buildActionMask = 2147483647;
files = (
4C1E375716F407C800FF10BB /* Timer.h in Headers */,
26DF762A16FBCE7100B4CC2E /* Results.h in Headers */,
4C1E378D16F40BB300FF10BB /* CFCMutableArray.h in Headers */,
4C1E374E16F407C800FF10BB /* Gauge.h in Headers */,
4C1E378716F40B9C00FF10BB /* CFCReleaser.h in Headers */,
@ -613,7 +622,7 @@
);
name = "lldb-perf-step";
productName = "lldb-step-test";
productReference = 4CE3705416FB6FA100BFD501 /* lldb-step-test */;
productReference = 4CE3705416FB6FA100BFD501 /* lldb-perf-step */;
productType = "com.apple.product-type.tool";
};
4CE3707B16FB70AD00BFD501 /* stepping-testcase */ = {
@ -742,11 +751,13 @@
4C1E375016F407C800FF10BB /* MemoryGauge.cpp in Sources */,
4C1E375416F407C800FF10BB /* TestCase.cpp in Sources */,
4C1E375816F407C800FF10BB /* Xcode.cpp in Sources */,
26DF762916FBCE7100B4CC2E /* Results.cpp in Sources */,
4C1E375216F407C800FF10BB /* Metric.cpp in Sources */,
4C1E375616F407C800FF10BB /* Timer.cpp in Sources */,
4C1E378616F40B9600FF10BB /* CFCMutableSet.cpp in Sources */,
4C1E378516F40B9200FF10BB /* CFCMutableDictionary.cpp in Sources */,
4C1E378816F40B9F00FF10BB /* CFCString.cpp in Sources */,
26DF764316FBF30E00B4CC2E /* Gauge.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -786,7 +797,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4CE3708816FB70EB00BFD501 /* stepping-testcase.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -850,6 +860,7 @@
"$(inherited)",
"$(SRCROOT)/../../build/Debug",
);
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@ -870,6 +881,7 @@
"$(inherited)",
"$(SRCROOT)/../../build/Debug",
);
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Debug";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
@ -962,6 +974,7 @@
"$(inherited)",
"$(SRCROOT)/../../build/Debug",
);
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@ -979,6 +992,7 @@
"$(inherited)",
"$(SRCROOT)/../../build/Debug",
);
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Debug";
PRODUCT_NAME = "$(TARGET_NAME)";
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../include $(SRCROOT)/../../source/Host/macosx/cfcpp $(SRCROOT)/../";
@ -992,6 +1006,7 @@
"$(inherited)",
"$(SRCROOT)/../../build/Debug",
);
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@ -1009,6 +1024,7 @@
"$(inherited)",
"$(SRCROOT)/../../build/Debug",
);
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Debug";
PRODUCT_NAME = "$(TARGET_NAME)";
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../ $(SRCROOT)/../../include/";
@ -1032,6 +1048,7 @@
4C86C5D816F7CC8900844407 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@ -1043,6 +1060,7 @@
4C86C5D916F7CC8900844407 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -1051,6 +1069,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@ -1058,6 +1077,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.9;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../ $(SRCROOT)/../../include/";
};
name = Debug;
};
@ -1065,9 +1085,11 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
MACOSX_DEPLOYMENT_TARGET = 10.9;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../ $(SRCROOT)/../../include/";
};
name = Release;
};
@ -1168,6 +1190,7 @@
4CE3705B16FB6FA100BFD501 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4CE3708216FB70AD00BFD501 /* Build configuration list for PBXNativeTarget "stepping-testcase" */ = {
isa = XCConfigurationList;
@ -1176,6 +1199,7 @@
4CE3708416FB70AD00BFD501 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};