diff options
Diffstat (limited to 'tools/lldb-perf')
26 files changed, 5451 insertions, 0 deletions
diff --git a/tools/lldb-perf/README b/tools/lldb-perf/README new file mode 100644 index 000000000000..7cec4faac2c8 --- /dev/null +++ b/tools/lldb-perf/README @@ -0,0 +1,295 @@ + The lldb-perf infrastructure for LLDB performance testing +=========================================================== + +lldb-perf is an infrastructure meant to simplify the creation of performance +tests for the LLDB debugger. It is contained in liblldbperf.a which is part of +the standard opensource checkout of LLDB + +Its main concepts are: +- Gauges: a gauge is a thing that takes a sample. Samples include elapsed time, + memory used, and energy consumed. +- Metrics: a metric is a collection of samples that knows how to do statistics + like sum() and average(). Metrics can be extended as needed. +- Measurements: a measurement is the thing that stores an action, a gauge and + a metric. You define measurements as in “take the time to run this function”, + “take the memory to run this block of code”, and then after you invoke it, + your stats will automagically be there. +- Tests: a test is a sequence of steps and measurements. + +Tests cases should be added as targets to the lldbperf.xcodeproj project. It +is probably easiest to duplicate one of the existing targets. In order to +write a test based on lldb-perf, you need to subclass lldb_perf::TestCase: + +using namespace lldb_perf; + +class FormattersTest : public TestCase +{ + +Usually, you will define measurements as variables of your test case class: + +private: + // C++ formatters + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_vector_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_list_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_map_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_string_measurement; + + // Cocoa formatters + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsstring_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsarray_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsdictionary_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsset_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsbundle_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsdate_measurement; + +A TimeMeasurement is, obviously, a class that measures “how much time to run +this block of code”. The block of code is passed as an std::function which you +can construct with a lambda! You need to give the prototype of your block of +code. In this example, we run blocks of code that take an SBValue and return +nothing. + +These blocks look like: + + m_dump_std_vector_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-vector", "time to dump an std::vector"); + +Here we are saying: make me a measurement named “std-vector”, whose +description is “time to dump an std::vector” and that takes the time required +to call lldb_perf::Xcode::FetchVariable(value,1,false). + +The Xcode class is a collection of utility functions that replicate common +Xcode patterns (FetchVariable unsurprisingly calls API functions that Xcode +could use when populating a variables view entry - the 1 means “expand 1 level +of depth” and the false means “do not dump the data to stdout”) + +A full constructor for a TestCase looks like: + +FormattersTest () : TestCase() +{ + m_dump_std_vector_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-vector", "time to dump an std::vector"); + m_dump_std_list_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-list", "time to dump an std::list"); + m_dump_std_map_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-map", "time to dump an std::map"); + m_dump_std_string_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-string", "time to dump an std::string"); + + m_dump_nsstring_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,0,false); + }, "ns-string", "time to dump an NSString"); + + m_dump_nsarray_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-array", "time to dump an NSArray"); + + m_dump_nsdictionary_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-dictionary", "time to dump an NSDictionary"); + + m_dump_nsset_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-set", "time to dump an NSSet"); + + m_dump_nsbundle_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-bundle", "time to dump an NSBundle"); + + m_dump_nsdate_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,0,false); + }, "ns-date", "time to dump an NSDate"); +} + +Once your test case is constructed, Setup() is called on it: + + virtual bool + Setup (int argc, const char** argv) + { + m_app_path.assign(argv[1]); + m_out_path.assign(argv[2]); + m_target = m_debugger.CreateTarget(m_app_path.c_str()); + m_target.BreakpointCreateByName("main"); + SBLaunchInfo launch_info (argv); + return Launch (launch_info); + } + +Setup() returns a boolean value that indicates if setup was successful. +In Setup() you fill out a SBLaunchInfo with any needed settings for launching +your process like arguments, environment variables, working directory, and +much more. + +The last thing you want to do in setup is call Launch(): + + bool + Launch (coSBLaunchInfo &launch_info); + +This ensures your target is now alive. Make sure to have a breakpoint created. + +Once you launched, the event loop is entered. The event loop waits for stops, +and when it gets one, it calls your test case’s TestStep() function: + + virtual void + TestStep (int counter, ActionWanted &next_action) + +the counter is the step id (a monotonically increasing counter). In TestStep() +you will essentially run your measurements and then return what you want the +driver to do by filling in the ActionWanted object named "next_action". + +Possible options are: +- continue process next_action.Continue(); +- kill process next_action.Kill(); +- Step-out on a thread next_action.StepOut(SBThread) +- step-over on a thread. next_action.StepOver(SBThread) + +If you use ActionWanted::Next() or ActionWanted::Finish() you need to specify +a thread to use. By default the TestCase class will select the first thread +that had a stop reason other than eStopReasonNone and place it into the +m_thread member variable of TestCase. This means if your test case hits a +breakpoint or steps, the thread that hit the breakpoint or finished the step +will automatically be selected in the process (m_process) and m_thread will +be set to this thread. If you have one or more threads that will stop with a +reason simultaneously, you will need to find those threads manually by +iterating through the process list and determine what to do next. + +For your convenience TestCase has m_debugger, m_target and m_process as member +variables. As state above m_thread will be filled in with the first thread +that has a stop reason. + +An example: + + virtual void + TestStep (int counter, ActionWanted &next_action) + { + case 0: + m_target.BreakpointCreateByLocation("fmts_tester.mm", 68); + next_action.Continue(); + break; + case 1: + DoTest (); + next_action.Continue(); + break; + case 2: + DoTest (); + next_action.StepOver(m_thread); + break; + +DoTest() is a function I define in my own class that calls the measurements: + void + DoTest () + { + SBThread thread_main(m_thread); + SBFrame frame_zero(thread_main.GetFrameAtIndex(0)); + + m_dump_nsarray_measurement(frame_zero.FindVariable("nsarray", lldb::eDynamicCanRunTarget)); + m_dump_nsarray_measurement(frame_zero.FindVariable("nsmutablearray", lldb::eDynamicCanRunTarget)); + + m_dump_nsdictionary_measurement(frame_zero.FindVariable("nsdictionary", lldb::eDynamicCanRunTarget)); + m_dump_nsdictionary_measurement(frame_zero.FindVariable("nsmutabledictionary", lldb::eDynamicCanRunTarget)); + + m_dump_nsstring_measurement(frame_zero.FindVariable("str0", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str1", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str2", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str3", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str4", lldb::eDynamicCanRunTarget)); + + m_dump_nsdate_measurement(frame_zero.FindVariable("me", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("cutie", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("mom", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("dad", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("today", lldb::eDynamicCanRunTarget)); + + m_dump_nsbundle_measurement(frame_zero.FindVariable("bundles", lldb::eDynamicCanRunTarget)); + m_dump_nsbundle_measurement(frame_zero.FindVariable("frameworks", lldb::eDynamicCanRunTarget)); + + m_dump_nsset_measurement(frame_zero.FindVariable("nsset", lldb::eDynamicCanRunTarget)); + m_dump_nsset_measurement(frame_zero.FindVariable("nsmutableset", lldb::eDynamicCanRunTarget)); + + m_dump_std_vector_measurement(frame_zero.FindVariable("vector", lldb::eDynamicCanRunTarget)); + m_dump_std_list_measurement(frame_zero.FindVariable("list", lldb::eDynamicCanRunTarget)); + m_dump_std_map_measurement(frame_zero.FindVariable("map", lldb::eDynamicCanRunTarget)); + + m_dump_std_string_measurement(frame_zero.FindVariable("sstr0", lldb::eDynamicCanRunTarget)); + m_dump_std_string_measurement(frame_zero.FindVariable("sstr1", lldb::eDynamicCanRunTarget)); + m_dump_std_string_measurement(frame_zero.FindVariable("sstr2", lldb::eDynamicCanRunTarget)); + m_dump_std_string_measurement(frame_zero.FindVariable("sstr3", lldb::eDynamicCanRunTarget)); + m_dump_std_string_measurement(frame_zero.FindVariable("sstr4", lldb::eDynamicCanRunTarget)); + } + +Essentially, you call your measurements as if they were functions, passing +them arguments and all, and they will do the right thing with gathering stats. + +The last step is usually to KILL the inferior and bail out: + + virtual ActionWanted + TestStep (int counter) + { +... + case 9: + DoTest (); + next_action.Continue(); + break; + case 10: + DoTest (); + next_action.Continue(); + break; + default: + next_action.Kill(); + break; + } + + +At the end, you define a Results() function: + + void + 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); + + CFURLRef file = CFURLCreateFromFileSystemRepresentation (NULL, + (const UInt8*)m_out_path.c_str(), + m_out_path.size(), + FALSE); + + CFURLWriteDataAndPropertiesToResource(file,xmlData,NULL,NULL); + } + +For now, pretty much copy this and just call Write() on all your measurements. +I plan to move this higher in the hierarchy (e.g. make a +TestCase::Write(filename) fairly soon). + +Your main() will look like: + +int main(int argc, const char * argv[]) +{ + MyTest test; + TestCase::Run (test, argc, argv); + return 0; +} + +If you are debugging your test, before Run() call + + test.SetVerbose(true); + +Feel free to send any questions and ideas for improvements. diff --git a/tools/lldb-perf/common/clang/build-clang.sh b/tools/lldb-perf/common/clang/build-clang.sh new file mode 100755 index 000000000000..3d9add79c4ab --- /dev/null +++ b/tools/lldb-perf/common/clang/build-clang.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +if [ -d "llvm-build" ]; then + echo "Using existing 'llvm-build' directory..." +else + mkdir llvm-build +fi + +cd llvm-build + +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 clang-only DEBUG_SYMBOLS=1 + rm -rf lib projects runtime unittests utils config.* + ( cd ./Debug/bin ; rm -rf ll* clang-check clang-tblgen count diagtool fpcmp macho-dump not opt yaml2obj FileCheck FileUpdate arcmt-test c-arcmt-test c-index-test bugpoint ) + ( cd ./tools ; rm -rf ll* clang-check clang-tblgen count diagtool fpcmp lto macho-dump not opt yaml2obj FileCheck FileUpdate arcmt-test c-arcmt-test c-index-test bugpoint ) + ( cd ./tools/clang ; rm -rf lib unittests utils ) + ( cd ./tools/clang/tools ; rm -rf arcmt-test c-arcmt-test c-index-test clang-check diagtool libclang ) + ( cd ../llvm ; rm -rf cmake configure docs examples projects *.txt *.TXT autoconf bindings test unittests utils ; find . -type d -name .svn -print0 | xargs -0 rm -rf ) + ( cd ../llvm/tools ; rm -rf *.txt bugpoint bugpoint-passes ll* lto macho-dump opt gold ) +fi + + + diff --git a/tools/lldb-perf/common/clang/lldb_perf_clang.cpp b/tools/lldb-perf/common/clang/lldb_perf_clang.cpp new file mode 100644 index 000000000000..ac9481c366ec --- /dev/null +++ b/tools/lldb-perf/common/clang/lldb_perf_clang.cpp @@ -0,0 +1,484 @@ +//===-- lldb_perf_clang.cpp -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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 "llvm/ADT/STLExtras.h" +#include <iostream> +#include <unistd.h> +#include <fstream> +#include <getopt.h> + +using namespace lldb_perf; + +#define NUM_EXPR_ITERATIONS 3 +class ClangTest : public TestCase +{ +public: + ClangTest () : + TestCase(), + m_time_create_target ([this] () -> void + { + m_memory_change_create_target.Start(); + m_target = m_debugger.CreateTarget(m_exe_path.c_str()); + m_memory_change_create_target.Stop(); + }, "time-create-target", "The time it takes to create a target."), + m_time_set_bp_main([this] () -> void + { + m_memory_change_break_main.Start(); + m_target.BreakpointCreateByName("main"); + m_memory_change_break_main.Stop(); + }, "time-set-break-main", "Elapsed time it takes to set a breakpoint at 'main' by name."), + m_memory_change_create_target (), + m_memory_change_break_main (), + m_memory_total (), + m_time_launch_stop_main(), + m_time_total (), + m_expr_first_evaluate([this] (SBFrame frame) -> void + { + frame.EvaluateExpression("Diags.DiagArgumentsStr[0].size()").GetError(); + }, "time-expr", "Elapsed time it takes to evaluate an expression for the first time."), + m_expr_frame_zero ([this] (SBFrame frame) -> void + { + frame.EvaluateExpression("Diags.DiagArgumentsStr[0].size()").GetError(); + }, "time-expr-frame-zero", "Elapsed time it takes to evaluate an expression 3 times at frame zero."), + m_expr_frame_non_zero ([this] (SBFrame frame) -> void + { + frame.EvaluateExpression("Diags.DiagArgumentsStr[0].size()").GetError(); + }, "time-expr-frame-non-zero", "Elapsed time it takes to evaluate an expression 3 times at a non-zero frame."), + m_exe_path(), + m_out_path(), + m_launch_info (NULL), + m_use_dsym (false) + { + } + + virtual + ~ClangTest () + { + } + + virtual bool + Setup (int& argc, const char**& argv) + { + if (m_exe_path.empty()) + return false; + m_launch_info.SetArguments(argv, false); + return true; + } + + void + DoTest () + { + } + + virtual void + TestStep (int counter, ActionWanted &next_action) + { + char temp_source_path[PATH_MAX] = "/tmp/main.XXXXXX.cpp"; + + switch (counter) + { + case 0: + { + //Xcode::RunCommand(m_debugger,"log enable -f /tmp/packets.txt gdb-remote packets",true); + + m_memory_total.Start(); + m_time_total.Start(); + + // Time creating the target + m_time_create_target(); + + m_time_set_bp_main(); + + int fd = mkstemps(temp_source_path, 4); + + if (fd >= 0) + { + const char *source_content = R"( +#include <stdio.h> +#include <stdint.h> +#include <vector> + +namespace { + struct Foo + { + int i; int j; + }; + void doit (const Foo &foo) + { + printf ("doit(%i)\n", foo.i); + } +} + +int main (int argc, char const *argv[], char const *envp[]) +{ + std::vector<int> ints; + for (int i=0;i<10;++i) + ints.push_back(i); + printf ("hello world\n"); + Foo foo = { 12, 13 }; + doit (foo); + return 0; +} +)"; + write (fd, source_content, strlen(source_content)); + close(fd); + } + else + { + const char *error_cstr = strerror(errno); + fprintf (stderr, "error: failed to created temporary source file: '%s' (%s)", temp_source_path, error_cstr); + exit(2); + } + + m_time_launch_stop_main.Start(); + const char *clang_argv[] = { + "-cc1", + "-triple", "x86_64-apple-macosx10.8.0", + "-emit-obj", + "-mrelax-all", + "-disable-free", + "-disable-llvm-verifier", + "-main-file-name", "main.cpp", + "-mrelocation-model", "pic", + "-pic-level", "2", + "-mdisable-fp-elim", + "-masm-verbose", + "-munwind-tables", + "-target-cpu", "core2", + "-target-linker-version", "132.10.1", + "-v", + "-g", + "-O0", + "-fdeprecated-macro", + "-ferror-limit", "19", + "-fmessage-length", "298", + "-stack-protector", "1", + "-mstackrealign", + "-fblocks", + "-fobjc-runtime=macosx-10.8.0", + "-fobjc-dispatch-method=mixed", + "-fencode-extended-block-signature", + "-fcxx-exceptions", + "-fexceptions", + "-fdiagnostics-show-option", + "-fcolor-diagnostics", + "-backend-option", + "-vectorize-loops", + "-o", "/tmp/main.o", + "-x", "c++", + NULL, + NULL }; + clang_argv[llvm::array_lengthof(clang_argv)-2] = temp_source_path; + SBLaunchInfo launch_info(clang_argv); + Launch (launch_info); + next_action.None(); // Don't continue or do anything, just wait for next event... + } + break; + case 1: + { + m_time_launch_stop_main.Stop(); + m_time_total.Stop(); + SBFrame frame (m_thread.GetFrameAtIndex(0)); + + // Time the first expression evaluation + m_expr_first_evaluate(frame); + + SBValue result; + for (size_t i=0; i<NUM_EXPR_ITERATIONS; ++i) + { + m_expr_frame_zero(frame); + } + m_target.BreakpointCreateByName("DeclContext::lookup"); + next_action.Continue(); + } + break; + case 2: + { + SBFrame frame (m_thread.GetFrameAtIndex(21)); + SBValue result; + for (size_t i=0; i<NUM_EXPR_ITERATIONS; ++i) + { + m_expr_frame_non_zero(frame); + } + next_action.Continue(); + } + break; + default: + m_memory_total.Stop(); + next_action.Kill(); + break; + } + } + + void + WriteResults (Results &results) + { + Results::Dictionary& results_dict = results.GetDictionary(); + + m_time_set_bp_main.WriteAverageAndStandardDeviation(results); + results_dict.Add ("memory-change-create-target", + "Memory increase that occurs due to creating the target.", + m_memory_change_create_target.GetDeltaValue().GetResult(NULL, NULL)); + + results_dict.Add ("memory-change-break-main", + "Memory increase that occurs due to setting a breakpoint at main by name.", + m_memory_change_break_main.GetDeltaValue().GetResult(NULL, NULL)); + + m_time_create_target.WriteAverageAndStandardDeviation(results); + m_expr_first_evaluate.WriteAverageAndStandardDeviation(results); + m_expr_frame_zero.WriteAverageAndStandardDeviation(results); + m_expr_frame_non_zero.WriteAverageAndStandardDeviation(results); + results_dict.Add ("memory-total-break-main", + "The total memory that the current process is using after setting the first breakpoint.", + m_memory_total.GetStopValue().GetResult(NULL, NULL)); + + results_dict.AddDouble("time-launch-stop-main", + "The time it takes to launch the process and stop at main.", + m_time_launch_stop_main.GetDeltaValue()); + + results_dict.AddDouble("time-total", + "The time it takes to create the target, set breakpoint at main, launch clang and hit the breakpoint at main.", + m_time_total.GetDeltaValue()); + results.Write(GetResultFilePath()); + } + + + + const char * + GetExecutablePath () const + { + if (m_exe_path.empty()) + return NULL; + return m_exe_path.c_str(); + } + + const char * + GetResultFilePath () const + { + if (m_out_path.empty()) + return NULL; + return m_out_path.c_str(); + } + + void + SetExecutablePath (const char *path) + { + if (path && path[0]) + m_exe_path = path; + else + m_exe_path.clear(); + } + + void + SetResultFilePath (const char *path) + { + if (path && path[0]) + m_out_path = path; + else + m_out_path.clear(); + } + + void + SetUseDSYM (bool b) + { + m_use_dsym = b; + } + + + +private: + // C++ formatters + TimeMeasurement<std::function<void()>> m_time_create_target; + TimeMeasurement<std::function<void()>> m_time_set_bp_main; + MemoryGauge m_memory_change_create_target; + MemoryGauge m_memory_change_break_main; + MemoryGauge m_memory_total; + TimeGauge m_time_launch_stop_main; + TimeGauge m_time_total; + TimeMeasurement<std::function<void(SBFrame)>> m_expr_first_evaluate; + TimeMeasurement<std::function<void(SBFrame)>> m_expr_frame_zero; + TimeMeasurement<std::function<void(SBFrame)>> m_expr_frame_non_zero; + std::string m_exe_path; + std::string m_out_path; + SBLaunchInfo m_launch_info; + bool m_use_dsym; + +}; + + +struct Options +{ + std::string clang_path; + std::string out_file; + bool verbose; + bool use_dsym; + bool error; + bool print_help; + + Options() : + verbose (false), + error (false), + print_help (false) + { + } +}; + +static struct option g_long_options[] = { + { "verbose", no_argument, NULL, 'v' }, + { "clang", required_argument, NULL, 'c' }, + { "out-file", required_argument, NULL, 'o' }, + { "dsym", no_argument, NULL, 'd' }, + { NULL, 0, NULL, 0 } +}; + + +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; +} + +int main(int argc, const char * argv[]) +{ + + // Prepare for & make calls to getopt_long_only. + + std::string short_option_string (GetShortOptionString(g_long_options)); + + ClangTest test; + + Options option_data; + bool done = false; + +#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(), + g_long_options, + &long_options_index); + + switch (short_option) + { + case 0: + // Already handled + break; + + case -1: + done = true; + break; + + case '?': + option_data.print_help = true; + break; + + case 'h': + option_data.print_help = true; + break; + + case 'v': + option_data.verbose = true; + break; + + case 'c': + { + SBFileSpec file(optarg); + if (file.Exists()) + test.SetExecutablePath(optarg); + else + fprintf(stderr, "error: file specified in --clang (-c) option doesn't exist: '%s'\n", optarg); + } + break; + + case 'o': + test.SetResultFilePath(optarg); + break; + + case 'd': + test.SetUseDSYM(true); + break; + + default: + option_data.error = true; + option_data.print_help = true; + fprintf (stderr, "error: unrecognized option %c\n", short_option); + break; + } + } + + + if (test.GetExecutablePath() == NULL) + { + // --clang is mandatory + option_data.print_help = true; + option_data.error = true; + fprintf (stderr, "error: the '--clang=PATH' option is mandatory\n"); + } + + if (option_data.print_help) + { + puts(R"( +NAME + lldb_perf_clang -- a tool that measures LLDB peformance while debugging clang. + +SYNOPSIS + lldb_perf_clang --clang=PATH [--out-file=PATH --verbose --dsym] -- [clang options] + +DESCRIPTION + Runs a set of static timing and memory tasks against clang and outputs results + to a plist file. +)"); + } + if (option_data.error) + { + exit(1); + } + + // Update argc and argv after parsing options + argc -= optind; + argv += optind; + + test.SetVerbose(true); + TestCase::Run(test, argc, argv); + return 0; +} + diff --git a/tools/lldb-perf/common/clang/main.cpp b/tools/lldb-perf/common/clang/main.cpp new file mode 100644 index 000000000000..709c3946fb2f --- /dev/null +++ b/tools/lldb-perf/common/clang/main.cpp @@ -0,0 +1,24 @@ +#include <stdio.h> +#include <stdint.h> +#include <vector> + +namespace { + struct Foo + { + int i; int j; + }; + void doit (const Foo &foo) + { + printf ("doit(%i)\n", foo.i); + } +} +int main (int argc, char const *argv[], char const *envp[]) +{ + std::vector<int> ints; + for (int i=0;i<10;++i) + ints.push_back(i); + printf ("hello world\n"); + Foo foo = { 12, 13 }; + doit (foo); + return 0; +} diff --git a/tools/lldb-perf/common/stepping/lldb-perf-stepping.cpp b/tools/lldb-perf/common/stepping/lldb-perf-stepping.cpp new file mode 100644 index 000000000000..bb607ef06fa7 --- /dev/null +++ b/tools/lldb-perf/common/stepping/lldb-perf-stepping.cpp @@ -0,0 +1,335 @@ +#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 <unistd.h> +#include <string> +#include <getopt.h> + +using namespace lldb_perf; + +class StepTest : public TestCase +{ + typedef void (*no_function) (void); + +public: + StepTest(bool use_single_stepping = false) : + m_main_source("stepping-testcase.cpp"), + m_use_single_stepping(use_single_stepping), + m_time_measurements(nullptr) + { + } + + virtual + ~StepTest() {} + + virtual bool + Setup (int& argc, const char**& argv) + { + TestCase::Setup (argc, argv); + + // Toggle the fast stepping command on or off as required. + const char *single_step_cmd = "settings set target.use-fast-stepping false"; + const char *fast_step_cmd = "settings set target.use-fast-stepping true"; + const char *cmd_to_use; + + if (m_use_single_stepping) + cmd_to_use = single_step_cmd; + else + cmd_to_use = fast_step_cmd; + + SBCommandReturnObject return_object; + m_debugger.GetCommandInterpreter().HandleCommand(cmd_to_use, + return_object); + if (!return_object.Succeeded()) + { + if (return_object.GetError() != NULL) + printf ("Got an error running settings set: %s.\n", return_object.GetError()); + else + printf ("Failed running settings set, no error.\n"); + } + + m_target = m_debugger.CreateTarget(m_app_path.c_str()); + m_first_bp = m_target.BreakpointCreateBySourceRegex("Here is some code to stop at originally.", m_main_source); + + const char* file_arg = m_app_path.c_str(); + const char* empty = nullptr; + const char* args[] = {file_arg, empty}; + SBLaunchInfo launch_info (args); + + return Launch (launch_info); + } + + void + WriteResults (Results &results) + { + // Gotta turn off the last timer now. + m_individual_step_times.push_back(m_time_measurements.Stop()); + + size_t num_time_measurements = m_individual_step_times.size(); + + Results::Dictionary& results_dict = results.GetDictionary(); + const char *short_format_string = "step-time-%0.2d"; + const size_t short_size = strlen(short_format_string) + 5; + char short_buffer[short_size]; + const char *long_format_string = "The time it takes for step %d in the step sequence."; + const size_t long_size = strlen(long_format_string) + 5; + char long_buffer[long_size]; + + for (size_t i = 0; i < num_time_measurements; i++) + { + snprintf (short_buffer, short_size, short_format_string, i); + snprintf (long_buffer, long_size, long_format_string, i); + + results_dict.AddDouble(short_buffer, + long_buffer, + m_individual_step_times[i]); + + } + results_dict.AddDouble ("total-time", "Total time spent stepping.", m_time_measurements.GetMetric().GetSum()); + results_dict.AddDouble ("stddev-time", "StdDev of time spent stepping.", m_time_measurements.GetMetric().GetStandardDeviation()); + + results.Write(m_out_path.c_str()); + } + + + const char * + GetExecutablePath () const + { + if (m_app_path.empty()) + return NULL; + return m_app_path.c_str(); + } + + const char * + GetResultFilePath () const + { + if (m_out_path.empty()) + return NULL; + return m_out_path.c_str(); + } + + void + SetExecutablePath (const char *path) + { + if (path && path[0]) + m_app_path = path; + else + m_app_path.clear(); + } + + void + SetResultFilePath (const char *path) + { + if (path && path[0]) + m_out_path = path; + else + m_out_path.clear(); + } + + void + SetUseSingleStep (bool use_it) + { + m_use_single_stepping = use_it; + } +private: + virtual void + TestStep (int counter, ActionWanted &next_action) + { + if (counter > 0) + { + m_individual_step_times.push_back(m_time_measurements.Stop()); + + } + + // Disable the breakpoint, just in case it gets multiple locations we don't want that confusing the stepping. + if (counter == 0) + m_first_bp.SetEnabled(false); + + next_action.StepOver(m_process.GetThreadAtIndex(0)); + m_time_measurements.Start(); + + + } + + SBBreakpoint m_first_bp; + SBFileSpec m_main_source; + TimeMeasurement<no_function> m_time_measurements; + std::vector<double> m_individual_step_times; + bool m_use_single_stepping; + std::string m_app_path; + std::string m_out_path; + + +}; + +struct Options +{ + std::string test_file_path; + std::string out_file; + bool verbose; + bool fast_step; + bool error; + bool print_help; + + Options() : + verbose (false), + fast_step (true), + error (false), + print_help (false) + { + } +}; + +static struct option g_long_options[] = { + { "verbose", no_argument, NULL, 'v' }, + { "single-step", no_argument, NULL, 's' }, + { "test-file", required_argument, NULL, 't' }, + { "out-file", required_argument, NULL, 'o' }, + { NULL, 0, NULL, 0 } +}; + + +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; +} + +int main(int argc, const char * argv[]) +{ + + // Prepare for & make calls to getopt_long_only. + + std::string short_option_string (GetShortOptionString(g_long_options)); + + StepTest test; + + Options option_data; + bool done = false; + +#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(), + g_long_options, + &long_options_index); + + switch (short_option) + { + case 0: + // Already handled + break; + + case -1: + done = true; + break; + + case '?': + option_data.print_help = true; + break; + + case 'h': + option_data.print_help = true; + break; + + case 'v': + option_data.verbose = true; + break; + + case 's': + option_data.fast_step = false; + test.SetUseSingleStep(true); + break; + + case 't': + { + SBFileSpec file(optarg); + if (file.Exists()) + test.SetExecutablePath(optarg); + else + fprintf(stderr, "error: file specified in --test-file (-t) option doesn't exist: '%s'\n", optarg); + } + break; + + case 'o': + test.SetResultFilePath(optarg); + break; + + default: + option_data.error = true; + option_data.print_help = true; + fprintf (stderr, "error: unrecognized option %c\n", short_option); + break; + } + } + + + if (option_data.print_help) + { + puts(R"( +NAME + lldb-perf-stepping -- a tool that measures LLDB peformance of simple stepping operations. + +SYNOPSIS + lldb-perf-stepping --test-file=FILE [--out-file=PATH --verbose --fast-step] + +DESCRIPTION + Runs a set of stepping operations, timing each step and outputs results + to a plist file. +)"); + exit(0); + } + if (option_data.error) + { + exit(1); + } + + if (test.GetExecutablePath() == NULL) + { + // --clang is mandatory + option_data.print_help = true; + option_data.error = true; + fprintf (stderr, "error: the '--test-file=PATH' option is mandatory\n"); + } + + // Update argc and argv after parsing options + argc -= optind; + argv += optind; + + test.SetVerbose(true); + TestCase::Run(test, argc, argv); + return 0; +} diff --git a/tools/lldb-perf/common/stepping/stepping-testcase.cpp b/tools/lldb-perf/common/stepping/stepping-testcase.cpp new file mode 100644 index 000000000000..f842c2379c1a --- /dev/null +++ b/tools/lldb-perf/common/stepping/stepping-testcase.cpp @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <vector> +#include <string> + +struct struct_for_copying +{ + struct_for_copying (int in_int, double in_double, const char *in_string) : + int_value(in_int), + double_value(in_double), + string_value (in_string) + { + + } + struct_for_copying() + { + struct_for_copying (0, 0, ""); + } + + int int_value; + double double_value; + std::string string_value; +}; + +int main (int argc, char **argv) +{ + struct_for_copying input_struct (150 * argc, 10.0 * argc, argv[0]); + struct_for_copying output_struct; + int some_int = 44; + double some_double = 34.5; + double other_double; + size_t vector_size; + std::vector<struct_for_copying> my_vector; + + printf ("Here is some code to stop at originally. Got: %d, %p.\n", argc, argv); + output_struct = input_struct; + other_double = (some_double * some_int)/((double) argc); + other_double = other_double > 0 ? some_double/other_double : some_double > 0 ? other_double/some_double : 10.0; + my_vector.push_back (input_struct); + vector_size = my_vector.size(); + + return vector_size == 0 ? 0 : 1; +} diff --git a/tools/lldb-perf/darwin/formatters/fmts_tester.mm b/tools/lldb-perf/darwin/formatters/fmts_tester.mm new file mode 100644 index 000000000000..57ce008297d9 --- /dev/null +++ b/tools/lldb-perf/darwin/formatters/fmts_tester.mm @@ -0,0 +1,79 @@ +//===-- fmts_tester.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#import <Cocoa/Cocoa.h> +#include <vector> +#include <list> +#include <map> +#include <string> + +int main() +{ + NSArray* nsarray = @[@1,@2,@"hello world",@3,@4,@"foobar"]; + NSMutableArray* nsmutablearray = [[NSMutableArray alloc] initWithCapacity:5]; + [nsmutablearray addObject:@1]; + [nsmutablearray addObject:@2]; + [nsmutablearray addObject:@"hello world"]; + [nsmutablearray addObject:@3]; + [nsmutablearray addObject:@4]; + [nsmutablearray addObject:@"foobar"]; + NSDictionary* nsdictionary = @{@1 : @1, @2 : @2, @"hello" : @"world", @3 : @3}; + NSMutableDictionary* nsmutabledictionary = [[NSMutableDictionary alloc] initWithCapacity:5]; + [nsmutabledictionary setObject:@1 forKey:@1]; + [nsmutabledictionary setObject:@2 forKey:@2]; + [nsmutabledictionary setObject:@"hello" forKey:@"world"]; + [nsmutabledictionary setObject:@3 forKey:@3]; + NSString* str0 = @"Hello world"; + NSString* str1 = @"Hello ℥"; + NSString* str2 = @"Hello world"; + NSString* str3 = @"Hello ℥"; + NSString* str4 = @"Hello world"; + NSDate* me = [NSDate dateWithNaturalLanguageString:@"April 10, 1985"]; + NSDate* cutie = [NSDate dateWithNaturalLanguageString:@"January 29, 1983"]; + NSDate* mom = [NSDate dateWithNaturalLanguageString:@"May 24, 1959"]; + NSDate* dad = [NSDate dateWithNaturalLanguageString:@"October 29, 1954"]; + NSDate* today = [NSDate dateWithNaturalLanguageString:@"March 14, 2013"]; + NSArray* bundles = [NSBundle allBundles]; + NSArray* frameworks = [NSBundle allFrameworks]; + NSSet* nsset = [NSSet setWithArray:nsarray]; + NSMutableSet* nsmutableset = [NSMutableSet setWithCapacity:5]; + [nsmutableset addObject:@1]; + [nsmutableset addObject:@2]; + [nsmutableset addObject:@"hello world"]; + [nsmutableset addObject:@3]; + [nsmutableset addObject:@4]; + [nsmutableset addObject:@"foobar"]; + std::vector<int> vector; + vector.push_back(1); + vector.push_back(2); + vector.push_back(3); + vector.push_back(4); + vector.push_back(5); + std::list<int> list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.push_back(4); + list.push_back(5); + std::map<int,int> map; + map[1] = 1; + map[2] = 2; + map[3] = 3; + map[4] = 4; + map[5] = 5; + std::string sstr0("Hello world"); + std::string sstr1("Hello world"); + std::string sstr2("Hello world"); + std::string sstr3("Hello world"); + std::string sstr4("Hello world"); + int x = 0; + for (;;) + x++; +}
\ No newline at end of file diff --git a/tools/lldb-perf/darwin/formatters/formatters.cpp b/tools/lldb-perf/darwin/formatters/formatters.cpp new file mode 100644 index 000000000000..ee3875618427 --- /dev/null +++ b/tools/lldb-perf/darwin/formatters/formatters.cpp @@ -0,0 +1,246 @@ +//===-- formatters.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> + +using namespace lldb_perf; + +class FormattersTest : public TestCase +{ +public: + FormattersTest () : TestCase() + { + m_dump_std_vector_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-vector", "time to dump an std::vector"); + m_dump_std_list_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-list", "time to dump an std::list"); + m_dump_std_map_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "std-map", "time to dump an std::map"); + + // use this in manual mode + m_dump_std_string_measurement = CreateTimeMeasurement([] () -> void { + }, "std-string", "time to dump an std::string"); + + m_dump_nsstring_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,0,false); + }, "ns-string", "time to dump an NSString"); + + m_dump_nsarray_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-array", "time to dump an NSArray"); + + m_dump_nsdictionary_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-dictionary", "time to dump an NSDictionary"); + + m_dump_nsset_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-set", "time to dump an NSSet"); + + m_dump_nsbundle_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,1,false); + }, "ns-bundle", "time to dump an NSBundle"); + + m_dump_nsdate_measurement = CreateTimeMeasurement([] (SBValue value) -> void { + lldb_perf::Xcode::FetchVariable (value,0,false); + }, "ns-date", "time to dump an NSDate"); + } + + virtual + ~FormattersTest () + { + } + + virtual bool + Setup (int& argc, const char**& argv) + { + m_app_path.assign(argv[1]); + m_out_path.assign(argv[2]); + m_target = m_debugger.CreateTarget(m_app_path.c_str()); + m_target.BreakpointCreateByName("main"); + SBLaunchInfo launch_info(argv); + return Launch (launch_info); + } + + void + DoTest () + { + SBFrame frame_zero(m_thread.GetFrameAtIndex(0)); + + m_dump_nsarray_measurement(frame_zero.FindVariable("nsarray", lldb::eDynamicCanRunTarget)); + m_dump_nsarray_measurement(frame_zero.FindVariable("nsmutablearray", lldb::eDynamicCanRunTarget)); + + m_dump_nsdictionary_measurement(frame_zero.FindVariable("nsdictionary", lldb::eDynamicCanRunTarget)); + m_dump_nsdictionary_measurement(frame_zero.FindVariable("nsmutabledictionary", lldb::eDynamicCanRunTarget)); + + m_dump_nsstring_measurement(frame_zero.FindVariable("str0", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str1", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str2", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str3", lldb::eDynamicCanRunTarget)); + m_dump_nsstring_measurement(frame_zero.FindVariable("str4", lldb::eDynamicCanRunTarget)); + + m_dump_nsdate_measurement(frame_zero.FindVariable("me", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("cutie", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("mom", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("dad", lldb::eDynamicCanRunTarget)); + m_dump_nsdate_measurement(frame_zero.FindVariable("today", lldb::eDynamicCanRunTarget)); + + m_dump_nsbundle_measurement(frame_zero.FindVariable("bundles", lldb::eDynamicCanRunTarget)); + m_dump_nsbundle_measurement(frame_zero.FindVariable("frameworks", lldb::eDynamicCanRunTarget)); + + m_dump_nsset_measurement(frame_zero.FindVariable("nsset", lldb::eDynamicCanRunTarget)); + m_dump_nsset_measurement(frame_zero.FindVariable("nsmutableset", lldb::eDynamicCanRunTarget)); + + m_dump_std_vector_measurement(frame_zero.FindVariable("vector", lldb::eDynamicCanRunTarget)); + m_dump_std_list_measurement(frame_zero.FindVariable("list", lldb::eDynamicCanRunTarget)); + m_dump_std_map_measurement(frame_zero.FindVariable("map", lldb::eDynamicCanRunTarget)); + + auto sstr0 = frame_zero.FindVariable("sstr0", lldb::eDynamicCanRunTarget); + auto sstr1 = frame_zero.FindVariable("sstr1", lldb::eDynamicCanRunTarget); + auto sstr2 = frame_zero.FindVariable("sstr2", lldb::eDynamicCanRunTarget); + auto sstr3 = frame_zero.FindVariable("sstr3", lldb::eDynamicCanRunTarget); + auto sstr4 = frame_zero.FindVariable("sstr4", lldb::eDynamicCanRunTarget); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr0,0,false); + m_dump_std_string_measurement.Stop(); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr1,0,false); + m_dump_std_string_measurement.Stop(); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr2,0,false); + m_dump_std_string_measurement.Stop(); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr3,0,false); + m_dump_std_string_measurement.Stop(); + + m_dump_std_string_measurement.Start(); + Xcode::FetchVariable(sstr4,0,false); + m_dump_std_string_measurement.Stop(); + + } + + virtual void + TestStep (int counter, ActionWanted &next_action) + { + switch (counter) + { + case 0: + m_target.BreakpointCreateByLocation("fmts_tester.mm", 78); + next_action.Continue(); + break; + case 1: + DoTest (); + next_action.Continue(); + break; + case 2: + DoTest (); + next_action.Continue(); + 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(); + break; + default: + next_action.Kill(); + break; + } + } + + virtual void + WriteResults (Results &results) + { + m_dump_std_vector_measurement.WriteAverageAndStandardDeviation(results); + m_dump_std_list_measurement.WriteAverageAndStandardDeviation(results); + m_dump_std_map_measurement.WriteAverageAndStandardDeviation(results); + m_dump_std_string_measurement.WriteAverageAndStandardDeviation(results); + + m_dump_nsstring_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsarray_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsdictionary_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsset_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsbundle_measurement.WriteAverageAndStandardDeviation(results); + m_dump_nsdate_measurement.WriteAverageAndStandardDeviation(results); + results.Write(m_out_path.c_str()); + } + +private: + // C++ formatters + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_vector_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_list_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_std_map_measurement; + TimeMeasurement<std::function<void()>> m_dump_std_string_measurement; + + // Cocoa formatters + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsstring_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsarray_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsdictionary_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsset_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsbundle_measurement; + TimeMeasurement<std::function<void(SBValue)>> m_dump_nsdate_measurement; + + // useful files + std::string m_app_path; + std::string m_out_path; +}; + +// argv[1] == path to app +// argv[2] == path to result +int main(int argc, const char * argv[]) +{ + FormattersTest frmtest; + frmtest.SetVerbose(true); + TestCase::Run(frmtest,argc,argv); + return 0; +} + diff --git a/tools/lldb-perf/darwin/sketch/foobar.sketch2 b/tools/lldb-perf/darwin/sketch/foobar.sketch2 Binary files differnew file mode 100644 index 000000000000..553c698b180c --- /dev/null +++ b/tools/lldb-perf/darwin/sketch/foobar.sketch2 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); +} diff --git a/tools/lldb-perf/lib/Gauge.cpp b/tools/lldb-perf/lib/Gauge.cpp new file mode 100644 index 000000000000..4c4593b3b292 --- /dev/null +++ b/tools/lldb-perf/lib/Gauge.cpp @@ -0,0 +1,53 @@ +//===-- 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())); +} diff --git a/tools/lldb-perf/lib/Gauge.h b/tools/lldb-perf/lib/Gauge.h new file mode 100644 index 000000000000..fc5c444a38b8 --- /dev/null +++ b/tools/lldb-perf/lib/Gauge.h @@ -0,0 +1,64 @@ +//===-- 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 diff --git a/tools/lldb-perf/lib/Measurement.h b/tools/lldb-perf/lib/Measurement.h new file mode 100644 index 000000000000..877e618d5469 --- /dev/null +++ b/tools/lldb-perf/lib/Measurement.h @@ -0,0 +1,217 @@ +//===-- 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 "Timer.h" +#include "Metric.h" +#include "MemoryGauge.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__) */ diff --git a/tools/lldb-perf/lib/MemoryGauge.cpp b/tools/lldb-perf/lib/MemoryGauge.cpp new file mode 100644 index 000000000000..2a46453f540b --- /dev/null +++ b/tools/lldb-perf/lib/MemoryGauge.cpp @@ -0,0 +1,165 @@ +//===-- 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/task.h> +#include <mach/mach_traps.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); +} diff --git a/tools/lldb-perf/lib/MemoryGauge.h b/tools/lldb-perf/lib/MemoryGauge.h new file mode 100644 index 000000000000..a1221b6b66cc --- /dev/null +++ b/tools/lldb-perf/lib/MemoryGauge.h @@ -0,0 +1,147 @@ +//===-- 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__ diff --git a/tools/lldb-perf/lib/Metric.cpp b/tools/lldb-perf/lib/Metric.cpp new file mode 100644 index 000000000000..1951cdb0250a --- /dev/null +++ b/tools/lldb-perf/lib/Metric.cpp @@ -0,0 +1,85 @@ +//===-- 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>; diff --git a/tools/lldb-perf/lib/Metric.h b/tools/lldb-perf/lib/Metric.h new file mode 100644 index 000000000000..45342d25b41a --- /dev/null +++ b/tools/lldb-perf/lib/Metric.h @@ -0,0 +1,72 @@ +//===-- 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 <vector> +#include <string> +#include <mach/task_info.h> + +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__) */ diff --git a/tools/lldb-perf/lib/Results.cpp b/tools/lldb-perf/lib/Results.cpp new file mode 100644 index 000000000000..6abf67e53b67 --- /dev/null +++ b/tools/lldb-perf/lib/Results.cpp @@ -0,0 +1,275 @@ +//===-- 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); + + 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; + } +} + + + diff --git a/tools/lldb-perf/lib/Results.h b/tools/lldb-perf/lib/Results.h new file mode 100644 index 000000000000..388077e7f581 --- /dev/null +++ b/tools/lldb-perf/lib/Results.h @@ -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 "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__ diff --git a/tools/lldb-perf/lib/TestCase.cpp b/tools/lldb-perf/lib/TestCase.cpp new file mode 100644 index 000000000000..c23a5e519773 --- /dev/null +++ b/tools/lldb-perf/lib/TestCase.cpp @@ -0,0 +1,358 @@ +//===-- 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; +} + diff --git a/tools/lldb-perf/lib/TestCase.h b/tools/lldb-perf/lib/TestCase.h new file mode 100644 index 000000000000..811d0432b58a --- /dev/null +++ b/tools/lldb-perf/lib/TestCase.h @@ -0,0 +1,205 @@ +//===-- 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 "lldb/API/LLDB.h" +#include "Measurement.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__) */ diff --git a/tools/lldb-perf/lib/Timer.cpp b/tools/lldb-perf/lib/Timer.cpp new file mode 100644 index 000000000000..4bbab904c63e --- /dev/null +++ b/tools/lldb-perf/lib/Timer.cpp @@ -0,0 +1,61 @@ +//===-- 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; +} diff --git a/tools/lldb-perf/lib/Timer.h b/tools/lldb-perf/lib/Timer.h new file mode 100644 index 000000000000..ff179355cd43 --- /dev/null +++ b/tools/lldb-perf/lib/Timer.h @@ -0,0 +1,66 @@ +//===-- 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__) */ diff --git a/tools/lldb-perf/lib/Xcode.cpp b/tools/lldb-perf/lib/Xcode.cpp new file mode 100644 index 000000000000..7b35e1c8cb54 --- /dev/null +++ b/tools/lldb-perf/lib/Xcode.cpp @@ -0,0 +1,165 @@ +//===-- 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); +} diff --git a/tools/lldb-perf/lib/Xcode.h b/tools/lldb-perf/lib/Xcode.h new file mode 100644 index 000000000000..77e025369372 --- /dev/null +++ b/tools/lldb-perf/lib/Xcode.h @@ -0,0 +1,64 @@ +//===-- 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/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_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__) */ diff --git a/tools/lldb-perf/lldbperf.xcodeproj/project.pbxproj b/tools/lldb-perf/lldbperf.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..0750f700b11d --- /dev/null +++ b/tools/lldb-perf/lldbperf.xcodeproj/project.pbxproj @@ -0,0 +1,1224 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXAggregateTarget section */ + 4C1E37E316F7A0A500FF10BB /* All Perf Tests */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 4C1E37E416F7A0A600FF10BB /* Build configuration list for PBXAggregateTarget "All Perf Tests" */; + buildPhases = ( + ); + dependencies = ( + 4CE3706916FB6FCA00BFD501 /* PBXTargetDependency */, + 4CE3706B16FB6FCC00BFD501 /* PBXTargetDependency */, + 4CE3706D16FB6FCF00BFD501 /* PBXTargetDependency */, + 4CE3706F16FB6FD200BFD501 /* PBXTargetDependency */, + ); + name = "All Perf Tests"; + productName = All; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 26B902E51700FA8D00EFDCE2 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C86C5C616F7A37800844407 /* LLDB.framework */; }; + 26B902E61700FAE800EFDCE2 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C86C5C616F7A37800844407 /* LLDB.framework */; }; + 26DBAD6216FA63F0008243D2 /* lldb_perf_clang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DBAD4916FA637D008243D2 /* lldb_perf_clang.cpp */; }; + 26DBAD6316FA66DC008243D2 /* liblldbperf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E373916F4035D00FF10BB /* liblldbperf.a */; }; + 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 */; }; + 4C1E375116F407C800FF10BB /* MemoryGauge.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E374516F407C800FF10BB /* MemoryGauge.h */; }; + 4C1E375216F407C800FF10BB /* Metric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E374616F407C800FF10BB /* Metric.cpp */; }; + 4C1E375316F407C800FF10BB /* Metric.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E374716F407C800FF10BB /* Metric.h */; }; + 4C1E375416F407C800FF10BB /* TestCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E374816F407C800FF10BB /* TestCase.cpp */; }; + 4C1E375516F407C800FF10BB /* TestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E374916F407C800FF10BB /* TestCase.h */; }; + 4C1E375616F407C800FF10BB /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E374A16F407C800FF10BB /* Timer.cpp */; }; + 4C1E375716F407C800FF10BB /* Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E374B16F407C800FF10BB /* Timer.h */; }; + 4C1E375816F407C800FF10BB /* Xcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E374C16F407C800FF10BB /* Xcode.cpp */; }; + 4C1E375916F407C800FF10BB /* Xcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E374D16F407C800FF10BB /* Xcode.h */; }; + 4C1E377916F4089E00FF10BB /* sketch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E377816F4089E00FF10BB /* sketch.cpp */; }; + 4C1E377A16F4091700FF10BB /* liblldbperf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E373916F4035D00FF10BB /* liblldbperf.a */; }; + 4C1E378216F40B8900FF10BB /* CFCBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E375B16F4081300FF10BB /* CFCBundle.cpp */; }; + 4C1E378316F40B8C00FF10BB /* CFCData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E375D16F4081300FF10BB /* CFCData.cpp */; }; + 4C1E378416F40B8F00FF10BB /* CFCMutableArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E375F16F4081300FF10BB /* CFCMutableArray.cpp */; }; + 4C1E378516F40B9200FF10BB /* CFCMutableDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E376116F4081300FF10BB /* CFCMutableDictionary.cpp */; }; + 4C1E378616F40B9600FF10BB /* CFCMutableSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E376316F4081300FF10BB /* CFCMutableSet.cpp */; }; + 4C1E378716F40B9C00FF10BB /* CFCReleaser.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E376516F4081300FF10BB /* CFCReleaser.h */; }; + 4C1E378816F40B9F00FF10BB /* CFCString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E376616F4081300FF10BB /* CFCString.cpp */; }; + 4C1E378916F40BA200FF10BB /* CFCString.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E376716F4081300FF10BB /* CFCString.h */; }; + 4C1E378A16F40BA600FF10BB /* CoreFoundationCPP.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E376816F4081300FF10BB /* CoreFoundationCPP.h */; }; + 4C1E378B16F40BAB00FF10BB /* CFCBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E375C16F4081300FF10BB /* CFCBundle.h */; }; + 4C1E378C16F40BAF00FF10BB /* CFCData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E375E16F4081300FF10BB /* CFCData.h */; }; + 4C1E378D16F40BB300FF10BB /* CFCMutableArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E376016F4081300FF10BB /* CFCMutableArray.h */; }; + 4C1E378E16F40BB700FF10BB /* CFCMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E376216F4081300FF10BB /* CFCMutableDictionary.h */; }; + 4C1E378F16F40BBB00FF10BB /* CFCMutableSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1E376416F4081300FF10BB /* CFCMutableSet.h */; }; + 4C1E37C716F79EC300FF10BB /* liblldbperf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E373916F4035D00FF10BB /* liblldbperf.a */; }; + 4C1E37CB16F79EFA00FF10BB /* formatters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E37B416F79E4600FF10BB /* formatters.cpp */; }; + 4C1E37E016F7A05D00FF10BB /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E37DB16F7A03900FF10BB /* CoreFoundation.framework */; }; + 4C1E37E216F7A07300FF10BB /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C1E37DB16F7A03900FF10BB /* CoreFoundation.framework */; }; + 4C86C5CB16F7C1D300844407 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C86C5C616F7A37800844407 /* LLDB.framework */; }; + 4C86C5CC16F7C1E000844407 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C86C5C616F7A37800844407 /* LLDB.framework */; }; + 4C86C5DA16F7CED300844407 /* fmts_tester.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4C1E37B316F79E4600FF10BB /* fmts_tester.mm */; }; + 4CDDF51017011EBB00D95015 /* stepping-testcase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3708716FB70E100BFD501 /* stepping-testcase.cpp */; }; + 4CE3707316FB701000BFD501 /* lldb-perf-stepping.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE3707216FB701000BFD501 /* lldb-perf-stepping.cpp */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 264B3DE516F7E47600D1E7AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 26F5C26A10F3D9A4009D5894; + remoteInfo = "lldb-tool"; + }; + 264B3DE716F7E47600D1E7AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 26680207115FD0ED008E1FE4; + remoteInfo = LLDB; + }; + 264B3DE916F7E47600D1E7AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 26579F68126A25920007C5CB; + remoteInfo = "darwin-debug"; + }; + 264B3DEB16F7E47600D1E7AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 2689FFCA13353D7A00698AC0; + remoteInfo = "lldb-core"; + }; + 264B3DED16F7E47600D1E7AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 26DC6A101337FE6900FF7998; + remoteInfo = "lldb-platform"; + }; + 264B3DEF16F7E47600D1E7AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EDC6D49914E5C19B001B75F8; + remoteInfo = launcherXPCService; + }; + 264B3DF116F7E47600D1E7AB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = EDE274EC14EDCE1F005B0F75; + remoteInfo = launcherRootXPCService; + }; + 26B902D61700F9BD00EFDCE2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 26680206115FD0ED008E1FE4; + remoteInfo = LLDB; + }; + 26B902E21700F9CC00EFDCE2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C1E373816F4035D00FF10BB; + remoteInfo = lldbperf; + }; + 4C1E379016F40BCD00FF10BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C1E373816F4035D00FF10BB; + remoteInfo = lldbperf; + }; + 4C1E37C316F79EB000FF10BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C1E373816F4035D00FF10BB; + remoteInfo = lldbperf; + }; + 4C86C5DB16F7CF1200844407 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C86C5D016F7CC8900844407; + remoteInfo = "format-tester"; + }; + 4CE3706816FB6FCA00BFD501 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C1E376C16F4087A00FF10BB; + remoteInfo = "lldb-perf-sketch"; + }; + 4CE3706A16FB6FCC00BFD501 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C1E37B916F79E9D00FF10BB; + remoteInfo = "lldb-perf-formatters"; + }; + 4CE3706C16FB6FCF00BFD501 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 26DBAD5816FA63B1008243D2; + remoteInfo = "lldb-perf-clang"; + }; + 4CE3706E16FB6FD200BFD501 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4CE3705316FB6FA100BFD501; + remoteInfo = "lldb-perf-step"; + }; + 4CE3708A16FB711200BFD501 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4CE3707B16FB70AD00BFD501; + remoteInfo = "stepping-testcase"; + }; + 4CE3708C16FB712300BFD501 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C1E373116F4035D00FF10BB /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C1E373816F4035D00FF10BB; + remoteInfo = lldbperf; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 26DBAD5716FA63B1008243D2 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 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>"; }; + 4C1E374416F407C800FF10BB /* MemoryGauge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryGauge.cpp; sourceTree = "<group>"; }; + 4C1E374516F407C800FF10BB /* MemoryGauge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryGauge.h; sourceTree = "<group>"; }; + 4C1E374616F407C800FF10BB /* Metric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Metric.cpp; sourceTree = "<group>"; }; + 4C1E374716F407C800FF10BB /* Metric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Metric.h; sourceTree = "<group>"; }; + 4C1E374816F407C800FF10BB /* TestCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestCase.cpp; sourceTree = "<group>"; }; + 4C1E374916F407C800FF10BB /* TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestCase.h; sourceTree = "<group>"; }; + 4C1E374A16F407C800FF10BB /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = "<group>"; }; + 4C1E374B16F407C800FF10BB /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = "<group>"; }; + 4C1E374C16F407C800FF10BB /* Xcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Xcode.cpp; sourceTree = "<group>"; }; + 4C1E374D16F407C800FF10BB /* Xcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xcode.h; sourceTree = "<group>"; }; + 4C1E375B16F4081300FF10BB /* CFCBundle.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CFCBundle.cpp; sourceTree = "<group>"; }; + 4C1E375C16F4081300FF10BB /* CFCBundle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFCBundle.h; sourceTree = "<group>"; }; + 4C1E375D16F4081300FF10BB /* CFCData.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CFCData.cpp; sourceTree = "<group>"; }; + 4C1E375E16F4081300FF10BB /* CFCData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFCData.h; sourceTree = "<group>"; }; + 4C1E375F16F4081300FF10BB /* CFCMutableArray.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CFCMutableArray.cpp; sourceTree = "<group>"; }; + 4C1E376016F4081300FF10BB /* CFCMutableArray.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFCMutableArray.h; sourceTree = "<group>"; }; + 4C1E376116F4081300FF10BB /* CFCMutableDictionary.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CFCMutableDictionary.cpp; sourceTree = "<group>"; }; + 4C1E376216F4081300FF10BB /* CFCMutableDictionary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFCMutableDictionary.h; sourceTree = "<group>"; }; + 4C1E376316F4081300FF10BB /* CFCMutableSet.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CFCMutableSet.cpp; sourceTree = "<group>"; }; + 4C1E376416F4081300FF10BB /* CFCMutableSet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFCMutableSet.h; sourceTree = "<group>"; }; + 4C1E376516F4081300FF10BB /* CFCReleaser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFCReleaser.h; sourceTree = "<group>"; }; + 4C1E376616F4081300FF10BB /* CFCString.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CFCString.cpp; sourceTree = "<group>"; }; + 4C1E376716F4081300FF10BB /* CFCString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFCString.h; sourceTree = "<group>"; }; + 4C1E376816F4081300FF10BB /* CoreFoundationCPP.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreFoundationCPP.h; sourceTree = "<group>"; }; + 4C1E376D16F4087A00FF10BB /* lldb-perf-sketch */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-perf-sketch"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4C1E377716F4089E00FF10BB /* foobar.sketch2 */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = foobar.sketch2; sourceTree = "<group>"; }; + 4C1E377816F4089E00FF10BB /* sketch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sketch.cpp; sourceTree = "<group>"; }; + 4C1E37B316F79E4600FF10BB /* fmts_tester.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = fmts_tester.mm; sourceTree = "<group>"; }; + 4C1E37B416F79E4600FF10BB /* formatters.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = formatters.cpp; sourceTree = "<group>"; }; + 4C1E37BA16F79E9D00FF10BB /* lldb-perf-formatters */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-perf-formatters"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4C1E37DB16F7A03900FF10BB /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; }; + 4C86C5C316F7A35000844407 /* lldb.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = lldb.xcodeproj; path = ../../lldb.xcodeproj; 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-perf-step */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-perf-step"; sourceTree = BUILT_PRODUCTS_DIR; }; + 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>"; }; + 4CE3707C16FB70AD00BFD501 /* stepping-testcase */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "stepping-testcase"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4CE3708716FB70E100BFD501 /* stepping-testcase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "stepping-testcase.cpp"; path = "stepping/stepping-testcase.cpp"; sourceTree = "<group>"; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 26DBAD5616FA63B1008243D2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 26B902E61700FAE800EFDCE2 /* LLDB.framework in Frameworks */, + 26DBAD6516FA66EA008243D2 /* CoreFoundation.framework in Frameworks */, + 26DBAD6316FA66DC008243D2 /* liblldbperf.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C1E373616F4035D00FF10BB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C1E376A16F4087A00FF10BB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C86C5CC16F7C1E000844407 /* LLDB.framework in Frameworks */, + 4C1E377A16F4091700FF10BB /* liblldbperf.a in Frameworks */, + 4C1E37E016F7A05D00FF10BB /* CoreFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C1E37B716F79E9D00FF10BB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C86C5CB16F7C1D300844407 /* LLDB.framework in Frameworks */, + 4C1E37E216F7A07300FF10BB /* CoreFoundation.framework in Frameworks */, + 4C1E37C716F79EC300FF10BB /* liblldbperf.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C86C5CE16F7CC8900844407 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4CE3705116FB6FA100BFD501 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 26B902E51700FA8D00EFDCE2 /* LLDB.framework in Frameworks */, + 4CE3707716FB704B00BFD501 /* CoreFoundation.framework in Frameworks */, + 4CE3707616FB704300BFD501 /* LLDB.framework in Frameworks */, + 4CE3707516FB703B00BFD501 /* liblldbperf.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4CE3707916FB70AD00BFD501 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 26DBAD4616FA637D008243D2 /* common */ = { + isa = PBXGroup; + children = ( + 4CE3707416FB701E00BFD501 /* stepping */, + 26DBAD4716FA637D008243D2 /* clang */, + ); + path = common; + sourceTree = "<group>"; + }; + 26DBAD4716FA637D008243D2 /* clang */ = { + isa = PBXGroup; + children = ( + 26DBAD4816FA637D008243D2 /* build-clang.sh */, + 26DBAD4916FA637D008243D2 /* lldb_perf_clang.cpp */, + ); + path = clang; + sourceTree = "<group>"; + }; + 4C1E373016F4035D00FF10BB = { + isa = PBXGroup; + children = ( + 4C86C5C316F7A35000844407 /* lldb.xcodeproj */, + 4C1E37B516F79E6600FF10BB /* Darwin */, + 26DBAD4616FA637D008243D2 /* common */, + 4C1E375A16F4081300FF10BB /* cfcpp */, + 4C1E374116F407C800FF10BB /* lib */, + 4C1E373A16F4035D00FF10BB /* Products */, + 4C1E37DD16F7A03900FF10BB /* Frameworks */, + ); + sourceTree = "<group>"; + }; + 4C1E373A16F4035D00FF10BB /* Products */ = { + isa = PBXGroup; + children = ( + 4C1E373916F4035D00FF10BB /* liblldbperf.a */, + 4C1E376D16F4087A00FF10BB /* lldb-perf-sketch */, + 4C1E37BA16F79E9D00FF10BB /* lldb-perf-formatters */, + 4C86C5D116F7CC8900844407 /* format-tester */, + 26DBAD5916FA63B1008243D2 /* lldb-perf-clang */, + 4CE3705416FB6FA100BFD501 /* lldb-perf-step */, + 4CE3707C16FB70AD00BFD501 /* stepping-testcase */, + ); + name = Products; + sourceTree = "<group>"; + }; + 4C1E374116F407C800FF10BB /* lib */ = { + 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 */, + 4C1E374B16F407C800FF10BB /* Timer.h */, + 4C1E374C16F407C800FF10BB /* Xcode.cpp */, + 4C1E374D16F407C800FF10BB /* Xcode.h */, + ); + path = lib; + sourceTree = "<group>"; + }; + 4C1E375A16F4081300FF10BB /* cfcpp */ = { + isa = PBXGroup; + children = ( + 4C1E375B16F4081300FF10BB /* CFCBundle.cpp */, + 4C1E375C16F4081300FF10BB /* CFCBundle.h */, + 4C1E375D16F4081300FF10BB /* CFCData.cpp */, + 4C1E375E16F4081300FF10BB /* CFCData.h */, + 4C1E375F16F4081300FF10BB /* CFCMutableArray.cpp */, + 4C1E376016F4081300FF10BB /* CFCMutableArray.h */, + 4C1E376116F4081300FF10BB /* CFCMutableDictionary.cpp */, + 4C1E376216F4081300FF10BB /* CFCMutableDictionary.h */, + 4C1E376316F4081300FF10BB /* CFCMutableSet.cpp */, + 4C1E376416F4081300FF10BB /* CFCMutableSet.h */, + 4C1E376516F4081300FF10BB /* CFCReleaser.h */, + 4C1E376616F4081300FF10BB /* CFCString.cpp */, + 4C1E376716F4081300FF10BB /* CFCString.h */, + 4C1E376816F4081300FF10BB /* CoreFoundationCPP.h */, + ); + name = cfcpp; + path = ../../source/Host/macosx/cfcpp; + sourceTree = "<group>"; + }; + 4C1E377616F4089E00FF10BB /* sketch */ = { + isa = PBXGroup; + children = ( + 4C1E377716F4089E00FF10BB /* foobar.sketch2 */, + 4C1E377816F4089E00FF10BB /* sketch.cpp */, + ); + name = sketch; + path = darwin/sketch; + sourceTree = "<group>"; + }; + 4C1E37B216F79E4600FF10BB /* formatters */ = { + isa = PBXGroup; + children = ( + 4C1E37B316F79E4600FF10BB /* fmts_tester.mm */, + 4C1E37B416F79E4600FF10BB /* formatters.cpp */, + ); + name = formatters; + path = darwin/formatters; + sourceTree = "<group>"; + }; + 4C1E37B516F79E6600FF10BB /* Darwin */ = { + isa = PBXGroup; + children = ( + 4C1E377616F4089E00FF10BB /* sketch */, + 4C1E37B216F79E4600FF10BB /* formatters */, + ); + name = Darwin; + sourceTree = "<group>"; + }; + 4C1E37DD16F7A03900FF10BB /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4C86C5C616F7A37800844407 /* LLDB.framework */, + 4C1E37DB16F7A03900FF10BB /* CoreFoundation.framework */, + ); + name = Frameworks; + path = ../..; + sourceTree = "<group>"; + }; + 4C86C5DE16F7D18F00844407 /* Products */ = { + isa = PBXGroup; + children = ( + 264B3DE616F7E47600D1E7AB /* lldb */, + 264B3DE816F7E47600D1E7AB /* LLDB.framework */, + 264B3DEA16F7E47600D1E7AB /* darwin-debug */, + 264B3DEC16F7E47600D1E7AB /* liblldb-core.a */, + 264B3DEE16F7E47600D1E7AB /* lldb-platform */, + 264B3DF016F7E47600D1E7AB /* com.apple.lldb.launcherXPCService.xpc */, + 264B3DF216F7E47600D1E7AB /* com.apple.lldb.launcherRootXPCService.xpc */, + ); + name = Products; + sourceTree = "<group>"; + }; + 4CE3707416FB701E00BFD501 /* stepping */ = { + isa = PBXGroup; + children = ( + 4CE3708716FB70E100BFD501 /* stepping-testcase.cpp */, + 4CE3707216FB701000BFD501 /* lldb-perf-stepping.cpp */, + ); + name = stepping; + sourceTree = "<group>"; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 4C1E373716F4035D00FF10BB /* Headers */ = { + isa = PBXHeadersBuildPhase; + 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 */, + 4C1E378916F40BA200FF10BB /* CFCString.h in Headers */, + 4C1E375116F407C800FF10BB /* MemoryGauge.h in Headers */, + 4C1E378C16F40BAF00FF10BB /* CFCData.h in Headers */, + 4C1E375516F407C800FF10BB /* TestCase.h in Headers */, + 4C1E375916F407C800FF10BB /* Xcode.h in Headers */, + 4C1E375316F407C800FF10BB /* Metric.h in Headers */, + 4C1E378F16F40BBB00FF10BB /* CFCMutableSet.h in Headers */, + 4C1E378E16F40BB700FF10BB /* CFCMutableDictionary.h in Headers */, + 4C1E378B16F40BAB00FF10BB /* CFCBundle.h in Headers */, + 4C1E378A16F40BA600FF10BB /* CoreFoundationCPP.h in Headers */, + 4C1E374F16F407C800FF10BB /* Measurement.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 26DBAD5816FA63B1008243D2 /* lldb-perf-clang */ = { + isa = PBXNativeTarget; + buildConfigurationList = 26DBAD5F16FA63B1008243D2 /* Build configuration list for PBXNativeTarget "lldb-perf-clang" */; + buildPhases = ( + 26DBAD5516FA63B1008243D2 /* Sources */, + 26DBAD5616FA63B1008243D2 /* Frameworks */, + 26DBAD5716FA63B1008243D2 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 26B902E31700F9CC00EFDCE2 /* PBXTargetDependency */, + ); + name = "lldb-perf-clang"; + productName = lldb_perf_clang; + productReference = 26DBAD5916FA63B1008243D2 /* lldb-perf-clang */; + productType = "com.apple.product-type.tool"; + }; + 4C1E373816F4035D00FF10BB /* lldbperf */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4C1E373D16F4035D00FF10BB /* Build configuration list for PBXNativeTarget "lldbperf" */; + buildPhases = ( + 4C1E373516F4035D00FF10BB /* Sources */, + 4C1E373616F4035D00FF10BB /* Frameworks */, + 4C1E373716F4035D00FF10BB /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 26B902D71700F9BD00EFDCE2 /* PBXTargetDependency */, + ); + name = lldbperf; + productName = lldbperf; + productReference = 4C1E373916F4035D00FF10BB /* liblldbperf.a */; + productType = "com.apple.product-type.library.static"; + }; + 4C1E376C16F4087A00FF10BB /* lldb-perf-sketch */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4C1E377316F4087A00FF10BB /* Build configuration list for PBXNativeTarget "lldb-perf-sketch" */; + buildPhases = ( + 4C1E376916F4087A00FF10BB /* Sources */, + 4C1E376A16F4087A00FF10BB /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 4C1E379116F40BCD00FF10BB /* PBXTargetDependency */, + ); + name = "lldb-perf-sketch"; + productName = "lldb-perf-sketch"; + productReference = 4C1E376D16F4087A00FF10BB /* lldb-perf-sketch */; + productType = "com.apple.product-type.tool"; + }; + 4C1E37B916F79E9D00FF10BB /* lldb-perf-formatters */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4C1E37C016F79E9D00FF10BB /* Build configuration list for PBXNativeTarget "lldb-perf-formatters" */; + buildPhases = ( + 4C1E37B616F79E9D00FF10BB /* Sources */, + 4C1E37B716F79E9D00FF10BB /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 4C1E37C416F79EB000FF10BB /* PBXTargetDependency */, + 4C86C5DC16F7CF1200844407 /* PBXTargetDependency */, + ); + name = "lldb-perf-formatters"; + productName = formatters; + productReference = 4C1E37BA16F79E9D00FF10BB /* lldb-perf-formatters */; + productType = "com.apple.product-type.tool"; + }; + 4C86C5D016F7CC8900844407 /* format-tester */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4C86C5D716F7CC8900844407 /* Build configuration list for PBXNativeTarget "format-tester" */; + buildPhases = ( + 4C86C5CD16F7CC8900844407 /* Sources */, + 4C86C5CE16F7CC8900844407 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "format-tester"; + productName = "format-tester"; + productReference = 4C86C5D116F7CC8900844407 /* format-tester */; + productType = "com.apple.product-type.tool"; + }; + 4CE3705316FB6FA100BFD501 /* lldb-perf-step */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4CE3706716FB6FA100BFD501 /* Build configuration list for PBXNativeTarget "lldb-perf-step" */; + buildPhases = ( + 4CE3705016FB6FA100BFD501 /* Sources */, + 4CE3705116FB6FA100BFD501 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 4CE3708D16FB712300BFD501 /* PBXTargetDependency */, + 4CE3708B16FB711200BFD501 /* PBXTargetDependency */, + ); + name = "lldb-perf-step"; + productName = "lldb-step-test"; + productReference = 4CE3705416FB6FA100BFD501 /* lldb-perf-step */; + productType = "com.apple.product-type.tool"; + }; + 4CE3707B16FB70AD00BFD501 /* stepping-testcase */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4CE3708216FB70AD00BFD501 /* Build configuration list for PBXNativeTarget "stepping-testcase" */; + buildPhases = ( + 4CE3707816FB70AD00BFD501 /* Sources */, + 4CE3707916FB70AD00BFD501 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "stepping-testcase"; + productName = "stepping-testcase"; + productReference = 4CE3707C16FB70AD00BFD501 /* stepping-testcase */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4C1E373116F4035D00FF10BB /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + ORGANIZATIONNAME = lldb.llvm.org; + }; + buildConfigurationList = 4C1E373416F4035D00FF10BB /* Build configuration list for PBXProject "lldbperf" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 4C1E373016F4035D00FF10BB; + productRefGroup = 4C1E373A16F4035D00FF10BB /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 4C86C5DE16F7D18F00844407 /* Products */; + ProjectRef = 4C86C5C316F7A35000844407 /* lldb.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 4C1E373816F4035D00FF10BB /* lldbperf */, + 4C1E376C16F4087A00FF10BB /* lldb-perf-sketch */, + 4C1E37B916F79E9D00FF10BB /* lldb-perf-formatters */, + 26DBAD5816FA63B1008243D2 /* lldb-perf-clang */, + 4C86C5D016F7CC8900844407 /* format-tester */, + 4CE3705316FB6FA100BFD501 /* lldb-perf-step */, + 4CE3707B16FB70AD00BFD501 /* stepping-testcase */, + 4C1E37E316F7A0A500FF10BB /* All Perf Tests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 264B3DE616F7E47600D1E7AB /* lldb */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = lldb; + remoteRef = 264B3DE516F7E47600D1E7AB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 264B3DE816F7E47600D1E7AB /* LLDB.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = LLDB.framework; + remoteRef = 264B3DE716F7E47600D1E7AB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 264B3DEA16F7E47600D1E7AB /* darwin-debug */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = "darwin-debug"; + remoteRef = 264B3DE916F7E47600D1E7AB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 264B3DEC16F7E47600D1E7AB /* liblldb-core.a */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.dylib"; + path = "liblldb-core.a"; + remoteRef = 264B3DEB16F7E47600D1E7AB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 264B3DEE16F7E47600D1E7AB /* lldb-platform */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = "lldb-platform"; + remoteRef = 264B3DED16F7E47600D1E7AB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 264B3DF016F7E47600D1E7AB /* com.apple.lldb.launcherXPCService.xpc */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = com.apple.lldb.launcherXPCService.xpc; + remoteRef = 264B3DEF16F7E47600D1E7AB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 264B3DF216F7E47600D1E7AB /* com.apple.lldb.launcherRootXPCService.xpc */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = com.apple.lldb.launcherRootXPCService.xpc; + remoteRef = 264B3DF116F7E47600D1E7AB /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXSourcesBuildPhase section */ + 26DBAD5516FA63B1008243D2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 26DBAD6216FA63F0008243D2 /* lldb_perf_clang.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C1E373516F4035D00FF10BB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C1E378316F40B8C00FF10BB /* CFCData.cpp in Sources */, + 4C1E378416F40B8F00FF10BB /* CFCMutableArray.cpp in Sources */, + 4C1E378216F40B8900FF10BB /* CFCBundle.cpp in Sources */, + 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; + }; + 4C1E376916F4087A00FF10BB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C1E377916F4089E00FF10BB /* sketch.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C1E37B616F79E9D00FF10BB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C1E37CB16F79EFA00FF10BB /* formatters.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C86C5CD16F7CC8900844407 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4C86C5DA16F7CED300844407 /* fmts_tester.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4CE3705016FB6FA100BFD501 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CE3707316FB701000BFD501 /* lldb-perf-stepping.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4CE3707816FB70AD00BFD501 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4CDDF51017011EBB00D95015 /* stepping-testcase.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 26B902D71700F9BD00EFDCE2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = LLDB; + targetProxy = 26B902D61700F9BD00EFDCE2 /* PBXContainerItemProxy */; + }; + 26B902E31700F9CC00EFDCE2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C1E373816F4035D00FF10BB /* lldbperf */; + targetProxy = 26B902E21700F9CC00EFDCE2 /* PBXContainerItemProxy */; + }; + 4C1E379116F40BCD00FF10BB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C1E373816F4035D00FF10BB /* lldbperf */; + targetProxy = 4C1E379016F40BCD00FF10BB /* PBXContainerItemProxy */; + }; + 4C1E37C416F79EB000FF10BB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C1E373816F4035D00FF10BB /* lldbperf */; + targetProxy = 4C1E37C316F79EB000FF10BB /* PBXContainerItemProxy */; + }; + 4C86C5DC16F7CF1200844407 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C86C5D016F7CC8900844407 /* format-tester */; + targetProxy = 4C86C5DB16F7CF1200844407 /* PBXContainerItemProxy */; + }; + 4CE3706916FB6FCA00BFD501 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C1E376C16F4087A00FF10BB /* lldb-perf-sketch */; + targetProxy = 4CE3706816FB6FCA00BFD501 /* PBXContainerItemProxy */; + }; + 4CE3706B16FB6FCC00BFD501 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C1E37B916F79E9D00FF10BB /* lldb-perf-formatters */; + targetProxy = 4CE3706A16FB6FCC00BFD501 /* PBXContainerItemProxy */; + }; + 4CE3706D16FB6FCF00BFD501 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 26DBAD5816FA63B1008243D2 /* lldb-perf-clang */; + targetProxy = 4CE3706C16FB6FCF00BFD501 /* PBXContainerItemProxy */; + }; + 4CE3706F16FB6FD200BFD501 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4CE3705316FB6FA100BFD501 /* lldb-perf-step */; + targetProxy = 4CE3706E16FB6FD200BFD501 /* PBXContainerItemProxy */; + }; + 4CE3708B16FB711200BFD501 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4CE3707B16FB70AD00BFD501 /* stepping-testcase */; + targetProxy = 4CE3708A16FB711200BFD501 /* PBXContainerItemProxy */; + }; + 4CE3708D16FB712300BFD501 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C1E373816F4035D00FF10BB /* lldbperf */; + targetProxy = 4CE3708C16FB712300BFD501 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 26DBAD6016FA63B1008243D2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../build/Debug", + ); + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Debug"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../ $(SRCROOT)/../../include/"; + }; + name = Debug; + }; + 26DBAD6116FA63B1008243D2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../build/Debug", + ); + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Release"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../ $(SRCROOT)/../../include/"; + }; + name = Release; + }; + 4C1E373B16F4035D00FF10BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + ONLY_ACTIVE_ARCH = YES; + }; + name = Debug; + }; + 4C1E373C16F4035D00FF10BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.7; + }; + name = Release; + }; + 4C1E373E16F4035D00FF10BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../include"; + }; + name = Debug; + }; + 4C1E373F16F4035D00FF10BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../include"; + }; + name = Release; + }; + 4C1E377416F4087A00FF10BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../build/Debug", + ); + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Debug"; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../../include $(SRCROOT)/../../source/Host/macosx/cfcpp $(SRCROOT)/../"; + }; + name = Debug; + }; + 4C1E377516F4087A00FF10BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(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)/../"; + }; + name = Release; + }; + 4C1E37C116F79E9D00FF10BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../build/Debug", + ); + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Debug"; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../ $(SRCROOT)/../../include/"; + }; + name = Debug; + }; + 4C1E37C216F79E9D00FF10BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(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/"; + }; + name = Release; + }; + 4C1E37E516F7A0A600FF10BB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 4C1E37E616F7A0A600FF10BB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 4C86C5D816F7CC8900844407 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 4C86C5D916F7CC8900844407 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 4CE3705A16FB6FA100BFD501 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../build/Debug", + ); + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + MACOSX_DEPLOYMENT_TARGET = 10.9; + OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Debug"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../ $(SRCROOT)/../../include/"; + }; + name = Debug; + }; + 4CE3705B16FB6FA100BFD501 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../build/Debug", + ); + GCC_INLINES_ARE_PRIVATE_EXTERN = NO; + MACOSX_DEPLOYMENT_TARGET = 10.9; + OTHER_LDFLAGS = "-Wl,-rpath,@loader_path/../../../../build/Debug"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/../ $(SRCROOT)/../../include/"; + }; + name = Release; + }; + 4CE3708316FB70AD00BFD501 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + MACOSX_DEPLOYMENT_TARGET = 10.9; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Debug; + }; + 4CE3708416FB70AD00BFD501 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_OPTIMIZATION_LEVEL = 0; + MACOSX_DEPLOYMENT_TARGET = 10.9; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 26DBAD5F16FA63B1008243D2 /* Build configuration list for PBXNativeTarget "lldb-perf-clang" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 26DBAD6016FA63B1008243D2 /* Debug */, + 26DBAD6116FA63B1008243D2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4C1E373416F4035D00FF10BB /* Build configuration list for PBXProject "lldbperf" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4C1E373B16F4035D00FF10BB /* Debug */, + 4C1E373C16F4035D00FF10BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4C1E373D16F4035D00FF10BB /* Build configuration list for PBXNativeTarget "lldbperf" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4C1E373E16F4035D00FF10BB /* Debug */, + 4C1E373F16F4035D00FF10BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4C1E377316F4087A00FF10BB /* Build configuration list for PBXNativeTarget "lldb-perf-sketch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4C1E377416F4087A00FF10BB /* Debug */, + 4C1E377516F4087A00FF10BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4C1E37C016F79E9D00FF10BB /* Build configuration list for PBXNativeTarget "lldb-perf-formatters" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4C1E37C116F79E9D00FF10BB /* Debug */, + 4C1E37C216F79E9D00FF10BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4C1E37E416F7A0A600FF10BB /* Build configuration list for PBXAggregateTarget "All Perf Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4C1E37E516F7A0A600FF10BB /* Debug */, + 4C1E37E616F7A0A600FF10BB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4C86C5D716F7CC8900844407 /* Build configuration list for PBXNativeTarget "format-tester" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4C86C5D816F7CC8900844407 /* Debug */, + 4C86C5D916F7CC8900844407 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4CE3706716FB6FA100BFD501 /* Build configuration list for PBXNativeTarget "lldb-perf-step" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4CE3705A16FB6FA100BFD501 /* Debug */, + 4CE3705B16FB6FA100BFD501 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4CE3708216FB70AD00BFD501 /* Build configuration list for PBXNativeTarget "stepping-testcase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4CE3708316FB70AD00BFD501 /* Debug */, + 4CE3708416FB70AD00BFD501 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4C1E373116F4035D00FF10BB /* Project object */; +} |