diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-06 20:12:03 +0000 | 
| commit | 9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (patch) | |
| tree | dd2a1ddf0476664c2b823409c36cbccd52662ca7 /tools/lldb-perf | |
| parent | 3bd2e91faeb9eeec1aae82c64a3253afff551cfd (diff) | |
Notes
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.sketch2Binary files differ new 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 */; +} | 
