aboutsummaryrefslogtreecommitdiff
path: root/tools/lldb-perf/darwin/sketch/sketch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lldb-perf/darwin/sketch/sketch.cpp')
-rw-r--r--tools/lldb-perf/darwin/sketch/sketch.cpp380
1 files changed, 380 insertions, 0 deletions
diff --git a/tools/lldb-perf/darwin/sketch/sketch.cpp b/tools/lldb-perf/darwin/sketch/sketch.cpp
new file mode 100644
index 000000000000..93e39165c133
--- /dev/null
+++ b/tools/lldb-perf/darwin/sketch/sketch.cpp
@@ -0,0 +1,380 @@
+//===-- sketch.cpp ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#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>
+#include <getopt.h>
+
+using namespace lldb_perf;
+
+static struct option g_long_options[] = {
+ { "verbose", no_argument, NULL, 'v' },
+ { "sketch", required_argument, NULL, 'c' },
+ { "foobar", required_argument, NULL, 'f' },
+ { "out-file", required_argument, NULL, 'o' },
+ { NULL, 0, NULL, 0 }
+};
+
+class SketchTest : public TestCase
+{
+public:
+ SketchTest () :
+ m_fetch_frames_measurement ([this] () -> void
+ {
+ Xcode::FetchFrames (GetProcess(),false,false);
+ }, "fetch-frames", "time to dump backtrace for every frame in every thread"),
+ m_file_line_bp_measurement([this] (const char* file, uint32_t line) -> void
+ {
+ Xcode::CreateFileLineBreakpoint(GetTarget(), file, line);
+ }, "file-line-bkpt", "time to set a breakpoint given a file and line"),
+ m_fetch_modules_measurement ([this] () -> void
+ {
+ Xcode::FetchModules(GetTarget());
+ }, "fetch-modules", "time to get info for all modules in the process"),
+ m_fetch_vars_measurement([this] (int depth) -> void
+ {
+ SBProcess process (GetProcess());
+ 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", "time to dump variables for the topmost frame in every thread"),
+ 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", "time to evaluate an expression and display the result")
+ {
+ m_app_path.clear();
+ m_out_path.clear();
+ m_doc_path.clear();
+ m_print_help = false;
+ }
+
+ virtual
+ ~SketchTest ()
+ {
+ }
+
+ virtual bool
+ ParseOption (int short_option, const char* optarg)
+ {
+ switch (short_option)
+ {
+ case 0:
+ return false;
+
+ case -1:
+ return false;
+
+ case '?':
+ case 'h':
+ m_print_help = true;
+ break;
+
+ case 'v':
+ SetVerbose(true);
+ break;
+
+ case 'c':
+ {
+ SBFileSpec file(optarg);
+ if (file.Exists())
+ SetExecutablePath(optarg);
+ else
+ fprintf(stderr, "error: file specified in --sketch (-c) option doesn't exist: '%s'\n", optarg);
+ }
+ break;
+
+ case 'f':
+ {
+ SBFileSpec file(optarg);
+ if (file.Exists())
+ SetDocumentPath(optarg);
+ else
+ fprintf(stderr, "error: file specified in --foobar (-f) option doesn't exist: '%s'\n", optarg);
+ }
+ break;
+
+ case 'o':
+ SetResultFilePath(optarg);
+ break;
+
+ default:
+ m_print_help = true;
+ fprintf (stderr, "error: unrecognized option %c\n", short_option);
+ break;
+ }
+ return true;
+ }
+
+ virtual struct option*
+ GetLongOptions ()
+ {
+ return g_long_options;
+ }
+
+ virtual bool
+ Setup (int& argc, const char**& argv)
+ {
+ TestCase::Setup(argc,argv);
+ bool error = false;
+
+ if (GetExecutablePath() == NULL)
+ {
+ // --sketch is mandatory
+ error = true;
+ fprintf (stderr, "error: the '--sketch=PATH' option is mandatory\n");
+ }
+
+ if (GetDocumentPath() == NULL)
+ {
+ // --foobar is mandatory
+ error = true;
+ fprintf (stderr, "error: the '--foobar=PATH' option is mandatory\n");
+ }
+
+ if (error || GetPrintHelp())
+ {
+ puts(R"(
+ NAME
+ lldb_perf_sketch -- a tool that measures LLDB peformance while debugging sketch.
+
+ SYNOPSIS
+ lldb_perf_sketch --sketch=PATH --foobar=PATH [--out-file=PATH --verbose]
+
+ DESCRIPTION
+ Runs a set of static timing and memory tasks against sketch and outputs results
+ to a plist file.
+ )");
+ }
+
+ if (error)
+ {
+ exit(1);
+ }
+ lldb::SBLaunchInfo launch_info = GetLaunchInfo();
+ m_target = m_debugger.CreateTarget(m_app_path.c_str());
+ m_file_line_bp_measurement("SKTDocument.m",245);
+ m_file_line_bp_measurement("SKTDocument.m",283);
+ m_file_line_bp_measurement("SKTText.m",326);
+ return Launch (launch_info);
+ }
+
+ lldb::SBLaunchInfo
+ GetLaunchInfo ()
+ {
+ 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};
+ return SBLaunchInfo(args);
+ }
+
+ void
+ DoTest ()
+ {
+ m_fetch_frames_measurement();
+ m_fetch_modules_measurement();
+ m_fetch_vars_measurement(1);
+ }
+
+ virtual void
+ TestStep (int counter, ActionWanted &next_action)
+ {
+ static int launch = 1;
+ switch (counter % 10)
+ {
+ case 0:
+ {
+ DoTest ();
+ if (counter == 0)
+ m_file_line_bp_measurement("SKTDocument.m",254);
+ next_action.Continue();
+ }
+ break;
+
+ case 1:
+ {
+ DoTest ();
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"properties");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[properties description]");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"typeName");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"data");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[data description]");
+ next_action.Continue();
+ }
+ break;
+
+ case 2:
+ {
+ DoTest ();
+ next_action.Continue();
+ }
+ break;
+
+ case 3:
+ {
+ DoTest ();
+ next_action.StepOver(m_thread);
+ }
+ break;
+
+ case 4:
+ {
+ DoTest ();
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"layoutManager");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"contents");
+ next_action.StepOver(m_thread);
+ }
+ break;
+
+ case 5:
+ {
+ DoTest ();
+ next_action.StepOver(m_thread);
+ }
+ break;
+
+ case 6:
+ {
+ DoTest ();
+ next_action.StepOver(m_thread);
+ }
+ break;
+
+ case 7:
+ {
+ DoTest ();
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"@\"an NSString\"");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[(id)@\"an NSString\" description]");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"@[@1,@2,@3]");
+ next_action.StepOut(m_thread);
+ }
+ break;
+
+ case 8:
+ {
+ DoTest ();
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[graphics description]");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[selectionIndexes description]");
+ m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"(BOOL)NSIntersectsRect(rect, graphicDrawingBounds)");
+ }
+ next_action.CallNext();
+ break;
+ case 9:
+ if (++launch < 10)
+ next_action.Relaunch(GetLaunchInfo());
+ else
+ next_action.Kill();
+ break;
+
+
+ default:
+ {
+ next_action.Kill();
+ }
+ break;
+ }
+ }
+
+ virtual void
+ WriteResults (Results &results)
+ {
+ m_fetch_frames_measurement.WriteAverageAndStandardDeviation(results);
+ m_file_line_bp_measurement.WriteAverageAndStandardDeviation(results);
+ m_fetch_modules_measurement.WriteAverageAndStandardDeviation(results);
+ m_fetch_vars_measurement.WriteAverageAndStandardDeviation(results);
+ m_run_expr_measurement.WriteAverageAndStandardDeviation(results);
+ results.Write(GetResultFilePath());
+ }
+
+ void
+ SetExecutablePath (const char* str)
+ {
+ if (str)
+ m_app_path.assign(str);
+ }
+
+ const char*
+ GetExecutablePath ()
+ {
+ if (m_app_path.empty())
+ return NULL;
+ return m_app_path.c_str();
+ }
+
+ void
+ SetDocumentPath (const char* str)
+ {
+ if (str)
+ m_doc_path.assign(str);
+ }
+
+ const char*
+ GetDocumentPath ()
+ {
+ if (m_doc_path.empty())
+ return NULL;
+ return m_doc_path.c_str();
+ }
+
+
+ void
+ SetResultFilePath (const char* str)
+ {
+ if (str)
+ m_out_path.assign(str);
+ }
+
+ const char*
+ GetResultFilePath ()
+ {
+ if (m_out_path.empty())
+ return "/dev/stdout";
+ return m_out_path.c_str();
+ }
+
+ bool
+ GetPrintHelp ()
+ {
+ return m_print_help;
+ }
+
+private:
+ Measurement<lldb_perf::TimeGauge, std::function<void()>> m_fetch_frames_measurement;
+ Measurement<lldb_perf::TimeGauge, std::function<void(const char*, uint32_t)>> m_file_line_bp_measurement;
+ Measurement<lldb_perf::TimeGauge, std::function<void()>> m_fetch_modules_measurement;
+ Measurement<lldb_perf::TimeGauge, std::function<void(int)>> m_fetch_vars_measurement;
+ Measurement<lldb_perf::TimeGauge, std::function<void(SBFrame, const char*)>> m_run_expr_measurement;
+
+ std::string m_app_path;
+ std::string m_doc_path;
+ std::string m_out_path;
+ bool m_print_help;
+};
+
+int main(int argc, const char * argv[])
+{
+ SketchTest test;
+ return TestCase::Run(test, argc, argv);
+}