Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,50 @@
//===-- 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"
#include "lldb/lldb-forward.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

@@ -0,0 +1,51 @@
//===-- Gauge.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_Gauge_h
#define PerfTestDriver_Gauge_h
#include <functional>
#include <string>
#include "Results.h"
namespace lldb_perf {
template <class T> class Gauge {
public:
typedef T ValueType;
Gauge() {}
virtual ~Gauge() {}
virtual void Start() = 0;
virtual ValueType Stop() = 0;
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

@@ -0,0 +1,158 @@
//===-- Measurement.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__Measurement__
#define __PerfTestDriver__Measurement__
#include "Gauge.h"
#include "MemoryGauge.h"
#include "Metric.h"
#include "Timer.h"
namespace lldb_perf {
template <typename GaugeType, typename Callable> class Measurement {
public:
Measurement() : m_gauge(), m_callable(), m_metric() {}
Measurement(Callable callable, const char *name, const char *desc)
: m_gauge(), m_callable(callable),
m_metric(Metric<typename GaugeType::ValueType>(name, desc)) {}
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_callable(rhs.GetCallable()),
m_metric(rhs.GetMetric()) {}
template <typename... Args> void operator()(Args... args) {
m_gauge.Start();
m_callable(args...);
m_metric.Append(m_gauge.Stop());
}
virtual const Callable &GetCallable() const { return m_callable; }
virtual const GaugeType &GetGauge() const { return m_gauge; }
virtual const Metric<typename GaugeType::ValueType> &GetMetric() const {
return m_metric;
}
void Start() { m_gauge.Start(); }
typename GaugeType::ValueType Stop() {
auto value = m_gauge.Stop();
m_metric.Append(value);
return value;
}
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()));
}
void WriteAverageAndStandardDeviation(Results &results) {
auto metric = GetMetric();
auto dictionary =
(Results::Dictionary *)results.GetDictionary()
.Add(metric.GetName(), metric.GetDescription(),
lldb_perf::GetResult<typename GaugeType::ValueType>(
NULL, metric.GetAverage()))
.get();
if (dictionary) {
dictionary->Add("stddev", NULL,
lldb_perf::GetResult<typename GaugeType::ValueType>(
NULL, metric.GetStandardDeviation()));
}
}
void WriteStandardDeviation(Results &results) {
auto metric = GetMetric();
results.GetDictionary().Add(
metric.GetName(), metric.GetDescription(),
lldb_perf::GetResult<typename GaugeType::ValueType>(
NULL, metric.GetStandardDeviation()));
}
protected:
GaugeType m_gauge;
Callable m_callable;
Metric<typename GaugeType::ValueType> m_metric;
};
template <typename Callable>
class TimeMeasurement : public Measurement<TimeGauge, Callable> {
public:
TimeMeasurement() : Measurement<TimeGauge, Callable>() {}
TimeMeasurement(Callable callable, const char *name = NULL,
const char *descr = NULL)
: Measurement<TimeGauge, Callable>(callable, name, descr) {}
template <typename Callable_Rhs>
TimeMeasurement(const TimeMeasurement<Callable_Rhs> &rhs)
: Measurement<TimeGauge, Callable>(rhs) {}
template <typename GaugeType_Rhs, typename Callable_Rhs>
TimeMeasurement(const Measurement<GaugeType_Rhs, Callable_Rhs> &rhs)
: Measurement<GaugeType_Rhs, Callable_Rhs>(rhs) {}
template <typename... Args> void operator()(Args... args) {
Measurement<TimeGauge, Callable>::operator()(args...);
}
};
template <typename Callable>
class MemoryMeasurement : public Measurement<MemoryGauge, Callable> {
public:
MemoryMeasurement() : Measurement<MemoryGauge, Callable>() {}
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 GaugeType_Rhs, typename Callable_Rhs>
MemoryMeasurement(const Measurement<GaugeType_Rhs, Callable_Rhs> &rhs)
: Measurement<GaugeType_Rhs, Callable_Rhs>(rhs) {}
template <typename... Args> void operator()(Args... args) {
Measurement<MemoryGauge, Callable>::operator()(args...);
}
};
}
#endif /* defined(__PerfTestDriver__Measurement__) */

View File

@@ -0,0 +1,133 @@
//===-- MemoryGauge.cpp -----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "MemoryGauge.h"
#include "lldb/lldb-forward.h"
#include <assert.h>
#include <cmath>
#include <mach/mach.h>
#include <mach/mach_traps.h>
#include <mach/task.h>
using namespace lldb_perf;
MemoryStats::MemoryStats(mach_vm_size_t virtual_size,
mach_vm_size_t resident_size,
mach_vm_size_t max_resident_size)
: m_virtual_size(virtual_size), m_resident_size(resident_size),
m_max_resident_size(max_resident_size) {}
MemoryStats::MemoryStats(const MemoryStats &rhs)
: m_virtual_size(rhs.m_virtual_size), m_resident_size(rhs.m_resident_size),
m_max_resident_size(rhs.m_max_resident_size) {}
MemoryStats &MemoryStats::operator=(const MemoryStats &rhs) {
if (this != &rhs) {
m_virtual_size = rhs.m_virtual_size;
m_resident_size = rhs.m_resident_size;
m_max_resident_size = rhs.m_max_resident_size;
}
return *this;
}
MemoryStats &MemoryStats::operator+=(const MemoryStats &rhs) {
m_virtual_size += rhs.m_virtual_size;
m_resident_size += rhs.m_resident_size;
m_max_resident_size += rhs.m_max_resident_size;
return *this;
}
MemoryStats MemoryStats::operator-(const MemoryStats &rhs) {
return MemoryStats(m_virtual_size - rhs.m_virtual_size,
m_resident_size - rhs.m_resident_size,
m_max_resident_size - rhs.m_max_resident_size);
}
MemoryStats MemoryStats::operator+(const MemoryStats &rhs) {
return MemoryStats(m_virtual_size + rhs.m_virtual_size,
m_resident_size + rhs.m_resident_size,
m_max_resident_size + rhs.m_max_resident_size);
}
MemoryStats MemoryStats::operator/(size_t n) {
MemoryStats result(*this);
result.m_virtual_size /= n;
result.m_resident_size /= n;
result.m_max_resident_size /= n;
return result;
}
MemoryStats MemoryStats::operator*(const MemoryStats &rhs) {
return MemoryStats(m_virtual_size * rhs.m_virtual_size,
m_resident_size * rhs.m_resident_size,
m_max_resident_size * rhs.m_max_resident_size);
}
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();
mach_task_basic_info_data_t taskBasicInfo;
mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
auto task_info_ret = task_info(task, MACH_TASK_BASIC_INFO,
(task_info_t)&taskBasicInfo, &count);
if (task_info_ret == KERN_SUCCESS) {
return MemoryStats(taskBasicInfo.virtual_size, taskBasicInfo.resident_size,
taskBasicInfo.resident_size_max);
}
return 0;
}
MemoryGauge::MemoryGauge()
: m_state(MemoryGauge::State::eNeverUsed), m_start(), m_delta() {}
void MemoryGauge::Start() {
m_state = MemoryGauge::State::eCounting;
m_start = Now();
}
MemoryGauge::ValueType MemoryGauge::Stop() {
m_stop = Now();
assert(m_state == MemoryGauge::State::eCounting &&
"cannot stop a non-started gauge");
m_state = MemoryGauge::State::eStopped;
m_delta = m_stop - m_start;
return m_delta;
}
MemoryGauge::ValueType MemoryGauge::GetDeltaValue() const {
assert(m_state == MemoryGauge::State::eStopped &&
"gauge must be used before you can evaluate it");
return m_delta;
}
template <>
Results::ResultSP lldb_perf::GetResult(const char *description,
MemoryStats value) {
return value.GetResult(NULL, description);
}
MemoryStats sqrt(const MemoryStats &arg) {
long double virt_size = arg.GetVirtualSize();
long double resident_size = arg.GetResidentSize();
long double max_resident_size = arg.GetMaxResidentSize();
virt_size = sqrtl(virt_size);
resident_size = sqrtl(resident_size);
max_resident_size = sqrtl(max_resident_size);
return MemoryStats(virt_size, resident_size, max_resident_size);
}

View File

@@ -0,0 +1,92 @@
//===-- MemoryGauge.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__MemoryGauge__
#define __PerfTestDriver__MemoryGauge__
#include "Gauge.h"
#include "Results.h"
#include <mach/task_info.h>
namespace lldb_perf {
class MemoryStats {
public:
MemoryStats(mach_vm_size_t virtual_size = 0, mach_vm_size_t resident_size = 0,
mach_vm_size_t max_resident_size = 0);
MemoryStats(const MemoryStats &rhs);
MemoryStats &operator=(const MemoryStats &rhs);
MemoryStats &operator+=(const MemoryStats &rhs);
MemoryStats operator-(const MemoryStats &rhs);
MemoryStats operator+(const MemoryStats &rhs);
MemoryStats operator/(size_t rhs);
MemoryStats operator*(const MemoryStats &rhs);
mach_vm_size_t GetVirtualSize() const { return m_virtual_size; }
mach_vm_size_t GetResidentSize() const { return m_resident_size; }
mach_vm_size_t GetMaxResidentSize() const { return m_max_resident_size; }
void SetVirtualSize(mach_vm_size_t vs) { m_virtual_size = vs; }
void SetResidentSize(mach_vm_size_t rs) { m_resident_size = rs; }
void SetMaxResidentSize(mach_vm_size_t mrs) { 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;
mach_vm_size_t m_max_resident_size;
};
class MemoryGauge : public Gauge<MemoryStats> {
public:
MemoryGauge();
virtual ~MemoryGauge() {}
void Start();
ValueType Stop();
virtual ValueType GetStartValue() const { return m_start; }
virtual ValueType GetStopValue() const { return m_stop; }
virtual ValueType GetDeltaValue() const;
private:
enum class State { eNeverUsed, eCounting, eStopped };
ValueType Now();
State m_state;
ValueType m_start;
ValueType m_stop;
ValueType m_delta;
};
template <>
Results::ResultSP GetResult(const char *description, MemoryStats value);
} // namespace lldb_perf
lldb_perf::MemoryStats sqrt(const lldb_perf::MemoryStats &arg);
#endif // #ifndef __PerfTestDriver__MemoryGauge__

View File

@@ -0,0 +1,60 @@
//===-- Metric.cpp ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Metric.h"
#include "MemoryGauge.h"
#include <cmath>
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() {}
template <class T> void Metric<T>::Append(T v) { m_dataset.push_back(v); }
template <class T> size_t Metric<T>::GetCount() const {
return m_dataset.size();
}
template <class T> T Metric<T>::GetSum() const {
T sum = 0;
for (auto v : m_dataset)
sum += v;
return sum;
}
template <class T> T Metric<T>::GetAverage() const {
return GetSum() / GetCount();
}
// Knuth's algorithm for stddev - massive cancellation resistant
template <class T>
T Metric<T>::GetStandardDeviation(StandardDeviationMode mode) const {
size_t n = 0;
T mean = 0;
T M2 = 0;
for (auto x : m_dataset) {
n = n + 1;
T delta = x - mean;
mean = mean + delta / n;
M2 = M2 + delta * (x - mean);
}
T variance;
if (mode == StandardDeviationMode::ePopulation || n == 1)
variance = M2 / n;
else
variance = M2 / (n - 1);
return sqrt(variance);
}
template class lldb_perf::Metric<double>;
template class lldb_perf::Metric<MemoryStats>;

View File

@@ -0,0 +1,58 @@
//===-- Metric.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__Metric__
#define __PerfTestDriver__Metric__
#include <mach/task_info.h>
#include <string>
#include <vector>
namespace lldb_perf {
class MemoryStats;
template <class ValueType> class Metric {
public:
enum class StandardDeviationMode { eSample, ePopulation };
Metric();
Metric(const char *, const char * = NULL);
void Append(ValueType v);
ValueType GetAverage() const;
size_t GetCount() const;
ValueType GetSum() const;
ValueType GetStandardDeviation(
StandardDeviationMode mode = StandardDeviationMode::ePopulation) const;
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();
}
private:
std::string m_name;
std::string m_description;
std::vector<ValueType> m_dataset;
};
}
#endif /* defined(__PerfTestDriver__Metric__) */

View File

@@ -0,0 +1,237 @@
//===-- 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:
llvm_unreachable("unhandled result");
}
}
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:
llvm_unreachable("unhandled result");
}
}
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);
if (out_path == NULL)
out_path = "/dev/stdout";
CFURLRef file = CFURLCreateFromFileSystemRepresentation(
NULL, (const UInt8 *)out_path, strlen(out_path), FALSE);
CFURLWriteDataAndPropertiesToResource(file, xmlData, NULL, NULL);
#endif
}
Results::ResultSP 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));
return m_dictionary[std::string(name)];
}
Results::ResultSP 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));
return m_dictionary[std::string(name)];
}
Results::ResultSP 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));
return m_dictionary[std::string(name)];
}
Results::ResultSP 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;
return m_dictionary[std::string(name)];
}
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;
}
}
Results::ResultSP Results::Array::Append(const ResultSP &result_sp) {
m_array.push_back(result_sp);
return 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,205 @@
//===-- 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 "lldb/lldb-forward.h"
#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() {}
ResultSP 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);
ResultSP Add(const char *name, const char *description,
const ResultSP &result_sp);
ResultSP AddDouble(const char *name, const char *descriptiorn,
double value);
ResultSP AddUnsigned(const char *name, const char *description,
uint64_t value);
ResultSP 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

@@ -0,0 +1,308 @@
//===-- TestCase.cpp --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "TestCase.h"
#include "Results.h"
#include "Xcode.h"
using namespace lldb_perf;
TestCase::TestCase()
: m_debugger(), m_target(), m_process(), m_thread(), m_listener(),
m_verbose(false), m_step(0) {
SBDebugger::Initialize();
SBHostOS::ThreadCreated("<lldb-tester.app.main>");
m_debugger = SBDebugger::Create(false);
m_listener = m_debugger.GetListener();
m_listener.StartListeningForEventClass(
m_debugger, SBProcess::GetBroadcasterClass(),
SBProcess::eBroadcastBitStateChanged | SBProcess::eBroadcastBitInterrupt);
}
static std::string GetShortOptionString(struct option *long_options) {
std::string option_string;
for (int i = 0; long_options[i].name != NULL; ++i) {
if (long_options[i].flag == NULL) {
option_string.push_back((char)long_options[i].val);
switch (long_options[i].has_arg) {
default:
case no_argument:
break;
case required_argument:
option_string.push_back(':');
break;
case optional_argument:
option_string.append(2, ':');
break;
}
}
}
return option_string;
}
bool TestCase::Setup(int &argc, const char **&argv) {
bool done = false;
struct option *long_options = GetLongOptions();
if (long_options) {
std::string short_option_string(GetShortOptionString(long_options));
#if __GLIBC__
optind = 0;
#else
optreset = 1;
optind = 1;
#endif
while (!done) {
int long_options_index = -1;
const int short_option = ::getopt_long_only(
argc, const_cast<char **>(argv), short_option_string.c_str(),
long_options, &long_options_index);
switch (short_option) {
case 0:
// Already handled
break;
case -1:
done = true;
break;
default:
done = !ParseOption(short_option, optarg);
break;
}
}
argc -= optind;
argv += optind;
}
return false;
}
bool TestCase::Launch(lldb::SBLaunchInfo &launch_info) {
lldb::SBError error;
m_process = m_target.Launch(launch_info, error);
if (!error.Success())
fprintf(stderr, "error: %s\n", error.GetCString());
if (m_process.IsValid())
return true;
return false;
}
bool TestCase::Launch(std::initializer_list<const char *> args) {
std::vector<const char *> args_vect(args);
args_vect.push_back(NULL);
lldb::SBLaunchInfo launch_info((const char **)&args_vect[0]);
return Launch(launch_info);
}
void TestCase::SetVerbose(bool b) { m_verbose = b; }
bool TestCase::GetVerbose() { return m_verbose; }
void TestCase::Loop() {
while (true) {
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)) {
if (m_verbose) {
const uint32_t num_threads = m_process.GetNumThreads();
for (auto thread_index = 0; thread_index < num_threads;
thread_index++) {
SBThread thread(m_process.GetThreadAtIndex(thread_index));
SBFrame frame(thread.GetFrameAtIndex(0));
SBStream strm;
strm.RedirectToFileHandle(stdout, false);
frame.GetDescription(strm);
}
puts("restarted");
}
call_test_step = false;
} else {
switch (state) {
case eStateInvalid:
case eStateDetached:
case eStateCrashed:
case eStateUnloaded:
break;
case eStateExited:
return;
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateRunning:
case eStateStepping:
call_test_step = false;
break;
case eStateStopped:
case eStateSuspended: {
call_test_step = true;
bool fatal = false;
bool selected_thread = false;
const uint32_t num_threads = m_process.GetNumThreads();
for (auto thread_index = 0; thread_index < num_threads;
thread_index++) {
SBThread thread(m_process.GetThreadAtIndex(thread_index));
SBFrame frame(thread.GetFrameAtIndex(0));
SBStream strm;
strm.RedirectToFileHandle(stdout, false);
frame.GetDescription(strm);
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);
}
} break;
}
}
} else {
call_test_step = true;
}
if (call_test_step) {
do_the_call:
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::eNone:
// Just exit and wait for the next event
break;
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::eRelaunch:
if (m_process.IsValid()) {
m_process.Kill();
m_process.Clear();
}
Launch(action.launch_info);
break;
case ActionWanted::Type::eKill:
if (m_verbose)
printf("kill\n");
m_process.Kill();
return;
case ActionWanted::Type::eCallNext:
goto do_the_call;
break;
}
}
}
if (GetVerbose())
printf("I am gonna die at step %d\n", m_step);
}
int TestCase::Run(TestCase &test, int argc, const char **argv) {
if (test.Setup(argc, argv)) {
test.Loop();
Results results;
test.WriteResults(results);
return RUN_SUCCESS;
} else
return RUN_SETUP_ERROR;
}

View File

@@ -0,0 +1,145 @@
//===-- TestCase.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__TestCase__
#define __PerfTestDriver__TestCase__
#include "Measurement.h"
#include "lldb/API/LLDB.h"
#include <getopt.h>
namespace lldb_perf {
class Results;
class TestCase {
public:
TestCase();
struct ActionWanted {
enum class Type {
eStepOver,
eContinue,
eStepOut,
eRelaunch,
eCallNext,
eNone,
eKill
} type;
lldb::SBThread thread;
lldb::SBLaunchInfo launch_info;
ActionWanted() : type(Type::eContinue), thread(), launch_info(NULL) {}
void None() {
type = Type::eNone;
thread = lldb::SBThread();
}
void Continue() {
type = Type::eContinue;
thread = lldb::SBThread();
}
void StepOver(lldb::SBThread t) {
type = Type::eStepOver;
thread = t;
}
void StepOut(lldb::SBThread t) {
type = Type::eStepOut;
thread = t;
}
void Relaunch(lldb::SBLaunchInfo l) {
type = Type::eRelaunch;
thread = lldb::SBThread();
launch_info = l;
}
void Kill() {
type = Type::eKill;
thread = lldb::SBThread();
}
void CallNext() {
type = Type::eCallNext;
thread = lldb::SBThread();
}
};
virtual ~TestCase() {}
virtual bool Setup(int &argc, const char **&argv);
virtual void TestStep(int counter, ActionWanted &next_action) = 0;
bool Launch(lldb::SBLaunchInfo &launch_info);
bool Launch(std::initializer_list<const char *> args = {});
void Loop();
void SetVerbose(bool);
bool GetVerbose();
virtual void WriteResults(Results &results) = 0;
template <typename G, typename A>
Measurement<G, A> CreateMeasurement(A a, const char *name = NULL,
const char *description = NULL) {
return Measurement<G, A>(a, name, description);
}
template <typename A>
TimeMeasurement<A> CreateTimeMeasurement(A a, const char *name = NULL,
const char *description = NULL) {
return TimeMeasurement<A>(a, name, description);
}
template <typename A>
MemoryMeasurement<A> CreateMemoryMeasurement(A a, const char *name = NULL,
const char *description = NULL) {
return MemoryMeasurement<A>(a, name, description);
}
static int Run(TestCase &test, int argc, const char **argv);
virtual bool ParseOption(int short_option, const char *optarg) {
return false;
}
virtual struct option *GetLongOptions() { return NULL; }
lldb::SBDebugger &GetDebugger() { return m_debugger; }
lldb::SBTarget &GetTarget() { return m_target; }
lldb::SBProcess &GetProcess() { return m_process; }
lldb::SBThread &GetThread() { return m_thread; }
int GetStep() { return m_step; }
static const int RUN_SUCCESS = 0;
static const int RUN_SETUP_ERROR = 100;
protected:
lldb::SBDebugger m_debugger;
lldb::SBTarget m_target;
lldb::SBProcess m_process;
lldb::SBThread m_thread;
lldb::SBListener m_listener;
bool m_verbose;
int m_step;
};
}
#endif /* defined(__PerfTestDriver__TestCase__) */

View File

@@ -0,0 +1,47 @@
//===-- Timer.cpp -----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Timer.h"
#include <assert.h>
using namespace lldb_perf;
TimeGauge::TimeType TimeGauge::Now() { return high_resolution_clock::now(); }
TimeGauge::TimeGauge() : m_start(), m_state(TimeGauge::State::eNeverUsed) {}
void TimeGauge::Start() {
m_state = TimeGauge::State::eCounting;
m_start = Now();
}
double TimeGauge::Stop() {
m_stop = Now();
assert(m_state == TimeGauge::State::eCounting &&
"cannot stop a non-started clock");
m_state = TimeGauge::State::eStopped;
m_delta = duration_cast<duration<double>>(m_stop - m_start).count();
return m_delta;
}
double 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_delta;
}

View File

@@ -0,0 +1,49 @@
//===-- Timer.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__Timer__
#define __PerfTestDriver__Timer__
#include "Gauge.h"
#include <chrono>
using namespace std::chrono;
namespace lldb_perf {
class TimeGauge : public Gauge<double> {
public:
TimeGauge();
virtual ~TimeGauge() {}
void Start();
double Stop();
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();
};
}
#endif /* defined(__PerfTestDriver__Timer__) */

View File

@@ -0,0 +1,137 @@
//===-- Xcode.cpp -----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "Xcode.h"
#include <string>
using namespace std;
using namespace lldb_perf;
void Xcode::FetchVariable(SBValue value, uint32_t expand, bool verbose) {
auto name = value.GetName();
auto num_value = value.GetValueAsUnsigned(0);
auto summary = value.GetSummary();
auto in_scope = value.IsInScope();
auto has_children = value.MightHaveChildren();
auto type_1 = value.GetType();
auto type_2 = value.GetType();
auto type_name_1 = value.GetTypeName();
auto type_3 = value.GetType();
auto type_name_2 = value.GetTypeName();
if (verbose)
printf("%s %s = 0x%llx (%llu) %s\n", value.GetTypeName(), value.GetName(),
num_value, num_value, summary);
if (expand > 0) {
auto count = value.GetNumChildren();
for (int i = 0; i < count; i++) {
SBValue child(value.GetChildAtIndex(i, lldb::eDynamicCanRunTarget, true));
FetchVariable(child, expand - 1, verbose);
}
}
}
void Xcode::FetchModules(SBTarget target, bool verbose) {
auto count = target.GetNumModules();
for (int i = 0; i < count; i++) {
SBModule module(target.GetModuleAtIndex(i));
auto fspec = module.GetFileSpec();
std::string path(1024, 0);
fspec.GetPath(&path[0], 1024);
auto uuid = module.GetUUIDBytes();
if (verbose) {
printf("%s %s\n", path.c_str(), module.GetUUIDString());
}
}
}
void Xcode::FetchVariables(SBFrame frame, uint32_t expand, bool verbose) {
auto values =
frame.GetVariables(true, true, true, false, eDynamicCanRunTarget);
auto count = values.GetSize();
for (int i = 0; i < count; i++) {
SBValue value(values.GetValueAtIndex(i));
FetchVariable(value, expand, verbose);
}
}
void Xcode::FetchFrames(SBProcess process, bool variables, bool verbose) {
auto pCount = process.GetNumThreads();
for (int p = 0; p < pCount; p++) {
SBThread thread(process.GetThreadAtIndex(p));
auto tCount = thread.GetNumFrames();
if (verbose)
printf("%s %d %d {%d}\n", thread.GetQueueName(), tCount,
thread.GetStopReason(), eStopReasonBreakpoint);
for (int t = 0; t < tCount; t++) {
SBFrame frame(thread.GetFrameAtIndex(t));
auto fp = frame.GetFP();
SBThread thread_dup = frame.GetThread();
SBFileSpec filespec(process.GetTarget().GetExecutable());
std::string path(1024, 0);
filespec.GetPath(&path[0], 1024);
auto state = process.GetState();
auto pCount_dup = process.GetNumThreads();
auto byte_size = process.GetAddressByteSize();
auto pc = frame.GetPC();
SBSymbolContext context(frame.GetSymbolContext(0x0000006e));
SBModule module(context.GetModule());
SBLineEntry entry(context.GetLineEntry());
SBFileSpec entry_filespec(process.GetTarget().GetExecutable());
std::string entry_path(1024, 0);
entry_filespec.GetPath(&entry_path[0], 1024);
auto line_1 = entry.GetLine();
auto line_2 = entry.GetLine();
auto fname = frame.GetFunctionName();
if (verbose)
printf("%llu %s %d %d %llu %s %d %s\n", fp, path.c_str(), state,
byte_size, pc, entry_path.c_str(), line_1, fname);
if (variables)
FetchVariables(frame, 0, verbose);
}
}
}
void Xcode::RunExpression(SBFrame frame, const char *expression, bool po,
bool verbose) {
SBValue value(frame.EvaluateExpression(expression, eDynamicCanRunTarget));
FetchVariable(value, 0, verbose);
if (po) {
auto descr = value.GetObjectDescription();
if (descr)
printf("po = %s\n", descr);
}
}
void Xcode::Next(SBThread thread) { thread.StepOver(); }
void Xcode::Continue(SBProcess process) { process.Continue(); }
void Xcode::RunCommand(SBDebugger debugger, const char *cmd, bool verbose) {
SBCommandReturnObject sb_ret;
auto interpreter = debugger.GetCommandInterpreter();
interpreter.HandleCommand(cmd, sb_ret);
if (verbose)
printf("%s\n%s\n", sb_ret.GetOutput(false), sb_ret.GetError(false));
}
SBThread Xcode::GetThreadWithStopReason(SBProcess process, StopReason reason) {
auto threads_count = process.GetNumThreads();
for (auto thread_num = 0; thread_num < threads_count; thread_num++) {
SBThread thread(process.GetThreadAtIndex(thread_num));
if (thread.GetStopReason() == reason) {
return thread;
}
}
return SBThread();
}
SBBreakpoint Xcode::CreateFileLineBreakpoint(SBTarget target, const char *file,
uint32_t line) {
return target.BreakpointCreateByLocation(file, line);
}

View File

@@ -0,0 +1,58 @@
//===-- Xcode.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__Xcode__
#define __PerfTestDriver__Xcode__
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBLineEntry.h"
#include "lldb/API/SBModule.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBValue.h"
using namespace lldb;
namespace lldb_perf {
class Xcode {
public:
static void FetchVariable(SBValue value, uint32_t expand = 0,
bool verbose = false);
static void FetchModules(SBTarget target, bool verbose = false);
static void FetchVariables(SBFrame frame, uint32_t expand = 0,
bool verbose = false);
static void FetchFrames(SBProcess process, bool variables = false,
bool verbose = false);
static void RunExpression(SBFrame frame, const char *expression,
bool po = false, bool verbose = false);
static void Next(SBThread thread);
static void Continue(SBProcess process);
static void RunCommand(SBDebugger debugger, const char *cmd,
bool verbose = false);
static SBThread GetThreadWithStopReason(SBProcess process, StopReason reason);
static SBBreakpoint CreateFileLineBreakpoint(SBTarget target,
const char *file, uint32_t line);
};
}
#endif /* defined(__PerfTestDriver__Xcode__) */