1d3a8d6565ff40fd99533f50a085ace806a9300eeGreg Clayton//===-- sketch.cpp ----------------------------------------------*- C++ -*-===//
2f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata//
3d3a8d6565ff40fd99533f50a085ace806a9300eeGreg Clayton//                     The LLVM Compiler Infrastructure
4f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata//
5d3a8d6565ff40fd99533f50a085ace806a9300eeGreg Clayton// This file is distributed under the University of Illinois Open Source
6d3a8d6565ff40fd99533f50a085ace806a9300eeGreg Clayton// License. See LICENSE.TXT for details.
7f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata//
8d3a8d6565ff40fd99533f50a085ace806a9300eeGreg Clayton//===----------------------------------------------------------------------===//
9f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
10f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include <CoreFoundation/CoreFoundation.h>
11f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
12f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include "lldb-perf/lib/Timer.h"
13f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include "lldb-perf/lib/Metric.h"
14f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include "lldb-perf/lib/Measurement.h"
15f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include "lldb-perf/lib/TestCase.h"
16f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include "lldb-perf/lib/Xcode.h"
17f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
18f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include <iostream>
19f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include <unistd.h>
20f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata#include <fstream>
2151a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata#include <getopt.h>
22f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
23af222500aa2ce2b18149277e561cdf75f2115df2Greg Claytonusing namespace lldb_perf;
24f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
256e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granatastatic struct option g_long_options[] = {
266e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    { "verbose",    no_argument,            NULL, 'v' },
276e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    { "sketch",     required_argument,      NULL, 'c' },
286e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    { "foobar",     required_argument,      NULL, 'f' },
296e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    { "out-file",   required_argument,      NULL, 'o' },
306e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    { NULL,         0,                      NULL,  0  }
316e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata};
326e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
33f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granataclass SketchTest : public TestCase
34f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata{
35f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granatapublic:
36f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    SketchTest () :
372002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_fetch_frames_measurement ([this] () -> void
382002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            {
392002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                Xcode::FetchFrames (GetProcess(),false,false);
402002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            }, "fetch-frames", "time to dump backtrace for every frame in every thread"),
412002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_file_line_bp_measurement([this] (const char* file, uint32_t line) -> void
422002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            {
432002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                Xcode::CreateFileLineBreakpoint(GetTarget(), file, line);
442002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            }, "file-line-bkpt", "time to set a breakpoint given a file and line"),
452002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_fetch_modules_measurement ([this] () -> void
462002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            {
472002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                Xcode::FetchModules(GetTarget());
482002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            }, "fetch-modules", "time to get info for all modules in the process"),
492002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_fetch_vars_measurement([this] (int depth) -> void
502002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            {
512002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                SBProcess process (GetProcess());
522002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                auto threads_count = process.GetNumThreads();
532002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                for (size_t thread_num = 0; thread_num < threads_count; thread_num++)
542002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                {
552002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                    SBThread thread(process.GetThreadAtIndex(thread_num));
562002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                    SBFrame frame(thread.GetFrameAtIndex(0));
572002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                    Xcode::FetchVariables(frame,depth,GetVerbose());
582002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                }
592002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            }, "fetch-vars", "time to dump variables for the topmost frame in every thread"),
602002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_run_expr_measurement([this] (SBFrame frame, const char* expr) -> void
612002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            {
622002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                SBValue value(frame.EvaluateExpression(expr, lldb::eDynamicCanRunTarget));
632002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton                Xcode::FetchVariable (value, 0, GetVerbose());
642002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton            }, "run-expr", "time to evaluate an expression and display the result")
656e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    {
666e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        m_app_path.clear();
676e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        m_out_path.clear();
686e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        m_doc_path.clear();
696e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        m_print_help = false;
706e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    }
71f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
72f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    virtual
73f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    ~SketchTest ()
74f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    {
75f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    }
76f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
7791c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton    virtual bool
786e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    ParseOption (int short_option, const char* optarg)
796e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    {
806e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        switch (short_option)
816e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        {
826e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            case 0:
836e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                return false;
846e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
856e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            case -1:
866e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                return false;
876e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
886e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            case '?':
896e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            case 'h':
906e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                m_print_help = true;
916e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                break;
926e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
936e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            case 'v':
946e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                SetVerbose(true);
956e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                break;
966e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
976e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            case 'c':
986e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            {
996e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                SBFileSpec file(optarg);
1006e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                if (file.Exists())
1016e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                    SetExecutablePath(optarg);
1026e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                else
1036e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                    fprintf(stderr, "error: file specified in --sketch (-c) option doesn't exist: '%s'\n", optarg);
1046e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            }
1056e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                break;
1066e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1076e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            case 'f':
1086e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            {
1096e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                SBFileSpec file(optarg);
1106e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                if (file.Exists())
1116e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                    SetDocumentPath(optarg);
1126e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                else
1136e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                    fprintf(stderr, "error: file specified in --foobar (-f) option doesn't exist: '%s'\n", optarg);
1146e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            }
1156e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                break;
1166e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1176e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            case 'o':
1186e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                SetResultFilePath(optarg);
1196e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                break;
1206e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1216e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            default:
1226e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                m_print_help = true;
1236e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                fprintf (stderr, "error: unrecognized option %c\n", short_option);
1246e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                break;
1256e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        }
1266e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        return true;
1276e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    }
1286e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1296e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    virtual struct option*
1306e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    GetLongOptions ()
1316e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    {
1326e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        return g_long_options;
1336e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    }
1346e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1356e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    virtual bool
136b1b36ec6dcfbe7c7dfa423d50cb7c2296deca68eEnrico Granata	Setup (int& argc, const char**& argv)
137f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    {
138f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata        TestCase::Setup(argc,argv);
1396e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        bool error = false;
1406e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1416e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        if (GetExecutablePath() == NULL)
1426e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        {
1436e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            // --sketch is mandatory
1446e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            error = true;
1456e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            fprintf (stderr, "error: the '--sketch=PATH' option is mandatory\n");
1466e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        }
1476e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1486e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        if (GetDocumentPath() == NULL)
1496e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        {
1506e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            // --foobar is mandatory
1516e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            error = true;
1526e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            fprintf (stderr, "error: the '--foobar=PATH' option is mandatory\n");
1536e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        }
1546e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1556e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        if (error || GetPrintHelp())
1566e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        {
1576e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            puts(R"(
1586e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                 NAME
1596e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                 lldb_perf_sketch -- a tool that measures LLDB peformance while debugging sketch.
1606e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1616e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                 SYNOPSIS
1626e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                 lldb_perf_sketch --sketch=PATH --foobar=PATH [--out-file=PATH --verbose]
1636e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1646e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                 DESCRIPTION
1656e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                 Runs a set of static timing and memory tasks against sketch and outputs results
1666e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                 to a plist file.
1676e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata                 )");
1686e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        }
1696e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
1706e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        if (error)
1716e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        {
1726e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            exit(1);
1736e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        }
174b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata        lldb::SBLaunchInfo launch_info = GetLaunchInfo();
175f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata        m_target = m_debugger.CreateTarget(m_app_path.c_str());
1762002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_file_line_bp_measurement("SKTDocument.m",245);
1772002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_file_line_bp_measurement("SKTDocument.m",283);
1782002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_file_line_bp_measurement("SKTText.m",326);
17991c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton        return Launch (launch_info);
180f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    }
181f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
182b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata    lldb::SBLaunchInfo
183b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata    GetLaunchInfo ()
184b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata    {
185b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata        const char* file_arg = m_doc_path.c_str();
186b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata        const char* persist_arg = "-ApplePersistenceIgnoreState";
187b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata        const char* persist_skip = "YES";
188b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata        const char* empty = nullptr;
189b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata        const char* args[] = {file_arg,persist_arg,persist_skip,empty};
190b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata        return SBLaunchInfo(args);
191b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata    }
192b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata
193f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    void
194f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    DoTest ()
195f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    {
1962002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_fetch_frames_measurement();
1972002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_fetch_modules_measurement();
1982002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton        m_fetch_vars_measurement(1);
199f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    }
200f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
201af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton	virtual void
202af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton	TestStep (int counter, ActionWanted &next_action)
203f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    {
2044d77c182b3b4fd418ccb488469aa18262bfe481bEnrico Granata        static int launch = 1;
2054d77c182b3b4fd418ccb488469aa18262bfe481bEnrico Granata        switch (counter % 10)
206af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        {
207af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 0:
208af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
209af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
210b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata                if (counter == 0)
211b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata                    m_file_line_bp_measurement("SKTDocument.m",254);
212af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                next_action.Continue();
213af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
214af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
215af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton
216af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 1:
217af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
218af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
21991c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"properties");
22091c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[properties description]");
22191c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"typeName");
22291c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"data");
22391c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[data description]");
224af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                next_action.Continue();
225af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
226af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
227af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton
228af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 2:
229af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
230af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
231af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                next_action.Continue();
232af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
233af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
234af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton
235af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 3:
236af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
237af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
23891c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                next_action.StepOver(m_thread);
239af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
240af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
241af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton
242af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 4:
243af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
244af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
24591c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"layoutManager");
24691c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"contents");
24791c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                next_action.StepOver(m_thread);
248af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
249af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
250af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton
251af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 5:
252af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
253af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
25491c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                next_action.StepOver(m_thread);
255af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
256af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
257af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton
258af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 6:
259af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
260af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
26191c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                next_action.StepOver(m_thread);
262af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
263af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
264af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton
265af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 7:
266af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
267af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
26891c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"@\"an NSString\"");
26991c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[(id)@\"an NSString\" description]");
27091c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"@[@1,@2,@3]");
27191c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                next_action.StepOut(m_thread);
272af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
273af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
274af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton
275af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        case 8:
276af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
277af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                DoTest ();
27891c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[graphics description]");
27991c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"[selectionIndexes description]");
28091c570abdc2eb7f0d9bc5affb086d515838ebc39Greg Clayton                m_run_expr_measurement(m_thread.GetFrameAtIndex(0),"(BOOL)NSIntersectsRect(rect, graphicDrawingBounds)");
281af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
28217a9d265c78823373cd36890f8b0f63e96d223c8Enrico Granata            next_action.CallNext();
283af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
284b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata        case 9:
28517a9d265c78823373cd36890f8b0f63e96d223c8Enrico Granata            if (++launch < 10)
28617a9d265c78823373cd36890f8b0f63e96d223c8Enrico Granata                next_action.Relaunch(GetLaunchInfo());
28717a9d265c78823373cd36890f8b0f63e96d223c8Enrico Granata            else
28817a9d265c78823373cd36890f8b0f63e96d223c8Enrico Granata                next_action.Kill();
28917a9d265c78823373cd36890f8b0f63e96d223c8Enrico Granata            break;
29017a9d265c78823373cd36890f8b0f63e96d223c8Enrico Granata
291b8158c8227c34b0fde91cf8602003f250bead007Enrico Granata
292af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton        default:
293af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            {
294af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton                next_action.Kill();
295af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            }
296af222500aa2ce2b18149277e561cdf75f2115df2Greg Clayton            break;
297f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata        }
298f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    }
299f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
3009de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    virtual void
3019de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    WriteResults (Results &results)
302f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    {
303ec87e5c098f1ce1c9182d1c5438e0beca0996597Enrico Granata        m_fetch_frames_measurement.WriteAverageAndStandardDeviation(results);
304ec87e5c098f1ce1c9182d1c5438e0beca0996597Enrico Granata        m_file_line_bp_measurement.WriteAverageAndStandardDeviation(results);
305ec87e5c098f1ce1c9182d1c5438e0beca0996597Enrico Granata        m_fetch_modules_measurement.WriteAverageAndStandardDeviation(results);
306ec87e5c098f1ce1c9182d1c5438e0beca0996597Enrico Granata        m_fetch_vars_measurement.WriteAverageAndStandardDeviation(results);
307ec87e5c098f1ce1c9182d1c5438e0beca0996597Enrico Granata        m_run_expr_measurement.WriteAverageAndStandardDeviation(results);
3086e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        results.Write(GetResultFilePath());
309f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    }
310f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
31151a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    void
31251a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    SetExecutablePath (const char* str)
31351a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    {
31451a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        if (str)
31551a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata            m_app_path.assign(str);
31651a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    }
31751a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata
31851a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    const char*
31951a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    GetExecutablePath ()
32051a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    {
32151a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        if (m_app_path.empty())
32251a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata            return NULL;
32351a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        return m_app_path.c_str();
32451a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    }
32551a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata
32651a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    void
32751a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    SetDocumentPath (const char* str)
32851a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    {
32951a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        if (str)
33051a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata            m_doc_path.assign(str);
33151a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    }
33251a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata
33351a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    const char*
33451a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    GetDocumentPath ()
33551a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    {
33651a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        if (m_doc_path.empty())
33751a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata            return NULL;
33851a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        return m_doc_path.c_str();
33951a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    }
34051a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata
34151a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata
34251a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    void
34351a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    SetResultFilePath (const char* str)
34451a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    {
34551a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        if (str)
34651a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata            m_out_path.assign(str);
34751a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    }
34851a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata
34951a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    const char*
35051a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    GetResultFilePath ()
35151a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    {
35251a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        if (m_out_path.empty())
3536e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata            return "/dev/stdout";
35451a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata        return m_out_path.c_str();
35551a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    }
35651a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata
3576e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    bool
3586e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    GetPrintHelp ()
3596e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    {
3606e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata        return m_print_help;
3616e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    }
3626e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata
363f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granataprivate:
3642002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton    Measurement<lldb_perf::TimeGauge, std::function<void()>> m_fetch_frames_measurement;
3652002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton    Measurement<lldb_perf::TimeGauge, std::function<void(const char*, uint32_t)>> m_file_line_bp_measurement;
3662002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton    Measurement<lldb_perf::TimeGauge, std::function<void()>> m_fetch_modules_measurement;
3672002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton    Measurement<lldb_perf::TimeGauge, std::function<void(int)>> m_fetch_vars_measurement;
3682002c030ded5da1adf38ceb76a7f393baa7a87e3Greg Clayton    Measurement<lldb_perf::TimeGauge, std::function<void(SBFrame, const char*)>> m_run_expr_measurement;
369f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
370f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    std::string m_app_path;
371f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    std::string m_doc_path;
372f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata    std::string m_out_path;
3736e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    bool m_print_help;
374f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata};
375f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata
376f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granataint main(int argc, const char * argv[])
377f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata{
37851a53958518a1b2aa4b8c37276dcc3a2516c00a5Enrico Granata    SketchTest test;
3796e792e9565c78f96ef5e0e36d467f724fd4efbf2Enrico Granata    return TestCase::Run(test, argc, argv);
380f5af85a2946ed4e1ff4766829d328cfb4961f259Enrico Granata}
381