summaryrefslogtreecommitdiffstats
path: root/lldb/tools/lldb-perf
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/lldb-perf')
-rw-r--r--lldb/tools/lldb-perf/darwin/sketch/main.cpp215
-rw-r--r--lldb/tools/lldb-perf/lib/Gauge.h50
-rw-r--r--lldb/tools/lldb-perf/lib/Measurement.h52
-rw-r--r--lldb/tools/lldb-perf/lib/MemoryGauge.cpp54
-rw-r--r--lldb/tools/lldb-perf/lib/MemoryGauge.h53
-rw-r--r--lldb/tools/lldb-perf/lib/Metric.cpp84
-rw-r--r--lldb/tools/lldb-perf/lib/Metric.h71
-rw-r--r--lldb/tools/lldb-perf/lib/TestCase.cpp178
-rw-r--r--lldb/tools/lldb-perf/lib/TestCase.h80
-rw-r--r--lldb/tools/lldb-perf/lib/Timer.cpp47
-rw-r--r--lldb/tools/lldb-perf/lib/Timer.h56
-rw-r--r--lldb/tools/lldb-perf/lib/Xcode.cpp164
-rw-r--r--lldb/tools/lldb-perf/lib/Xcode.h63
13 files changed, 1167 insertions, 0 deletions
diff --git a/lldb/tools/lldb-perf/darwin/sketch/main.cpp b/lldb/tools/lldb-perf/darwin/sketch/main.cpp
new file mode 100644
index 00000000000..c90c6594240
--- /dev/null
+++ b/lldb/tools/lldb-perf/darwin/sketch/main.cpp
@@ -0,0 +1,215 @@
+//
+// main.cpp
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/6/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#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/TestCase.h"
+#include "lldb-perf/lib/Xcode.h"
+
+#include <iostream>
+#include <unistd.h>
+#include <fstream>
+
+using namespace lldb::perf;
+
+class SketchTest : public TestCase
+{
+public:
+ SketchTest () :
+ m_fetch_frames_measurement ([this] (SBProcess process) -> void {
+ Xcode::FetchFrames (process,false,false);
+ }, "fetch-frames"),
+ m_file_line_bp_measurement([] (SBTarget target,const char* file, uint32_t line) -> void {
+ Xcode::CreateFileLineBreakpoint(target, file, line);
+ }, "file-line-bkpt"),
+ m_fetch_modules_measurement ([] (SBTarget target) -> void {
+ Xcode::FetchModules(target);
+ }, "fetch-modules"),
+ m_fetch_vars_measurement([this] (SBProcess process, int depth) -> void {
+ auto threads_count = process.GetNumThreads();
+ for (size_t thread_num = 0; thread_num < threads_count; thread_num++)
+ {
+ SBThread thread(process.GetThreadAtIndex(thread_num));
+ SBFrame frame(thread.GetFrameAtIndex(0));
+ Xcode::FetchVariables(frame,depth,GetVerbose());
+
+ }
+ }, "fetch-vars"),
+ m_run_expr_measurement([this] (SBFrame frame, const char* expr) -> void {
+ SBValue value(frame.EvaluateExpression(expr, lldb::eDynamicCanRunTarget));
+ Xcode::FetchVariable(value,0,GetVerbose());
+ }, "run-expr")
+ {}
+
+ virtual
+ ~SketchTest ()
+ {
+ }
+
+ virtual void
+ Setup (int argc, const char** argv)
+ {
+ m_app_path.assign(argv[1]); // "~/perf/Small_ObjC/Sketch/build/Debug/Sketch.app"
+ m_doc_path.assign(argv[2]); // "/Volumes/work/egranata/perf/Small_ObjC/TesterApp/foobar.sketch2";
+ m_out_path.assign(argv[3]);
+ TestCase::Setup(argc,argv);
+ m_target = m_debugger.CreateTarget(m_app_path.c_str());
+ const char* file_arg = m_doc_path.c_str();
+ const char* persist_arg = "-ApplePersistenceIgnoreState";
+ const char* persist_skip = "YES";
+ const char* empty = nullptr;
+ const char* args[] = {file_arg,persist_arg,persist_skip,empty};
+ m_file_line_bp_measurement(m_target, "SKTDocument.m",245);
+ m_file_line_bp_measurement(m_target, "SKTDocument.m",283);
+ m_file_line_bp_measurement(m_target, "SKTText.m",326);
+
+ Launch (args,".");
+ }
+
+ void
+ DoTest ()
+ {
+ m_fetch_frames_measurement(m_process);
+ m_fetch_modules_measurement(m_target);
+ m_fetch_vars_measurement(m_process,1);
+ }
+
+ virtual ActionWanted
+ TestStep (int counter)
+ {
+#define STEP(n) if (counter == n)
+#define NEXT(s) return TestCase::ActionWanted{TestCase::ActionWanted::Type::eAWNext,SelectMyThread(s)}
+#define FINISH(s) return TestCase::ActionWanted{TestCase::ActionWanted::Type::eAWFinish,SelectMyThread(s)}
+#define CONT return TestCase::ActionWanted{TestCase::ActionWanted::Type::eAWContinue,SBThread()}
+#define KILL return TestCase::ActionWanted{TestCase::ActionWanted::Type::eAWKill,SBThread()}
+ STEP(0) {
+ DoTest ();
+ m_file_line_bp_measurement(m_target, "SKTDocument.m",254);
+ CONT;
+ }
+ STEP(1) {
+ DoTest ();
+ SBThread thread(SelectMyThread("SKTDocument.m"));
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"properties");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"[properties description]");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"typeName");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"data");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"[data description]");
+ CONT;
+ }
+ STEP(2) {
+ DoTest ();
+ CONT;
+ }
+ STEP(3) {
+ DoTest ();
+ NEXT("SKTText.m");
+ }
+ STEP(4) {
+ DoTest ();
+ SBThread thread(SelectMyThread("SKTText.m"));
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"layoutManager");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"contents");
+ NEXT("SKTText.m");
+ }
+ STEP(5) {
+ DoTest ();
+ NEXT("SKTText.m");
+ }
+ STEP(6) {
+ DoTest ();
+ NEXT("SKTText.m");
+ }
+ STEP(7) {
+ DoTest ();
+ SBThread thread(SelectMyThread("SKTText.m"));
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"@\"an NSString\"");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"[(id)@\"an NSString\" description]");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"@[@1,@2,@3]");
+ FINISH("SKTText.m");
+ }
+ STEP(8) {
+ DoTest ();
+ SBThread thread(SelectMyThread("SKTGraphicView.m"));
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"[graphics description]");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"[selectionIndexes description]");
+ m_run_expr_measurement(thread.GetFrameAtIndex(0),"(BOOL)NSIntersectsRect(rect, graphicDrawingBounds)");
+ KILL;
+ }
+ KILL;
+#undef STEP
+#undef NEXT
+#undef CONT
+#undef KILL
+ }
+
+ void
+ Results ()
+ {
+ auto ff_metric = m_fetch_frames_measurement.metric();
+ auto fl_metric = m_file_line_bp_measurement.metric();
+ auto md_metric = m_fetch_modules_measurement.metric();
+ auto fv_metric = m_fetch_vars_measurement.metric();
+ auto xp_metric = m_run_expr_measurement.metric();
+
+ CFCMutableArray array;
+ ff_metric.Write(array);
+ fl_metric.Write(array);
+ md_metric.Write(array);
+ fv_metric.Write(array);
+ xp_metric.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);
+ }
+
+private:
+ Measurement<lldb::perf::TimeGauge, std::function<void(SBProcess)>> m_fetch_frames_measurement;
+ Measurement<lldb::perf::TimeGauge, std::function<void(SBTarget, const char*, uint32_t)>> m_file_line_bp_measurement;
+ Measurement<lldb::perf::TimeGauge, std::function<void(SBTarget)>> m_fetch_modules_measurement;
+ Measurement<lldb::perf::TimeGauge, std::function<void(SBProcess,int)>> m_fetch_vars_measurement;
+ Measurement<lldb::perf::TimeGauge, std::function<void(SBFrame,const char*)>> m_run_expr_measurement;
+
+ SBThread
+ SelectMyThread (const char* file_name)
+ {
+ auto threads_count = m_process.GetNumThreads();
+ for (auto thread_num = 0; thread_num < threads_count; thread_num++)
+ {
+ SBThread thread(m_process.GetThreadAtIndex(thread_num));
+ auto local_file_name = thread.GetFrameAtIndex(0).GetCompileUnit().GetFileSpec().GetFilename();
+ if (!local_file_name)
+ continue;
+ if (strcmp(local_file_name,file_name))
+ continue;
+ return thread;
+ }
+ Xcode::RunCommand(m_debugger,"bt all",true);
+ assert(false);
+ }
+ std::string m_app_path;
+ std::string m_doc_path;
+ std::string m_out_path;
+};
+
+// argv[1] == path to app
+// argv[2] == path to document
+// argv[3] == path to result
+int main(int argc, const char * argv[])
+{
+ SketchTest skt;
+ TestCase::Run(skt,argc,argv);
+ return 0;
+}
+
diff --git a/lldb/tools/lldb-perf/lib/Gauge.h b/lldb/tools/lldb-perf/lib/Gauge.h
new file mode 100644
index 00000000000..7c843368baa
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/Gauge.h
@@ -0,0 +1,50 @@
+//
+// Gauge.h
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/7/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef PerfTestDriver_Gauge_h
+#define PerfTestDriver_Gauge_h
+
+#include <functional>
+
+namespace lldb { namespace perf
+{
+template <class TASizeType>
+class Gauge
+{
+public:
+ typedef TASizeType SizeType;
+public:
+ Gauge ()
+ {}
+
+ virtual
+ ~Gauge ()
+ {}
+
+ virtual void
+ start () = 0;
+
+ virtual SizeType
+ stop () = 0;
+
+ virtual SizeType
+ value () = 0;
+
+ template <typename F, typename... Args>
+ SizeType
+ gauge (F f,Args... args)
+ {
+ start();
+ f(args...);
+ return stop();
+ }
+
+};
+} }
+
+#endif
diff --git a/lldb/tools/lldb-perf/lib/Measurement.h b/lldb/tools/lldb-perf/lib/Measurement.h
new file mode 100644
index 00000000000..0697b0fe30f
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/Measurement.h
@@ -0,0 +1,52 @@
+//
+// Measurement.h
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/7/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__Measurement__
+#define __PerfTestDriver__Measurement__
+
+#include "Gauge.h"
+#include "Metric.h"
+
+namespace lldb { namespace perf
+{
+template <typename GaugeType, typename Action>
+class Measurement : public WriteToPList
+{
+public:
+ Measurement (Action act, const char* name = NULL) :
+ m_action (act),
+ m_metric (Metric<typename GaugeType::SizeType>(name))
+ {}
+
+ template <typename... Args>
+ void
+ operator () (Args... args)
+ {
+ GaugeType gauge;
+ m_metric.append (gauge.gauge(m_action,args...));
+ }
+
+ Metric<typename GaugeType::SizeType>
+ metric ()
+ {
+ return m_metric;
+ }
+
+ virtual void
+ Write (CFCMutableArray& parent)
+ {
+ m_metric.Write(parent);
+ }
+
+private:
+ Action m_action;
+ Metric<typename GaugeType::SizeType> m_metric;
+};
+} }
+
+#endif /* defined(__PerfTestDriver__Measurement__) */
diff --git a/lldb/tools/lldb-perf/lib/MemoryGauge.cpp b/lldb/tools/lldb-perf/lib/MemoryGauge.cpp
new file mode 100644
index 00000000000..2a80fccb7e0
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/MemoryGauge.cpp
@@ -0,0 +1,54 @@
+//
+// MemoryGauge.cpp
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/6/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "MemoryGauge.h"
+#include <assert.h>
+#include <mach/task.h>
+
+using namespace lldb::perf;
+
+MemoryGauge::SizeType
+MemoryGauge::now ()
+{
+ task_t task = MACH_PORT_NULL;
+ mach_task_basic_info_data_t taskBasicInfo;
+ mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
+ if (task_info(task, MACH_TASK_BASIC_INFO, (task_info_t) & taskBasicInfo, &count) == KERN_SUCCESS) {
+ return taskBasicInfo.virtual_size;
+ }
+ return 0;
+}
+
+MemoryGauge::MemoryGauge () :
+m_start(),
+m_state(MemoryGauge::State::eMSNeverUsed)
+{
+}
+
+void
+MemoryGauge::start ()
+{
+ m_state = MemoryGauge::State::eMSCounting;
+ m_start = now();
+}
+
+MemoryGauge::SizeType
+MemoryGauge::stop ()
+{
+ auto stop = now();
+ assert(m_state == MemoryGauge::State::eMSCounting && "cannot stop a non-started gauge");
+ m_state = MemoryGauge::State::eMSStopped;
+ return (m_value = stop-m_start);
+}
+
+MemoryGauge::SizeType
+MemoryGauge::value ()
+{
+ assert(m_state == MemoryGauge::State::eMSStopped && "gauge must be used before you can evaluate it");
+ return m_value;
+}
diff --git a/lldb/tools/lldb-perf/lib/MemoryGauge.h b/lldb/tools/lldb-perf/lib/MemoryGauge.h
new file mode 100644
index 00000000000..272b9969b8c
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/MemoryGauge.h
@@ -0,0 +1,53 @@
+//
+// MemoryGauge.h
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/6/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__MemoryGauge__
+#define __PerfTestDriver__MemoryGauge__
+
+#include "Gauge.h"
+
+#include <mach/task_info.h>
+
+namespace lldb { namespace perf
+{
+class MemoryGauge : public Gauge<mach_vm_size_t>
+{
+private:
+ enum class State
+ {
+ eMSNeverUsed,
+ eMSCounting,
+ eMSStopped
+ };
+
+ SizeType
+ now ();
+
+ SizeType m_start;
+ State m_state;
+ SizeType m_value;
+
+public:
+ MemoryGauge ();
+
+ virtual
+ ~MemoryGauge ()
+ {}
+
+ void
+ start ();
+
+ SizeType
+ stop ();
+
+ SizeType
+ value ();
+};
+} }
+
+#endif /* defined(__PerfTestDriver__MemoryGauge__) */
diff --git a/lldb/tools/lldb-perf/lib/Metric.cpp b/lldb/tools/lldb-perf/lib/Metric.cpp
new file mode 100644
index 00000000000..885413fc65a
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/Metric.cpp
@@ -0,0 +1,84 @@
+//
+// Metric.cpp
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/7/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "Metric.h"
+
+#include "CFCMutableArray.h"
+#include "CFCMutableDictionary.h"
+#include "CFCString.h"
+
+using namespace lldb::perf;
+
+template <class T>
+Metric<T>::Metric () : Metric ("")
+{}
+
+template <class T>
+Metric<T>::Metric (const char* n) :
+m_name(n ? n : ""),
+m_dataset ()
+{}
+
+template <class T>
+void
+Metric<T>::append (T v)
+{
+ m_dataset.push_back(v);
+}
+
+template <class T>
+size_t
+Metric<T>::count ()
+{
+ return m_dataset.size();
+}
+
+template <class T>
+T
+Metric<T>::sum ()
+{
+ T sum = 0;
+ for (auto v : m_dataset)
+ sum += v;
+ return sum;
+}
+
+template <class T>
+T
+Metric<T>::average ()
+{
+ return sum()/count();
+}
+
+template <class T>
+const char*
+Metric<T>::name ()
+{
+ return m_name.c_str();
+}
+
+template <class T>
+void Metric<T>::WriteImpl (CFCMutableArray& parent, identity<double>)
+{
+ CFCMutableDictionary dict;
+ dict.AddValueCString(CFCString("name").get(),m_name.c_str(), true);
+ dict.AddValueDouble(CFCString("value").get(),this->average(), true);
+ parent.AppendValue(dict.get(), true);
+}
+
+template <class T>
+void Metric<T>::WriteImpl (CFCMutableArray& parent, identity<mach_vm_size_t>)
+{
+ CFCMutableDictionary dict;
+ dict.AddValueCString(CFCString("name").get(),m_name.c_str(), true);
+ dict.AddValueUInt64(CFCString("value").get(),this->average(), true);
+ parent.AppendValue(dict.get(), true);
+}
+
+template class lldb::perf::Metric<double>;
+template class lldb::perf::Metric<mach_vm_size_t>;
diff --git a/lldb/tools/lldb-perf/lib/Metric.h b/lldb/tools/lldb-perf/lib/Metric.h
new file mode 100644
index 00000000000..33ed6c27443
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/Metric.h
@@ -0,0 +1,71 @@
+//
+// Metric.h
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/7/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__Metric__
+#define __PerfTestDriver__Metric__
+
+#include <vector>
+#include <string>
+#include <mach/task_info.h>
+
+#include "CFCMutableArray.h"
+
+namespace lldb { namespace perf
+{
+class WriteToPList
+{
+public:
+ virtual void
+ Write (CFCMutableArray& parent) = 0;
+
+ virtual
+ ~WriteToPList () {}
+};
+
+template <class ValueType>
+class Metric : public WriteToPList {
+public:
+ Metric ();
+ Metric (const char*);
+
+ void
+ append (ValueType v);
+
+ size_t
+ count ();
+
+ ValueType
+ sum ();
+
+ ValueType
+ average ();
+
+ const char*
+ name ();
+
+ virtual void
+ Write (CFCMutableArray& parent)
+ {
+ WriteImpl(parent, identity<ValueType>());
+ }
+
+private:
+
+ template<typename T>
+ struct identity { typedef T type; };
+
+ void WriteImpl (CFCMutableArray& parent, identity<double>);
+
+ void WriteImpl (CFCMutableArray& parent, identity<mach_vm_size_t>);
+
+ std::string m_name;
+ std::vector<ValueType> m_dataset;
+};
+} }
+
+#endif /* defined(__PerfTestDriver__Metric__) */
diff --git a/lldb/tools/lldb-perf/lib/TestCase.cpp b/lldb/tools/lldb-perf/lib/TestCase.cpp
new file mode 100644
index 00000000000..2067969f81a
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/TestCase.cpp
@@ -0,0 +1,178 @@
+//
+// TestCase.cpp
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/7/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "TestCase.h"
+#include "Xcode.h"
+
+using namespace lldb::perf;
+
+TestCase::TestCase () :
+m_debugger(),
+m_target(),
+m_process(),
+m_thread(),
+m_listener(),
+m_verbose(false)
+{}
+
+void
+TestCase::Setup (int argc, const char** argv)
+{
+ SBDebugger::Initialize();
+ SBHostOS::ThreadCreated ("<lldb-tester.app.main>");
+ m_debugger = SBDebugger::Create(false);
+ m_listener = m_debugger.GetListener();
+}
+
+bool
+TestCase::Launch (const char** args, const char* cwd)
+{
+ m_process = m_target.LaunchSimple(args,NULL,cwd);
+ m_process.GetBroadcaster().AddListener(m_listener, SBProcess::eBroadcastBitStateChanged | SBProcess::eBroadcastBitInterrupt);
+ return m_process.IsValid ();
+}
+
+void
+TestCase::SetVerbose (bool b)
+{
+ m_verbose = b;
+}
+
+bool
+TestCase::GetVerbose ()
+{
+ return m_verbose;
+}
+
+void
+TestCase::Loop ()
+{
+ int step = 0;
+ 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;
+ for (auto thread_index = 0; thread_index < m_process.GetNumThreads(); thread_index++)
+ {
+ SBThread thread(m_process.GetThreadAtIndex(thread_index));
+ SBFrame frame(thread.GetFrameAtIndex(0));
+ 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:
+ if (m_verbose) printf("trace\n");
+ break;
+
+ case eStopReasonPlanComplete:
+ 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:
+ if (m_verbose) printf("exception\n");
+ fatal = true;
+ break;
+ case eStopReasonBreakpoint:
+ if (m_verbose) printf("breakpoint id = %lld.%lld\n",thread.GetStopReasonDataAtIndex(0),thread.GetStopReasonDataAtIndex(1));
+ break;
+ case eStopReasonWatchpoint:
+ if (m_verbose) printf("watchpoint id = %lld\n",thread.GetStopReasonDataAtIndex(0));
+ break;
+ case eStopReasonSignal:
+ if (m_verbose) printf("signal %d\n",(int)thread.GetStopReasonDataAtIndex(0));
+ break;
+ }
+ }
+ if (fatal)
+ {
+ if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
+ exit(1);
+ }
+ if (m_verbose)
+ printf("RUNNING STEP %d\n",step);
+ auto action = TestStep(step);
+ step++;
+ switch (action.type)
+ {
+ case ActionWanted::Type::eAWContinue:
+ m_debugger.HandleCommand("continue");
+ break;
+ case ActionWanted::Type::eAWFinish:
+ 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",step);
+ exit(501);
+ }
+ m_process.SetSelectedThread(action.thread);
+ m_debugger.HandleCommand("finish");
+ break;
+ case ActionWanted::Type::eAWNext:
+ 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",step);
+ exit(500);
+ }
+ m_process.SetSelectedThread(action.thread);
+ m_debugger.HandleCommand("next");
+ break;
+ case ActionWanted::Type::eAWKill:
+ if (m_verbose) printf("I want to die\n");
+ m_process.Kill();
+ return;
+ }
+ }
+ }
+ }
+ if (GetVerbose()) printf("I am gonna die at step %d\n",step);
+}
+
+void
+TestCase::Run (TestCase& test, int argc, const char** argv)
+{
+ test.Setup(argc, argv);
+ test.Loop();
+ test.Results();
+}
diff --git a/lldb/tools/lldb-perf/lib/TestCase.h b/lldb/tools/lldb-perf/lib/TestCase.h
new file mode 100644
index 00000000000..f2d67de6662
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/TestCase.h
@@ -0,0 +1,80 @@
+//
+// TestCase.h
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/7/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__TestCase__
+#define __PerfTestDriver__TestCase__
+
+#include "lldb/API/LLDB.h"
+#include "Measurement.h"
+
+using namespace lldb;
+
+namespace lldb { namespace perf
+{
+class TestCase
+{
+public:
+ TestCase();
+
+ struct ActionWanted
+ {
+ enum class Type
+ {
+ eAWNext,
+ eAWContinue,
+ eAWFinish,
+ eAWKill
+ } type;
+ SBThread thread;
+ };
+
+ virtual
+ ~TestCase ()
+ {}
+
+ virtual void
+ Setup (int argc, const char** argv);
+
+ virtual ActionWanted
+ TestStep (int counter) = 0;
+
+ bool
+ Launch (const char** args, const char* cwd);
+
+ void
+ Loop();
+
+ void
+ SetVerbose (bool);
+
+ bool
+ GetVerbose ();
+
+ virtual void
+ Results () = 0;
+
+ template <typename G,typename A>
+ Measurement<G,A> CreateMeasurement (A a, const char* name = NULL)
+ {
+ return Measurement<G,A> (a,name);
+ }
+
+ static void
+ Run (TestCase& test, int argc, const char** argv);
+
+protected:
+ SBDebugger m_debugger;
+ SBTarget m_target;
+ SBProcess m_process;
+ SBThread m_thread;
+ SBListener m_listener;
+ bool m_verbose;
+};
+} }
+
+#endif /* defined(__PerfTestDriver__TestCase__) */
diff --git a/lldb/tools/lldb-perf/lib/Timer.cpp b/lldb/tools/lldb-perf/lib/Timer.cpp
new file mode 100644
index 00000000000..59871aab4ce
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/Timer.cpp
@@ -0,0 +1,47 @@
+//
+// Timer.cpp
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/6/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "Timer.h"
+#include <assert.h>
+
+using namespace lldb::perf;
+
+TimeGauge::HPTime
+TimeGauge::now ()
+{
+ return high_resolution_clock::now();
+}
+
+TimeGauge::TimeGauge () :
+m_start(),
+m_state(TimeGauge::State::eTSNeverUsed)
+{
+}
+
+void
+TimeGauge::start ()
+{
+ m_state = TimeGauge::State::eTSCounting;
+ m_start = now();
+}
+
+double
+TimeGauge::stop ()
+{
+ auto stop = now();
+ assert(m_state == TimeGauge::State::eTSCounting && "cannot stop a non-started clock");
+ m_state = TimeGauge::State::eTSStopped;
+ return (m_value = duration_cast<duration<double>>(stop-m_start).count());
+}
+
+double
+TimeGauge::value ()
+{
+ assert(m_state == TimeGauge::State::eTSStopped && "clock must be used before you can evaluate it");
+ return m_value;
+}
diff --git a/lldb/tools/lldb-perf/lib/Timer.h b/lldb/tools/lldb-perf/lib/Timer.h
new file mode 100644
index 00000000000..c877a3d3c9e
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/Timer.h
@@ -0,0 +1,56 @@
+//
+// Timer.h
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/6/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__Timer__
+#define __PerfTestDriver__Timer__
+
+#include "Gauge.h"
+
+#include <chrono>
+
+using namespace std::chrono;
+
+namespace lldb { namespace perf
+{
+class TimeGauge : public Gauge<double>
+{
+private:
+ enum class State
+ {
+ eTSNeverUsed,
+ eTSCounting,
+ eTSStopped
+ };
+
+ typedef high_resolution_clock::time_point HPTime;
+ HPTime m_start;
+ double m_value;
+ State m_state;
+
+ HPTime
+ now ();
+
+public:
+ TimeGauge ();
+
+ virtual
+ ~TimeGauge ()
+ {}
+
+ void
+ start ();
+
+ double
+ stop ();
+
+ double
+ value ();
+};
+} }
+
+#endif /* defined(__PerfTestDriver__Timer__) */
diff --git a/lldb/tools/lldb-perf/lib/Xcode.cpp b/lldb/tools/lldb-perf/lib/Xcode.cpp
new file mode 100644
index 00000000000..fd2d2c4406c
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/Xcode.cpp
@@ -0,0 +1,164 @@
+//
+// Xcode.cpp
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/6/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#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 = %llu %s\n",value.GetTypeName(),value.GetName(),num_value,summary);
+ if (expand > 0)
+ {
+ auto count = value.GetNumChildren();
+ for (int i = 0; i < count; i++)
+ {
+ SBValue child(value.GetChildAtIndex(i));
+ 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("%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);
+}
diff --git a/lldb/tools/lldb-perf/lib/Xcode.h b/lldb/tools/lldb-perf/lib/Xcode.h
new file mode 100644
index 00000000000..670fdcbc24f
--- /dev/null
+++ b/lldb/tools/lldb-perf/lib/Xcode.h
@@ -0,0 +1,63 @@
+//
+// Xcode.h
+// PerfTestDriver
+//
+// Created by Enrico Granata on 3/6/13.
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__Xcode__
+#define __PerfTestDriver__Xcode__
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBValue.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBModule.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBLineEntry.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandReturnObject.h"
+#include "lldb/API/SBBreakpoint.h"
+
+using namespace lldb;
+
+namespace lldb { namespace 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__) */
OpenPOWER on IntegriCloud