[Lldb-commits] [lldb] r176715 - Initial checkin of a new project: LLDB Performance Testing Infrastructure

Enrico Granata egranata at apple.com
Fri Mar 8 12:29:14 PST 2013


Author: enrico
Date: Fri Mar  8 14:29:13 2013
New Revision: 176715

URL: http://llvm.org/viewvc/llvm-project?rev=176715&view=rev
Log:
Initial checkin of a new project: LLDB Performance Testing Infrastructure

This is a very basic implementation of a library that easily allows to drive LLDB.framework to write test cases for performance

This is separate from the LLDB testsuite in test/ in that:
a) this uses C++ instead of Python to avoid measures being affected by SWIG
b) this is in very early development and needs lots of tweaking before it can be considered functionally complete
c) this is not meant to test correctness but to help catch performance regressions

There is a sample application built against the library (in darwin/sketch) that uses the famous sample app Sketch as an inferior to measure certain basic parameters of LLDB's behavior.
The resulting output is a PLIST much like the following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
	<dict>
		<key>fetch-frames</key>
		<real>0.13161715522222225</real>
	</dict>
	<dict>
		<key>file-line-bkpt</key>
		<real>0.029111678750000002</real>
	</dict>
	<dict>
		<key>fetch-modules</key>
		<real>0.00026376766666666668</real>
	</dict>
	<dict>
		<key>fetch-vars</key>
		<real>0.17820429311111111</real>
	</dict>
	<dict>
		<key>run-expr</key>
		<real>0.029676525769230768</real>
	</dict>
</array>
</plist>

Areas for improvement:
- code cleanups (I will be out of the office for a couple days this coming week, but please keep ideas coming!)
- more metrics and test cases
- better error checking

This toolkit also comprises a simple event-loop-driven controller for LLDB, similar yet much simpler to what the Driver does to implement the lldb command-line tool.


Added:
    lldb/trunk/tools/lldb-perf/
    lldb/trunk/tools/lldb-perf/darwin/
    lldb/trunk/tools/lldb-perf/darwin/sketch/
    lldb/trunk/tools/lldb-perf/darwin/sketch/main.cpp
    lldb/trunk/tools/lldb-perf/lib/
    lldb/trunk/tools/lldb-perf/lib/Gauge.h
    lldb/trunk/tools/lldb-perf/lib/Measurement.h
    lldb/trunk/tools/lldb-perf/lib/MemoryGauge.cpp
    lldb/trunk/tools/lldb-perf/lib/MemoryGauge.h
    lldb/trunk/tools/lldb-perf/lib/Metric.cpp
    lldb/trunk/tools/lldb-perf/lib/Metric.h
    lldb/trunk/tools/lldb-perf/lib/TestCase.cpp
    lldb/trunk/tools/lldb-perf/lib/TestCase.h
    lldb/trunk/tools/lldb-perf/lib/Timer.cpp
    lldb/trunk/tools/lldb-perf/lib/Timer.h
    lldb/trunk/tools/lldb-perf/lib/Xcode.cpp
    lldb/trunk/tools/lldb-perf/lib/Xcode.h
Modified:
    lldb/trunk/examples/python/process_events.py
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
    lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp

Modified: lldb/trunk/examples/python/process_events.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/python/process_events.py?rev=176715&r1=176714&r2=176715&view=diff
==============================================================================
--- lldb/trunk/examples/python/process_events.py (original)
+++ lldb/trunk/examples/python/process_events.py Fri Mar  8 14:29:13 2013
@@ -184,6 +184,7 @@ def main(argv):
                     event = lldb.SBEvent()
                     if listener.WaitForEvent (options.event_timeout, event):
                         state = lldb.SBProcess.GetStateFromEvent (event)
+                        print "event %s" % (lldb.SBDebugger.StateAsCString(state))
                         if state == lldb.eStateStopped:
                             if stop_idx == 0:
                                 if launch_info:
@@ -203,6 +204,7 @@ def main(argv):
                                 run_commands (command_interpreter, options.stop_commands)
                             stop_idx += 1
                             print_threads (process, options)
+                            print "continuing process %u" % (pid)
                             process.Continue()
                         elif state == lldb.eStateExited:
                             exit_desc = process.GetExitDescription()

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=176715&r1=176714&r2=176715&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Fri Mar  8 14:29:13 2013
@@ -517,6 +517,36 @@
 		4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
 		94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */; };
 		94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94094C69163B6CD90083A547 /* ValueObjectCast.cpp */; };
+		940DB8B816EA614400D3C2F1 /* lldbperf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 940DB89A16EA5F4200D3C2F1 /* lldbperf.a */; };
+		940DB8CC16EA66FB00D3C2F1 /* Gauge.h in Headers */ = {isa = PBXBuildFile; fileRef = 940DB8CA16EA66FB00D3C2F1 /* Gauge.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		940DB8D016EA670C00D3C2F1 /* Measurement.h in Headers */ = {isa = PBXBuildFile; fileRef = 940DB8CE16EA670C00D3C2F1 /* Measurement.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		940DB8D316EA671800D3C2F1 /* MemoryGauge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940DB8D116EA671800D3C2F1 /* MemoryGauge.cpp */; };
+		940DB8D416EA671800D3C2F1 /* MemoryGauge.h in Headers */ = {isa = PBXBuildFile; fileRef = 940DB8D216EA671800D3C2F1 /* MemoryGauge.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		940DB8D716EA672200D3C2F1 /* Metric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940DB8D516EA672200D3C2F1 /* Metric.cpp */; };
+		940DB8D816EA672200D3C2F1 /* Metric.h in Headers */ = {isa = PBXBuildFile; fileRef = 940DB8D616EA672200D3C2F1 /* Metric.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		940DB8DB16EA672D00D3C2F1 /* TestCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940DB8D916EA672D00D3C2F1 /* TestCase.cpp */; };
+		940DB8DC16EA672D00D3C2F1 /* TestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 940DB8DA16EA672D00D3C2F1 /* TestCase.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		940DB8DF16EA673800D3C2F1 /* Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940DB8DD16EA673800D3C2F1 /* Timer.cpp */; };
+		940DB8E016EA673800D3C2F1 /* Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 940DB8DE16EA673800D3C2F1 /* Timer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		940DB8E316EA674000D3C2F1 /* Xcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940DB8E116EA674000D3C2F1 /* Xcode.cpp */; };
+		940DB8E416EA674000D3C2F1 /* Xcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 940DB8E216EA674000D3C2F1 /* Xcode.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		940DB8E516EA6E1800D3C2F1 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26680207115FD0ED008E1FE4 /* LLDB.framework */; };
+		940DB8E716EA709400D3C2F1 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 940DB8E616EA709400D3C2F1 /* main.cpp */; };
+		940DB8EB16EA752000D3C2F1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26F5C39010F3FA26009D5894 /* CoreFoundation.framework */; };
+		940DB8EC16EA752E00D3C2F1 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26680207115FD0ED008E1FE4 /* LLDB.framework */; };
+		940DB8ED16EA76A400D3C2F1 /* CFCBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EED10F1B8AD00F91463 /* CFCBundle.cpp */; };
+		940DB8EE16EA76A400D3C2F1 /* CFCBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7EEE10F1B8AD00F91463 /* CFCBundle.h */; };
+		940DB8EF16EA76A400D3C2F1 /* CFCData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EEF10F1B8AD00F91463 /* CFCData.cpp */; };
+		940DB8F016EA76A400D3C2F1 /* CFCData.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7EF010F1B8AD00F91463 /* CFCData.h */; };
+		940DB8F116EA76A400D3C2F1 /* CFCMutableArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EF110F1B8AD00F91463 /* CFCMutableArray.cpp */; };
+		940DB8F216EA76A400D3C2F1 /* CFCMutableArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7EF210F1B8AD00F91463 /* CFCMutableArray.h */; };
+		940DB8F316EA76A400D3C2F1 /* CFCMutableDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EF310F1B8AD00F91463 /* CFCMutableDictionary.cpp */; };
+		940DB8F416EA76A400D3C2F1 /* CFCMutableDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7EF410F1B8AD00F91463 /* CFCMutableDictionary.h */; };
+		940DB8F516EA76A400D3C2F1 /* CFCMutableSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EF510F1B8AD00F91463 /* CFCMutableSet.cpp */; };
+		940DB8F616EA76A400D3C2F1 /* CFCMutableSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7EF610F1B8AD00F91463 /* CFCMutableSet.h */; };
+		940DB8F716EA76A400D3C2F1 /* CFCReleaser.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7EF710F1B8AD00F91463 /* CFCReleaser.h */; };
+		940DB8F816EA76A400D3C2F1 /* CFCString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EF810F1B8AD00F91463 /* CFCString.cpp */; };
+		940DB8F916EA76A400D3C2F1 /* CFCString.h in Headers */ = {isa = PBXBuildFile; fileRef = 26BC7EF910F1B8AD00F91463 /* CFCString.h */; };
 		941BCC7F14E48C4000BB969C /* SBTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568614E355F2003A195C /* SBTypeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		941BCC8014E48C4000BB969C /* SBTypeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568714E355F2003A195C /* SBTypeFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		941BCC8114E48C4000BB969C /* SBTypeSummary.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568814E355F2003A195C /* SBTypeSummary.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -697,9 +727,32 @@
 			remoteGlobalIDString = 2689FFC913353D7A00698AC0;
 			remoteInfo = "lldb-core";
 		};
+		940DB8BA16EA61D900D3C2F1 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 26680206115FD0ED008E1FE4;
+			remoteInfo = LLDB;
+		};
+		940DB8E816EA72BE00D3C2F1 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 940DB89916EA5F4200D3C2F1;
+			remoteInfo = lldbperf;
+		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXCopyFilesBuildPhase section */
+		940DB8AB16EA60C900D3C2F1 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
 		AF90106415AB7D2900FF120D /* CopyFiles */ = {
 			isa = PBXCopyFilesBuildPhase;
 			buildActionMask = 8;
@@ -1535,6 +1588,21 @@
 		94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PriorityPointerPair.h; path = include/lldb/Utility/PriorityPointerPair.h; sourceTree = "<group>"; };
 		94094C68163B6CCC0083A547 /* ValueObjectCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectCast.h; path = include/lldb/Core/ValueObjectCast.h; sourceTree = "<group>"; };
 		94094C69163B6CD90083A547 /* ValueObjectCast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectCast.cpp; path = source/Core/ValueObjectCast.cpp; sourceTree = "<group>"; };
+		940DB89A16EA5F4200D3C2F1 /* lldbperf.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = lldbperf.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		940DB8AD16EA60C900D3C2F1 /* lldb-perf-sketch */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-perf-sketch"; sourceTree = BUILT_PRODUCTS_DIR; };
+		940DB8CA16EA66FB00D3C2F1 /* Gauge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gauge.h; sourceTree = "<group>"; };
+		940DB8CE16EA670C00D3C2F1 /* Measurement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Measurement.h; sourceTree = "<group>"; };
+		940DB8D116EA671800D3C2F1 /* MemoryGauge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryGauge.cpp; sourceTree = "<group>"; };
+		940DB8D216EA671800D3C2F1 /* MemoryGauge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryGauge.h; sourceTree = "<group>"; };
+		940DB8D516EA672200D3C2F1 /* Metric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Metric.cpp; sourceTree = "<group>"; };
+		940DB8D616EA672200D3C2F1 /* Metric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Metric.h; sourceTree = "<group>"; };
+		940DB8D916EA672D00D3C2F1 /* TestCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TestCase.cpp; sourceTree = "<group>"; };
+		940DB8DA16EA672D00D3C2F1 /* TestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestCase.h; sourceTree = "<group>"; };
+		940DB8DD16EA673800D3C2F1 /* Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timer.cpp; sourceTree = "<group>"; };
+		940DB8DE16EA673800D3C2F1 /* Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = "<group>"; };
+		940DB8E116EA674000D3C2F1 /* Xcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Xcode.cpp; sourceTree = "<group>"; };
+		940DB8E216EA674000D3C2F1 /* Xcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Xcode.h; sourceTree = "<group>"; };
+		940DB8E616EA709400D3C2F1 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
 		9443B120140C18A90013457C /* SBData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBData.h; path = include/lldb/API/SBData.h; sourceTree = "<group>"; };
 		9443B121140C18C10013457C /* SBData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBData.cpp; path = source/API/SBData.cpp; sourceTree = "<group>"; };
 		9452573616262CD000325455 /* SBDeclaration.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBDeclaration.i; sourceTree = "<group>"; };
@@ -1773,6 +1841,24 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		940DB89716EA5F4200D3C2F1 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				940DB8E516EA6E1800D3C2F1 /* LLDB.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		940DB8AA16EA60C900D3C2F1 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				940DB8B816EA614400D3C2F1 /* lldbperf.a in Frameworks */,
+				940DB8EB16EA752000D3C2F1 /* CoreFoundation.framework in Frameworks */,
+				940DB8EC16EA752E00D3C2F1 /* LLDB.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		EDC6D49614E5C19B001B75F8 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
@@ -1840,6 +1926,8 @@
 				26DC6A101337FE6900FF7998 /* lldb-platform */,
 				EDC6D49914E5C19B001B75F8 /* com.apple.lldb.launcherXPCService.xpc */,
 				EDE274EC14EDCE1F005B0F75 /* com.apple.lldb.launcherRootXPCService.xpc */,
+				940DB89A16EA5F4200D3C2F1 /* lldbperf.a */,
+				940DB8AD16EA60C900D3C2F1 /* lldb-perf-sketch */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -3209,6 +3297,7 @@
 		26F5C22410F3D950009D5894 /* Tools */ = {
 			isa = PBXGroup;
 			children = (
+				940DB8C416EA64D400D3C2F1 /* lldb-perf */,
 				26579F55126A255E0007C5CB /* darwin-debug */,
 				265E9BE0115C2B8500D0DCCB /* debugserver */,
 				26F5C22510F3D956009D5894 /* Driver */,
@@ -3355,6 +3444,51 @@
 			path = source/Host/common;
 			sourceTree = "<group>";
 		};
+		940DB8C416EA64D400D3C2F1 /* lldb-perf */ = {
+			isa = PBXGroup;
+			children = (
+				940DB8C616EA654E00D3C2F1 /* darwin */,
+				940DB8C516EA654900D3C2F1 /* lib */,
+			);
+			name = "lldb-perf";
+			path = "tools/lldb-perf";
+			sourceTree = "<group>";
+		};
+		940DB8C516EA654900D3C2F1 /* lib */ = {
+			isa = PBXGroup;
+			children = (
+				940DB8CA16EA66FB00D3C2F1 /* Gauge.h */,
+				940DB8CE16EA670C00D3C2F1 /* Measurement.h */,
+				940DB8D116EA671800D3C2F1 /* MemoryGauge.cpp */,
+				940DB8D216EA671800D3C2F1 /* MemoryGauge.h */,
+				940DB8D516EA672200D3C2F1 /* Metric.cpp */,
+				940DB8D616EA672200D3C2F1 /* Metric.h */,
+				940DB8D916EA672D00D3C2F1 /* TestCase.cpp */,
+				940DB8DA16EA672D00D3C2F1 /* TestCase.h */,
+				940DB8DD16EA673800D3C2F1 /* Timer.cpp */,
+				940DB8DE16EA673800D3C2F1 /* Timer.h */,
+				940DB8E116EA674000D3C2F1 /* Xcode.cpp */,
+				940DB8E216EA674000D3C2F1 /* Xcode.h */,
+			);
+			path = lib;
+			sourceTree = "<group>";
+		};
+		940DB8C616EA654E00D3C2F1 /* darwin */ = {
+			isa = PBXGroup;
+			children = (
+				940DB8C716EA655400D3C2F1 /* sketch */,
+			);
+			path = darwin;
+			sourceTree = "<group>";
+		};
+		940DB8C716EA655400D3C2F1 /* sketch */ = {
+			isa = PBXGroup;
+			children = (
+				940DB8E616EA709400D3C2F1 /* main.cpp */,
+			);
+			path = sketch;
+			sourceTree = "<group>";
+		};
 		94CB255616B0683B0059775D /* DataFormatters */ = {
 			isa = PBXGroup;
 			children = (
@@ -3509,6 +3643,27 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		940DB89816EA5F4200D3C2F1 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				940DB8E016EA673800D3C2F1 /* Timer.h in Headers */,
+				940DB8CC16EA66FB00D3C2F1 /* Gauge.h in Headers */,
+				940DB8D416EA671800D3C2F1 /* MemoryGauge.h in Headers */,
+				940DB8DC16EA672D00D3C2F1 /* TestCase.h in Headers */,
+				940DB8F716EA76A400D3C2F1 /* CFCReleaser.h in Headers */,
+				940DB8E416EA674000D3C2F1 /* Xcode.h in Headers */,
+				940DB8F916EA76A400D3C2F1 /* CFCString.h in Headers */,
+				940DB8F016EA76A400D3C2F1 /* CFCData.h in Headers */,
+				940DB8F216EA76A400D3C2F1 /* CFCMutableArray.h in Headers */,
+				940DB8F616EA76A400D3C2F1 /* CFCMutableSet.h in Headers */,
+				940DB8D816EA672200D3C2F1 /* Metric.h in Headers */,
+				940DB8F416EA76A400D3C2F1 /* CFCMutableDictionary.h in Headers */,
+				940DB8D016EA670C00D3C2F1 /* Measurement.h in Headers */,
+				940DB8EE16EA76A400D3C2F1 /* CFCBundle.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 /* End PBXHeadersBuildPhase section */
 
 /* Begin PBXLegacyTarget section */
@@ -3621,6 +3776,42 @@
 			productReference = 26F5C26A10F3D9A4009D5894 /* lldb */;
 			productType = "com.apple.product-type.tool";
 		};
+		940DB89916EA5F4200D3C2F1 /* lldbperf */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 940DB8A816EA5F4200D3C2F1 /* Build configuration list for PBXNativeTarget "lldbperf" */;
+			buildPhases = (
+				940DB89616EA5F4200D3C2F1 /* Sources */,
+				940DB89716EA5F4200D3C2F1 /* Frameworks */,
+				940DB89816EA5F4200D3C2F1 /* Headers */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				940DB8BB16EA61D900D3C2F1 /* PBXTargetDependency */,
+			);
+			name = lldbperf;
+			productName = lldbperf;
+			productReference = 940DB89A16EA5F4200D3C2F1 /* lldbperf.a */;
+			productType = "com.apple.product-type.library.dynamic";
+		};
+		940DB8AC16EA60C900D3C2F1 /* lldb-perf-sketch */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 940DB8B316EA60CA00D3C2F1 /* Build configuration list for PBXNativeTarget "lldb-perf-sketch" */;
+			buildPhases = (
+				940DB8A916EA60C900D3C2F1 /* Sources */,
+				940DB8AA16EA60C900D3C2F1 /* Frameworks */,
+				940DB8AB16EA60C900D3C2F1 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				940DB8E916EA72BE00D3C2F1 /* PBXTargetDependency */,
+			);
+			name = "lldb-perf-sketch";
+			productName = "lldb-perf-sketch";
+			productReference = 940DB8AD16EA60C900D3C2F1 /* lldb-perf-sketch */;
+			productType = "com.apple.product-type.tool";
+		};
 		EDC6D49814E5C19B001B75F8 /* launcherXPCService */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = EDC6D4A614E5C19B001B75F8 /* Build configuration list for PBXNativeTarget "launcherXPCService" */;
@@ -3691,6 +3882,8 @@
 				EDC6D49814E5C19B001B75F8 /* launcherXPCService */,
 				EDE274E214EDCE1F005B0F75 /* launcherRootXPCService */,
 				2687EAC51508110B00DD8C2E /* install-headers */,
+				940DB89916EA5F4200D3C2F1 /* lldbperf */,
+				940DB8AC16EA60C900D3C2F1 /* lldb-perf-sketch */,
 			);
 		};
 /* End PBXProject section */
@@ -4264,6 +4457,32 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
+		940DB89616EA5F4200D3C2F1 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				940DB8EF16EA76A400D3C2F1 /* CFCData.cpp in Sources */,
+				940DB8F116EA76A400D3C2F1 /* CFCMutableArray.cpp in Sources */,
+				940DB8ED16EA76A400D3C2F1 /* CFCBundle.cpp in Sources */,
+				940DB8D316EA671800D3C2F1 /* MemoryGauge.cpp in Sources */,
+				940DB8DB16EA672D00D3C2F1 /* TestCase.cpp in Sources */,
+				940DB8E316EA674000D3C2F1 /* Xcode.cpp in Sources */,
+				940DB8DF16EA673800D3C2F1 /* Timer.cpp in Sources */,
+				940DB8D716EA672200D3C2F1 /* Metric.cpp in Sources */,
+				940DB8F516EA76A400D3C2F1 /* CFCMutableSet.cpp in Sources */,
+				940DB8F316EA76A400D3C2F1 /* CFCMutableDictionary.cpp in Sources */,
+				940DB8F816EA76A400D3C2F1 /* CFCString.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		940DB8A916EA60C900D3C2F1 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				940DB8E716EA709400D3C2F1 /* main.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		EDC6D49514E5C19B001B75F8 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -4350,6 +4569,16 @@
 			target = 2689FFC913353D7A00698AC0 /* lldb-core */;
 			targetProxy = 26DC6A151337FE7300FF7998 /* PBXContainerItemProxy */;
 		};
+		940DB8BB16EA61D900D3C2F1 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 26680206115FD0ED008E1FE4 /* LLDB */;
+			targetProxy = 940DB8BA16EA61D900D3C2F1 /* PBXContainerItemProxy */;
+		};
+		940DB8E916EA72BE00D3C2F1 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 940DB89916EA5F4200D3C2F1 /* lldbperf */;
+			targetProxy = 940DB8E816EA72BE00D3C2F1 /* PBXContainerItemProxy */;
+		};
 /* End PBXTargetDependency section */
 
 /* Begin XCBuildConfiguration section */
@@ -4713,7 +4942,6 @@
 				GCC_ENABLE_OBJC_GC = supported;
 				GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
 				HEADER_SEARCH_PATHS = /usr/include/libxml2;
-				LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/lldb-core.a";
 				MACH_O_TYPE = staticlib;
 				OTHER_CPLUSPLUSFLAGS = (
 					"-fno-rtti",
@@ -4743,7 +4971,6 @@
 				GCC_ENABLE_OBJC_GC = supported;
 				GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
 				HEADER_SEARCH_PATHS = /usr/include/libxml2;
-				LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/lldb-core.a";
 				MACH_O_TYPE = staticlib;
 				OTHER_CPLUSPLUSFLAGS = (
 					"-fno-rtti",
@@ -4773,7 +5000,6 @@
 				GCC_ENABLE_OBJC_GC = supported;
 				GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
 				HEADER_SEARCH_PATHS = /usr/include/libxml2;
-				LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/lldb-core.a";
 				MACH_O_TYPE = staticlib;
 				OTHER_CPLUSPLUSFLAGS = (
 					"-fno-rtti",
@@ -5485,7 +5711,6 @@
 				GCC_ENABLE_OBJC_GC = supported;
 				GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
 				HEADER_SEARCH_PATHS = /usr/include/libxml2;
-				LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/lldb-core.a";
 				MACH_O_TYPE = staticlib;
 				OTHER_CPLUSPLUSFLAGS = (
 					"-fno-rtti",
@@ -5662,6 +5887,186 @@
 			};
 			name = DebugClang;
 		};
+		940DB8A416EA5F4200D3C2F1 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				EXECUTABLE_EXTENSION = a;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/$(PRODUCT_NAME).a";
+				MACH_O_TYPE = staticlib;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(SRCROOT)/Tools";
+			};
+			name = Debug;
+		};
+		940DB8A516EA5F4200D3C2F1 /* DebugClang */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				EXECUTABLE_EXTENSION = a;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/$(PRODUCT_NAME).a";
+				MACH_O_TYPE = staticlib;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(SRCROOT)/Tools";
+			};
+			name = DebugClang;
+		};
+		940DB8A616EA5F4200D3C2F1 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				COPY_PHASE_STRIP = YES;
+				ENABLE_NS_ASSERTIONS = NO;
+				EXECUTABLE_EXTENSION = a;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/$(PRODUCT_NAME).a";
+				MACH_O_TYPE = staticlib;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(SRCROOT)/Tools $(SRCROOT)/source/Host/macosx/";
+			};
+			name = Release;
+		};
+		940DB8A716EA5F4200D3C2F1 /* BuildAndIntegration */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				COPY_PHASE_STRIP = YES;
+				ENABLE_NS_ASSERTIONS = NO;
+				EXECUTABLE_EXTENSION = a;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				LD_DYLIB_INSTALL_NAME = "$(DEVELOPER_DIR)/Library/PrivateFrameworks/LLDB.framework/Resources/$(PRODUCT_NAME).a";
+				MACH_O_TYPE = staticlib;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(SRCROOT)/Tools $(SRCROOT)/source/Host/macosx/";
+			};
+			name = BuildAndIntegration;
+		};
+		940DB8B416EA60CA00D3C2F1 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(SRCROOT)/Tools";
+			};
+			name = Debug;
+		};
+		940DB8B516EA60CA00D3C2F1 /* DebugClang */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(SRCROOT)/Tools";
+			};
+			name = DebugClang;
+		};
+		940DB8B616EA60CA00D3C2F1 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				COPY_PHASE_STRIP = YES;
+				ENABLE_NS_ASSERTIONS = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(SRCROOT)/Tools";
+			};
+			name = Release;
+		};
+		940DB8B716EA60CA00D3C2F1 /* BuildAndIntegration */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				COPY_PHASE_STRIP = YES;
+				ENABLE_NS_ASSERTIONS = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				USER_HEADER_SEARCH_PATHS = "$(SRCROOT)/include $(SRCROOT)/source $(LLVM_SOURCE_DIR)/include $(LLVM_SOURCE_DIR)/tools/clang/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/include $(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)/tools/clang/include $(SRCROOT)/Tools";
+			};
+			name = BuildAndIntegration;
+		};
 		EDC6D4A714E5C19B001B75F8 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
@@ -5964,6 +6369,26 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = BuildAndIntegration;
 		};
+		940DB8A816EA5F4200D3C2F1 /* Build configuration list for PBXNativeTarget "lldbperf" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				940DB8A416EA5F4200D3C2F1 /* Debug */,
+				940DB8A516EA5F4200D3C2F1 /* DebugClang */,
+				940DB8A616EA5F4200D3C2F1 /* Release */,
+				940DB8A716EA5F4200D3C2F1 /* BuildAndIntegration */,
+			);
+			defaultConfigurationIsVisible = 0;
+		};
+		940DB8B316EA60CA00D3C2F1 /* Build configuration list for PBXNativeTarget "lldb-perf-sketch" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				940DB8B416EA60CA00D3C2F1 /* Debug */,
+				940DB8B516EA60CA00D3C2F1 /* DebugClang */,
+				940DB8B616EA60CA00D3C2F1 /* Release */,
+				940DB8B716EA60CA00D3C2F1 /* BuildAndIntegration */,
+			);
+			defaultConfigurationIsVisible = 0;
+		};
 		EDC6D4A614E5C19B001B75F8 /* Build configuration list for PBXNativeTarget "launcherXPCService" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (

Modified: lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp?rev=176715&r1=176714&r2=176715&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp (original)
+++ lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp Fri Mar  8 14:29:13 2013
@@ -432,6 +432,44 @@ CFCMutableDictionary::SetValueUInt64(CFS
 }
 
 bool
+CFCMutableDictionary::AddValueDouble(CFStringRef key, double value, bool can_create)
+{
+    CFMutableDictionaryRef dict = Dictionary(can_create);
+    if (dict != NULL)
+    {
+        // The number may appear negative if the MSBit is set in "value". Due to a limitation of
+        // CFNumber, there isn't a way to have it show up otherwise as of this writing.
+        CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &value));
+        if (cf_number.get())
+        {
+            // Let the dictionary own the CFNumber
+            ::CFDictionaryAddValue (dict, key, cf_number.get());
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
+CFCMutableDictionary::SetValueDouble(CFStringRef key, double value, bool can_create)
+{
+    CFMutableDictionaryRef dict = Dictionary(can_create);
+    if (dict != NULL)
+    {
+        // The number may appear negative if the MSBit is set in "value". Due to a limitation of
+        // CFNumber, there isn't a way to have it show up otherwise as of this writing.
+        CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &value));
+        if (cf_number.get())
+        {
+            // Let the dictionary own the CFNumber
+            ::CFDictionarySetValue (dict, key, cf_number.get());
+            return true;
+        }
+    }
+    return false;
+}
+
+bool
 CFCMutableDictionary::AddValueCString(CFStringRef key, const char *cstr, bool can_create)
 {
     CFMutableDictionaryRef dict = Dictionary(can_create);

Modified: lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.h?rev=176715&r1=176714&r2=176715&view=diff
==============================================================================
--- lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.h (original)
+++ lldb/trunk/source/Host/macosx/cfcpp/CFCMutableDictionary.h Fri Mar  8 14:29:13 2013
@@ -53,6 +53,8 @@ public:
     bool    SetValueUInt32(CFStringRef key, uint32_t value, bool can_create = false);
     bool    AddValueUInt64(CFStringRef key, uint64_t value, bool can_create = false);
     bool    SetValueUInt64(CFStringRef key, uint64_t value, bool can_create = false);
+    bool    AddValueDouble(CFStringRef key, double value, bool can_create = false);
+    bool    SetValueDouble(CFStringRef key, double value, bool can_create = false);
     bool    AddValueCString(CFStringRef key, const char *cstr, bool can_create = false);
     bool    SetValueCString(CFStringRef key, const char *cstr, bool can_create = false);
     void    RemoveValue(const void *value);

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=176715&r1=176714&r2=176715&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Fri Mar  8 14:29:13 2013
@@ -1849,6 +1849,8 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
         {
             // The result is the number of ClassInfo structures that were filled in
             uint32_t num_class_infos = return_value.GetScalar().ULong();
+            if (log)
+                log->Printf("Discovered %u ObjC classes\n",num_class_infos);
             if (num_class_infos > 0)
             {
                 // Read the ClassInfo structures
@@ -2099,6 +2101,8 @@ AppleObjCRuntimeV2::UpdateISAToDescripto
         {
             // The result is the number of ClassInfo structures that were filled in
             uint32_t num_class_infos = return_value.GetScalar().ULong();
+            if (log)
+                log->Printf("Discovered %u ObjC classes in shared cache\n",num_class_infos);
             if (num_class_infos > 0)
             {
                 // Read the ClassInfo structures

Added: lldb/trunk/tools/lldb-perf/darwin/sketch/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/darwin/sketch/main.cpp?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/darwin/sketch/main.cpp (added)
+++ lldb/trunk/tools/lldb-perf/darwin/sketch/main.cpp Fri Mar  8 14:29:13 2013
@@ -0,0 +1,215 @@
+//
+//  main.cpp
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "lldb-perf/lib/Timer.h"
+#include "lldb-perf/lib/Metric.h"
+#include "lldb-perf/lib/Measurement.h"
+#include "lldb-perf/lib/TestCase.h"
+#include "lldb-perf/lib/Xcode.h"
+
+#include <iostream>
+#include <unistd.h>
+#include <fstream>
+
+using namespace lldb::perf;
+
+class SketchTest : public TestCase
+{
+public:
+    SketchTest () :
+    m_fetch_frames_measurement ([this] (SBProcess process) -> void {
+        Xcode::FetchFrames (process,false,false);
+    }, "fetch-frames"),
+    m_file_line_bp_measurement([] (SBTarget target,const char* file, uint32_t line) -> void {
+        Xcode::CreateFileLineBreakpoint(target, file, line);
+    }, "file-line-bkpt"),
+    m_fetch_modules_measurement ([] (SBTarget target) -> void {
+        Xcode::FetchModules(target);
+    }, "fetch-modules"),
+    m_fetch_vars_measurement([this] (SBProcess process, int depth) -> void {
+        auto threads_count = process.GetNumThreads();
+        for (size_t thread_num = 0; thread_num < threads_count; thread_num++)
+        {
+            SBThread thread(process.GetThreadAtIndex(thread_num));
+            SBFrame frame(thread.GetFrameAtIndex(0));
+            Xcode::FetchVariables(frame,depth,GetVerbose());
+            
+        }
+    }, "fetch-vars"),
+    m_run_expr_measurement([this] (SBFrame frame, const char* expr) -> void {
+        SBValue value(frame.EvaluateExpression(expr, lldb::eDynamicCanRunTarget));
+        Xcode::FetchVariable(value,0,GetVerbose());
+    }, "run-expr")
+    {}
+    
+    virtual
+    ~SketchTest ()
+    {
+    }
+    
+    virtual void
+	Setup (int argc, const char** argv)
+    {
+        m_app_path.assign(argv[1]); // "~/perf/Small_ObjC/Sketch/build/Debug/Sketch.app"
+        m_doc_path.assign(argv[2]); // "/Volumes/work/egranata/perf/Small_ObjC/TesterApp/foobar.sketch2";
+        m_out_path.assign(argv[3]);
+        TestCase::Setup(argc,argv);
+        m_target = m_debugger.CreateTarget(m_app_path.c_str());
+        const char* file_arg = m_doc_path.c_str(); 
+        const char* persist_arg = "-ApplePersistenceIgnoreState";
+        const char* persist_skip = "YES";
+        const char* empty = nullptr;
+        const char* args[] = {file_arg,persist_arg,persist_skip,empty};
+        m_file_line_bp_measurement(m_target, "SKTDocument.m",245);
+        m_file_line_bp_measurement(m_target, "SKTDocument.m",283);
+        m_file_line_bp_measurement(m_target, "SKTText.m",326);
+        
+        Launch (args,".");
+    }
+    
+    void
+    DoTest ()
+    {
+        m_fetch_frames_measurement(m_process);
+        m_fetch_modules_measurement(m_target);
+        m_fetch_vars_measurement(m_process,1);
+    }
+    
+	virtual ActionWanted
+	TestStep (int counter)
+    {
+#define STEP(n) if (counter == n)
+#define NEXT(s) return TestCase::ActionWanted{TestCase::ActionWanted::Type::eAWNext,SelectMyThread(s)}
+#define FINISH(s) return TestCase::ActionWanted{TestCase::ActionWanted::Type::eAWFinish,SelectMyThread(s)}
+#define CONT return TestCase::ActionWanted{TestCase::ActionWanted::Type::eAWContinue,SBThread()}
+#define KILL return TestCase::ActionWanted{TestCase::ActionWanted::Type::eAWKill,SBThread()}
+        STEP(0) {
+            DoTest ();
+            m_file_line_bp_measurement(m_target, "SKTDocument.m",254);
+            CONT;
+        }
+        STEP(1) {
+            DoTest ();
+            SBThread thread(SelectMyThread("SKTDocument.m"));
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"properties");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"[properties description]");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"typeName");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"data");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"[data description]");
+            CONT;
+        }
+        STEP(2) {
+            DoTest ();
+            CONT;
+        }
+        STEP(3) {
+            DoTest ();
+            NEXT("SKTText.m");
+        }
+        STEP(4) {
+            DoTest ();
+            SBThread thread(SelectMyThread("SKTText.m"));
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"layoutManager");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"contents");
+            NEXT("SKTText.m");
+        }
+        STEP(5) {
+            DoTest ();
+            NEXT("SKTText.m");
+        }
+        STEP(6) {
+            DoTest ();
+            NEXT("SKTText.m");
+        }
+        STEP(7) {
+            DoTest ();
+            SBThread thread(SelectMyThread("SKTText.m"));
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"@\"an NSString\"");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"[(id)@\"an NSString\" description]");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"@[@1, at 2, at 3]");
+            FINISH("SKTText.m");
+        }
+        STEP(8) {
+            DoTest ();
+            SBThread thread(SelectMyThread("SKTGraphicView.m"));
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"[graphics description]");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"[selectionIndexes description]");
+            m_run_expr_measurement(thread.GetFrameAtIndex(0),"(BOOL)NSIntersectsRect(rect, graphicDrawingBounds)");
+            KILL;
+        }
+        KILL;
+#undef STEP
+#undef NEXT
+#undef CONT
+#undef KILL
+    }
+    
+    void
+    Results ()
+    {
+        auto ff_metric = m_fetch_frames_measurement.metric();
+        auto fl_metric = m_file_line_bp_measurement.metric();
+        auto md_metric = m_fetch_modules_measurement.metric();
+        auto fv_metric = m_fetch_vars_measurement.metric();
+        auto xp_metric = m_run_expr_measurement.metric();
+        
+        CFCMutableArray array;
+        ff_metric.Write(array);
+        fl_metric.Write(array);
+        md_metric.Write(array);
+        fv_metric.Write(array);
+        xp_metric.Write(array);
+
+        CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, array.get(), kCFPropertyListXMLFormat_v1_0, 0, NULL);
+        
+        CFURLRef file = CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8*)m_out_path.c_str(), m_out_path.size(), FALSE);
+        
+        CFURLWriteDataAndPropertiesToResource(file,xmlData,NULL,NULL);
+    }
+    
+private:
+    Measurement<lldb::perf::TimeGauge, std::function<void(SBProcess)>> m_fetch_frames_measurement;
+    Measurement<lldb::perf::TimeGauge, std::function<void(SBTarget, const char*, uint32_t)>> m_file_line_bp_measurement;
+    Measurement<lldb::perf::TimeGauge, std::function<void(SBTarget)>> m_fetch_modules_measurement;
+    Measurement<lldb::perf::TimeGauge, std::function<void(SBProcess,int)>> m_fetch_vars_measurement;
+    Measurement<lldb::perf::TimeGauge, std::function<void(SBFrame,const char*)>> m_run_expr_measurement;
+    
+    SBThread
+	SelectMyThread (const char* file_name)
+	{
+		auto threads_count = m_process.GetNumThreads();
+		for (auto thread_num = 0; thread_num < threads_count; thread_num++)
+		{
+			SBThread thread(m_process.GetThreadAtIndex(thread_num));
+			auto local_file_name = thread.GetFrameAtIndex(0).GetCompileUnit().GetFileSpec().GetFilename();
+			if (!local_file_name)
+				continue;
+			if (strcmp(local_file_name,file_name))
+				continue;
+			return thread;
+		}
+		Xcode::RunCommand(m_debugger,"bt all",true);
+		assert(false);
+	}
+    std::string m_app_path;
+    std::string m_doc_path;
+    std::string m_out_path;
+};
+
+// argv[1] == path to app
+// argv[2] == path to document
+// argv[3] == path to result
+int main(int argc, const char * argv[])
+{
+    SketchTest skt;
+    TestCase::Run(skt,argc,argv);
+    return 0;
+}
+

Added: lldb/trunk/tools/lldb-perf/lib/Gauge.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/Gauge.h?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/Gauge.h (added)
+++ lldb/trunk/tools/lldb-perf/lib/Gauge.h Fri Mar  8 14:29:13 2013
@@ -0,0 +1,50 @@
+//
+//  Gauge.h
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/7/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef PerfTestDriver_Gauge_h
+#define PerfTestDriver_Gauge_h
+
+#include <functional>
+
+namespace lldb { namespace perf
+{
+template <class TASizeType>
+class Gauge
+{
+public:
+    typedef TASizeType SizeType;
+public:
+    Gauge ()
+    {}
+    
+    virtual
+    ~Gauge ()
+    {}
+    
+    virtual void
+    start () = 0;
+    
+    virtual SizeType
+    stop () = 0;
+    
+    virtual  SizeType
+    value () = 0;
+    
+    template <typename F, typename... Args>
+    SizeType
+    gauge (F f,Args... args)
+    {
+        start();
+        f(args...);
+        return stop();
+    }
+
+};
+} }
+
+#endif

Added: lldb/trunk/tools/lldb-perf/lib/Measurement.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/Measurement.h?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/Measurement.h (added)
+++ lldb/trunk/tools/lldb-perf/lib/Measurement.h Fri Mar  8 14:29:13 2013
@@ -0,0 +1,52 @@
+//
+//  Measurement.h
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/7/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__Measurement__
+#define __PerfTestDriver__Measurement__
+
+#include "Gauge.h"
+#include "Metric.h"
+
+namespace lldb { namespace perf
+{
+template <typename GaugeType, typename Action>
+class Measurement : public WriteToPList
+{
+public:
+    Measurement (Action act, const char* name = NULL)  :
+    m_action (act),
+    m_metric (Metric<typename GaugeType::SizeType>(name))
+    {}
+
+    template <typename... Args>
+    void
+    operator () (Args... args)
+    {
+        GaugeType gauge;
+        m_metric.append (gauge.gauge(m_action,args...));
+    }
+    
+    Metric<typename GaugeType::SizeType>
+    metric ()
+    {
+        return m_metric;
+    }
+    
+    virtual void
+    Write (CFCMutableArray& parent)
+    {
+        m_metric.Write(parent);
+    }
+
+private:
+    Action m_action;
+    Metric<typename GaugeType::SizeType> m_metric;
+};
+} }
+
+#endif /* defined(__PerfTestDriver__Measurement__) */

Added: lldb/trunk/tools/lldb-perf/lib/MemoryGauge.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/MemoryGauge.cpp?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/MemoryGauge.cpp (added)
+++ lldb/trunk/tools/lldb-perf/lib/MemoryGauge.cpp Fri Mar  8 14:29:13 2013
@@ -0,0 +1,54 @@
+//
+//  MemoryGauge.cpp
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "MemoryGauge.h"
+#include <assert.h>
+#include <mach/task.h>
+
+using namespace lldb::perf;
+
+MemoryGauge::SizeType
+MemoryGauge::now ()
+{
+    task_t task = MACH_PORT_NULL;
+    mach_task_basic_info_data_t taskBasicInfo;
+    mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
+    if (task_info(task, MACH_TASK_BASIC_INFO, (task_info_t) & taskBasicInfo, &count) == KERN_SUCCESS) {
+        return taskBasicInfo.virtual_size;
+    }
+    return 0;
+}
+
+MemoryGauge::MemoryGauge () :
+m_start(),
+m_state(MemoryGauge::State::eMSNeverUsed)
+{
+}
+
+void
+MemoryGauge::start ()
+{
+	m_state = MemoryGauge::State::eMSCounting;
+	m_start = now();
+}
+
+MemoryGauge::SizeType
+MemoryGauge::stop ()
+{
+	auto stop = now();
+	assert(m_state == MemoryGauge::State::eMSCounting && "cannot stop a non-started gauge");
+	m_state = MemoryGauge::State::eMSStopped;
+	return (m_value = stop-m_start);
+}
+
+MemoryGauge::SizeType
+MemoryGauge::value ()
+{
+	assert(m_state == MemoryGauge::State::eMSStopped && "gauge must be used before you can evaluate it");
+	return m_value;
+}

Added: lldb/trunk/tools/lldb-perf/lib/MemoryGauge.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/MemoryGauge.h?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/MemoryGauge.h (added)
+++ lldb/trunk/tools/lldb-perf/lib/MemoryGauge.h Fri Mar  8 14:29:13 2013
@@ -0,0 +1,53 @@
+//
+//  MemoryGauge.h
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__MemoryGauge__
+#define __PerfTestDriver__MemoryGauge__
+
+#include "Gauge.h"
+
+#include <mach/task_info.h>
+
+namespace lldb { namespace perf
+{
+class MemoryGauge : public Gauge<mach_vm_size_t>
+{
+private:
+    enum class State
+    {
+        eMSNeverUsed,
+        eMSCounting,
+        eMSStopped
+    };
+    
+    SizeType
+    now ();
+    
+    SizeType m_start;
+    State m_state;
+    SizeType m_value;
+
+public:
+    MemoryGauge ();
+    
+    virtual
+    ~MemoryGauge ()
+    {}
+    
+    void
+    start ();
+    
+    SizeType
+    stop ();
+    
+    SizeType
+    value ();
+};
+} }
+
+#endif /* defined(__PerfTestDriver__MemoryGauge__) */

Added: lldb/trunk/tools/lldb-perf/lib/Metric.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/Metric.cpp?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/Metric.cpp (added)
+++ lldb/trunk/tools/lldb-perf/lib/Metric.cpp Fri Mar  8 14:29:13 2013
@@ -0,0 +1,84 @@
+//
+//  Metric.cpp
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/7/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "Metric.h"
+
+#include "CFCMutableArray.h"
+#include "CFCMutableDictionary.h"
+#include "CFCString.h"
+
+using namespace lldb::perf;
+
+template <class T>
+Metric<T>::Metric () : Metric ("")
+{}
+
+template <class T>
+Metric<T>::Metric (const char* n) :
+m_name(n ? n : ""),
+m_dataset ()
+{}
+
+template <class T>
+void
+Metric<T>::append (T v)
+{
+    m_dataset.push_back(v);
+}
+
+template <class T>
+size_t
+Metric<T>::count ()
+{
+    return m_dataset.size();
+}
+
+template <class T>
+T
+Metric<T>::sum ()
+{
+    T sum = 0;
+    for (auto v : m_dataset)
+        sum += v;
+    return sum;
+}
+
+template <class T>
+T
+Metric<T>::average ()
+{
+    return sum()/count();
+}
+
+template <class T>
+const char*
+Metric<T>::name ()
+{
+    return m_name.c_str();
+}
+
+template <class T>
+void Metric<T>::WriteImpl (CFCMutableArray& parent, identity<double>)
+{
+    CFCMutableDictionary dict;
+    dict.AddValueCString(CFCString("name").get(),m_name.c_str(), true);
+    dict.AddValueDouble(CFCString("value").get(),this->average(), true);
+    parent.AppendValue(dict.get(), true);
+}
+
+template <class T>
+void Metric<T>::WriteImpl (CFCMutableArray& parent, identity<mach_vm_size_t>)
+{
+    CFCMutableDictionary dict;
+    dict.AddValueCString(CFCString("name").get(),m_name.c_str(), true);
+    dict.AddValueUInt64(CFCString("value").get(),this->average(), true);
+    parent.AppendValue(dict.get(), true);
+}
+
+template class lldb::perf::Metric<double>;
+template class lldb::perf::Metric<mach_vm_size_t>;

Added: lldb/trunk/tools/lldb-perf/lib/Metric.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/Metric.h?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/Metric.h (added)
+++ lldb/trunk/tools/lldb-perf/lib/Metric.h Fri Mar  8 14:29:13 2013
@@ -0,0 +1,71 @@
+//
+//  Metric.h
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/7/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__Metric__
+#define __PerfTestDriver__Metric__
+
+#include <vector>
+#include <string>
+#include <mach/task_info.h>
+
+#include "CFCMutableArray.h"
+
+namespace lldb { namespace perf
+{
+class WriteToPList
+{
+public:
+    virtual void
+    Write (CFCMutableArray& parent) = 0;
+    
+    virtual
+    ~WriteToPList () {}
+};
+
+template <class ValueType>
+class Metric : public WriteToPList {
+public:
+    Metric ();
+    Metric (const char*);
+    
+    void
+    append (ValueType v);
+    
+    size_t
+    count ();
+    
+    ValueType
+    sum ();
+    
+    ValueType
+    average ();
+    
+    const char*
+    name ();
+    
+    virtual void
+    Write (CFCMutableArray& parent)
+    {
+        WriteImpl(parent, identity<ValueType>());
+    }
+    
+private:
+
+    template<typename T>
+    struct identity { typedef T type; };
+    
+    void WriteImpl (CFCMutableArray& parent, identity<double>);
+
+    void WriteImpl (CFCMutableArray& parent, identity<mach_vm_size_t>);
+    
+    std::string m_name;
+    std::vector<ValueType> m_dataset;
+};
+} }
+
+#endif /* defined(__PerfTestDriver__Metric__) */

Added: lldb/trunk/tools/lldb-perf/lib/TestCase.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/TestCase.cpp?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/TestCase.cpp (added)
+++ lldb/trunk/tools/lldb-perf/lib/TestCase.cpp Fri Mar  8 14:29:13 2013
@@ -0,0 +1,178 @@
+//
+//  TestCase.cpp
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/7/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "TestCase.h"
+#include "Xcode.h"
+
+using namespace lldb::perf;
+
+TestCase::TestCase () :
+m_debugger(),
+m_target(),
+m_process(),
+m_thread(),
+m_listener(),
+m_verbose(false)
+{}
+
+void
+TestCase::Setup (int argc, const char** argv)
+{
+	SBDebugger::Initialize();
+	SBHostOS::ThreadCreated ("<lldb-tester.app.main>");
+	m_debugger = SBDebugger::Create(false);
+	m_listener = m_debugger.GetListener();
+}
+
+bool
+TestCase::Launch (const char** args, const char* cwd)
+{
+	m_process = m_target.LaunchSimple(args,NULL,cwd);
+	m_process.GetBroadcaster().AddListener(m_listener, SBProcess::eBroadcastBitStateChanged | SBProcess::eBroadcastBitInterrupt);
+	return m_process.IsValid ();
+}
+
+void
+TestCase::SetVerbose (bool b)
+{
+    m_verbose = b;
+}
+
+bool
+TestCase::GetVerbose ()
+{
+    return m_verbose;
+}
+
+void
+TestCase::Loop ()
+{
+	int step = 0;
+	SBEvent evt;
+	while (true)
+	{
+		m_listener.WaitForEvent (UINT32_MAX,evt);
+		StateType state = SBProcess::GetStateFromEvent (evt);
+		if (m_verbose)
+			printf("event = %s\n",SBDebugger::StateAsCString(state));
+		if (SBProcess::GetRestartedFromEvent(evt))
+			continue;
+		switch (state)
+		{
+			case eStateInvalid:
+			case eStateDetached:
+			case eStateCrashed:
+			case eStateUnloaded:
+				break;
+			case eStateExited:
+				return;
+			case eStateConnected:
+			case eStateAttaching:
+			case eStateLaunching:
+			case eStateRunning:
+			case eStateStepping:
+				continue;
+			case eStateStopped:
+			case eStateSuspended:
+			{
+				bool fatal = false;
+				for (auto thread_index = 0; thread_index < m_process.GetNumThreads(); thread_index++)
+				{
+					SBThread thread(m_process.GetThreadAtIndex(thread_index));
+					SBFrame frame(thread.GetFrameAtIndex(0));
+					StopReason stop_reason = thread.GetStopReason();
+					if (m_verbose) printf("tid = 0x%llx pc = 0x%llx ",thread.GetThreadID(),frame.GetPC());
+					switch (stop_reason)
+					{
+				        case eStopReasonNone:
+                            if (m_verbose) printf("none\n");
+                            break;
+                            
+				        case eStopReasonTrace:
+                            if (m_verbose) printf("trace\n");
+                            break;
+                            
+				        case eStopReasonPlanComplete:
+                            if (m_verbose) printf("plan complete\n");
+                            break;
+				        case eStopReasonThreadExiting:
+                            if (m_verbose) printf("thread exiting\n");
+                            break;
+				        case eStopReasonExec:
+                            if (m_verbose) printf("exec\n");
+                            break;
+						case eStopReasonInvalid:
+                            if (m_verbose) printf("invalid\n");
+                            break;
+			        	case eStopReasonException:
+                            if (m_verbose) printf("exception\n");
+                            fatal = true;
+                            break;
+				        case eStopReasonBreakpoint:
+                            if (m_verbose) printf("breakpoint id = %lld.%lld\n",thread.GetStopReasonDataAtIndex(0),thread.GetStopReasonDataAtIndex(1));
+                            break;
+				        case eStopReasonWatchpoint:
+                            if (m_verbose) printf("watchpoint id = %lld\n",thread.GetStopReasonDataAtIndex(0));
+                            break;
+				        case eStopReasonSignal:
+                            if (m_verbose) printf("signal %d\n",(int)thread.GetStopReasonDataAtIndex(0));
+                            break;
+					}
+				}
+				if (fatal)
+				{
+					if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
+					exit(1);
+				}
+				if (m_verbose)
+					printf("RUNNING STEP %d\n",step);
+				auto action = TestStep(step);
+				step++;
+				switch (action.type)
+				{
+					case ActionWanted::Type::eAWContinue:
+						m_debugger.HandleCommand("continue");
+						break;
+                    case ActionWanted::Type::eAWFinish:
+                        if (action.thread.IsValid() == false)
+                        {
+                            if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
+                            if (m_verbose) printf("[finish invalid] I am gonna die at step %d\n",step);
+                            exit(501);
+                        }
+                        m_process.SetSelectedThread(action.thread);
+                        m_debugger.HandleCommand("finish");
+						break;
+					case ActionWanted::Type::eAWNext:
+                        if (action.thread.IsValid() == false)
+                        {
+                            if (m_verbose) Xcode::RunCommand(m_debugger,"bt all",true);
+                            if (m_verbose) printf("[next invalid] I am gonna die at step %d\n",step);
+                            exit(500);
+                        }
+                        m_process.SetSelectedThread(action.thread);
+                        m_debugger.HandleCommand("next");
+						break;
+					case ActionWanted::Type::eAWKill:
+						if (m_verbose) printf("I want to die\n");
+						m_process.Kill();
+						return;
+				}
+			}
+		}
+	}
+	if (GetVerbose()) printf("I am gonna die at step %d\n",step);
+}
+
+void
+TestCase::Run (TestCase& test, int argc, const char** argv)
+{
+    test.Setup(argc, argv);
+    test.Loop();
+    test.Results();
+}

Added: lldb/trunk/tools/lldb-perf/lib/TestCase.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/TestCase.h?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/TestCase.h (added)
+++ lldb/trunk/tools/lldb-perf/lib/TestCase.h Fri Mar  8 14:29:13 2013
@@ -0,0 +1,80 @@
+//
+//  TestCase.h
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/7/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__TestCase__
+#define __PerfTestDriver__TestCase__
+
+#include "lldb/API/LLDB.h"
+#include "Measurement.h"
+
+using namespace lldb;
+
+namespace lldb { namespace perf
+{
+class TestCase
+{
+public:
+    TestCase();
+    
+    struct ActionWanted
+	{
+		enum class Type
+		{
+			eAWNext,
+			eAWContinue,
+            eAWFinish,
+			eAWKill
+		} type;
+		SBThread thread;
+	};
+    
+    virtual
+    ~TestCase ()
+    {}
+    
+	virtual void
+	Setup (int argc, const char** argv);
+    
+	virtual ActionWanted
+	TestStep (int counter) = 0;
+	
+	bool
+	Launch (const char** args, const char* cwd);
+	
+	void
+	Loop();
+    
+    void
+    SetVerbose (bool);
+    
+    bool
+    GetVerbose ();
+    
+    virtual void
+    Results () = 0;
+    
+    template <typename G,typename A>
+    Measurement<G,A> CreateMeasurement (A a, const char* name = NULL)
+    {
+        return Measurement<G,A> (a,name);
+    }
+    
+    static void
+    Run (TestCase& test, int argc, const char** argv);
+    
+protected:
+	SBDebugger m_debugger;
+	SBTarget m_target;
+	SBProcess m_process;
+	SBThread m_thread;
+	SBListener m_listener;
+    bool m_verbose;
+};
+} }
+
+#endif /* defined(__PerfTestDriver__TestCase__) */

Added: lldb/trunk/tools/lldb-perf/lib/Timer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/Timer.cpp?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/Timer.cpp (added)
+++ lldb/trunk/tools/lldb-perf/lib/Timer.cpp Fri Mar  8 14:29:13 2013
@@ -0,0 +1,47 @@
+//
+//  Timer.cpp
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "Timer.h"
+#include <assert.h>
+
+using namespace lldb::perf;
+
+TimeGauge::HPTime
+TimeGauge::now ()
+{
+	return high_resolution_clock::now();
+}
+
+TimeGauge::TimeGauge () :
+m_start(),
+m_state(TimeGauge::State::eTSNeverUsed)
+{
+}
+
+void
+TimeGauge::start ()
+{
+	m_state = TimeGauge::State::eTSCounting;
+	m_start = now();
+}
+
+double
+TimeGauge::stop ()
+{
+	auto stop = now();
+	assert(m_state == TimeGauge::State::eTSCounting && "cannot stop a non-started clock");
+	m_state = TimeGauge::State::eTSStopped;
+	return (m_value = duration_cast<duration<double>>(stop-m_start).count());
+}
+
+double
+TimeGauge::value ()
+{
+	assert(m_state == TimeGauge::State::eTSStopped && "clock must be used before you can evaluate it");
+	return m_value;
+}

Added: lldb/trunk/tools/lldb-perf/lib/Timer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/Timer.h?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/Timer.h (added)
+++ lldb/trunk/tools/lldb-perf/lib/Timer.h Fri Mar  8 14:29:13 2013
@@ -0,0 +1,56 @@
+//
+//  Timer.h
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__Timer__
+#define __PerfTestDriver__Timer__
+
+#include "Gauge.h"
+
+#include <chrono>
+
+using namespace std::chrono;
+
+namespace lldb { namespace perf
+{
+class TimeGauge : public Gauge<double>
+{
+private:
+    enum class State
+    {
+        eTSNeverUsed,
+        eTSCounting,
+        eTSStopped
+    };
+    
+    typedef high_resolution_clock::time_point HPTime;
+    HPTime m_start;
+    double m_value;
+    State m_state;
+    
+    HPTime
+    now ();
+    
+public:
+    TimeGauge ();
+    
+    virtual
+    ~TimeGauge ()
+    {}
+    
+    void
+    start ();
+    
+    double
+    stop ();
+    
+    double
+    value ();
+};
+} }
+
+#endif /* defined(__PerfTestDriver__Timer__) */

Added: lldb/trunk/tools/lldb-perf/lib/Xcode.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/Xcode.cpp?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/Xcode.cpp (added)
+++ lldb/trunk/tools/lldb-perf/lib/Xcode.cpp Fri Mar  8 14:29:13 2013
@@ -0,0 +1,164 @@
+//
+//  Xcode.cpp
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#include "Xcode.h"
+#include <string>
+
+using namespace std;
+using namespace lldb::perf;
+
+void
+Xcode::FetchVariable (SBValue value, uint32_t expand, bool verbose)
+{
+	auto name = value.GetName();
+	auto num_value = value.GetValueAsUnsigned(0);
+	auto summary = value.GetSummary();
+	auto in_scope = value.IsInScope();
+	auto has_children = value.MightHaveChildren();
+	auto type_1 = value.GetType();
+	auto type_2 = value.GetType();
+	auto type_name_1 = value.GetTypeName();
+	auto type_3 = value.GetType();
+	auto type_name_2 = value.GetTypeName();
+	if (verbose)
+		printf("%s %s = %llu %s\n",value.GetTypeName(),value.GetName(),num_value,summary);
+	if (expand > 0)
+	{
+		auto count = value.GetNumChildren();
+		for (int i = 0; i < count; i++)
+		{
+			SBValue child(value.GetChildAtIndex(i));
+			FetchVariable (child,expand-1,verbose);
+		}
+	}
+}
+
+void
+Xcode::FetchModules (SBTarget target, bool verbose)
+{
+	auto count = target.GetNumModules();
+	for (int i = 0; i < count; i++)
+	{
+		SBModule module(target.GetModuleAtIndex(i));
+		auto fspec = module.GetFileSpec();
+		std::string path(1024,0);
+		fspec.GetPath(&path[0],1024);
+		auto uuid = module.GetUUIDBytes();
+		if (verbose)
+		{
+			printf("%s %s\n",path.c_str(),module.GetUUIDString());
+		}
+	}
+}
+
+void
+Xcode::FetchVariables (SBFrame frame, uint32_t expand, bool verbose)
+{
+	auto values = frame.GetVariables (true,true,true,false, eDynamicCanRunTarget);
+	auto count = values.GetSize();
+	for (int i = 0; i < count; i++)
+	{
+		SBValue value(values.GetValueAtIndex(i));
+		FetchVariable (value,expand,verbose);
+	}
+}
+
+void
+Xcode::FetchFrames(SBProcess process, bool variables, bool verbose)
+{
+	auto pCount = process.GetNumThreads();
+	for (int p = 0; p < pCount; p++)
+	{
+		SBThread thread(process.GetThreadAtIndex(p));
+		auto tCount = thread.GetNumFrames ();
+		if (verbose)
+			printf("%s %d %d {%d}\n",thread.GetQueueName(),tCount,thread.GetStopReason(),eStopReasonBreakpoint);
+		for (int t = 0; t < tCount; t++)
+		{
+			SBFrame frame(thread.GetFrameAtIndex(t));
+			auto fp = frame.GetFP();
+			SBThread thread_dup = frame.GetThread();
+			SBFileSpec filespec(process.GetTarget().GetExecutable());
+			std::string path(1024,0);
+			filespec.GetPath(&path[0],1024);
+			auto state = process.GetState();
+			auto pCount_dup = process.GetNumThreads();
+			auto byte_size = process.GetAddressByteSize();
+			auto pc = frame.GetPC();
+			SBSymbolContext context(frame.GetSymbolContext(0x0000006e));
+			SBModule module(context.GetModule());
+			SBLineEntry entry(context.GetLineEntry());
+			SBFileSpec entry_filespec(process.GetTarget().GetExecutable());
+			std::string entry_path(1024,0);
+			entry_filespec.GetPath(&entry_path[0],1024);
+			auto line_1 = entry.GetLine();
+			auto line_2 = entry.GetLine();
+			auto fname = frame.GetFunctionName();
+			if (verbose)
+				printf("%llu %s %d %d %llu %s %d %s\n",fp,path.c_str(),state,byte_size,pc,entry_path.c_str(),line_1,fname);
+			if (variables)
+				FetchVariables (frame, 0, verbose);
+		}
+	}
+}
+
+void
+Xcode::RunExpression (SBFrame frame, const char* expression, bool po, bool verbose)
+{
+	SBValue value (frame.EvaluateExpression (expression, eDynamicCanRunTarget));
+	FetchVariable (value,0,verbose);
+	if (po)
+	{
+		auto descr = value.GetObjectDescription();
+		if (descr)
+			printf("%s\n",descr);
+	}
+}
+
+void
+Xcode::Next (SBThread thread)
+{
+	thread.StepOver();
+}
+
+void
+Xcode::Continue (SBProcess process)
+{
+	process.Continue();
+}
+
+void
+Xcode::RunCommand (SBDebugger debugger, const char* cmd, bool verbose)
+{
+	SBCommandReturnObject sb_ret;
+	auto interpreter = debugger.GetCommandInterpreter();
+	interpreter.HandleCommand(cmd,sb_ret);
+	if (verbose)
+		printf("%s\n%s\n",sb_ret.GetOutput(false),sb_ret.GetError(false));
+}
+
+SBThread
+Xcode::GetThreadWithStopReason (SBProcess process, StopReason reason)
+{
+	auto threads_count = process.GetNumThreads();
+	for (auto thread_num = 0; thread_num < threads_count; thread_num++)
+	{
+		SBThread thread(process.GetThreadAtIndex(thread_num));
+		if (thread.GetStopReason() == reason)
+		{
+			return thread;
+		}
+	}
+	return SBThread();
+}
+
+SBBreakpoint
+Xcode::CreateFileLineBreakpoint (SBTarget target, const char* file, uint32_t line)
+{
+    return target.BreakpointCreateByLocation(file, line);
+}

Added: lldb/trunk/tools/lldb-perf/lib/Xcode.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-perf/lib/Xcode.h?rev=176715&view=auto
==============================================================================
--- lldb/trunk/tools/lldb-perf/lib/Xcode.h (added)
+++ lldb/trunk/tools/lldb-perf/lib/Xcode.h Fri Mar  8 14:29:13 2013
@@ -0,0 +1,63 @@
+//
+//  Xcode.h
+//  PerfTestDriver
+//
+//  Created by Enrico Granata on 3/6/13.
+//  Copyright (c) 2013 Apple Inc. All rights reserved.
+//
+
+#ifndef __PerfTestDriver__Xcode__
+#define __PerfTestDriver__Xcode__
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBValue.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBModule.h"
+#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBLineEntry.h"
+#include "lldb/API/SBThread.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBCommandInterpreter.h"
+#include "lldb/API/SBCommandReturnObject.h"
+#include "lldb/API/SBBreakpoint.h"
+
+using namespace lldb;
+
+namespace lldb { namespace perf
+{
+class Xcode
+{
+public:
+	static void
+	FetchVariable (SBValue value, uint32_t expand = 0, bool verbose = false);
+    
+	static void
+	FetchModules (SBTarget target, bool verbose = false);
+    
+	static void
+	FetchVariables (SBFrame frame, uint32_t expand = 0, bool verbose = false);
+    
+	static void
+	FetchFrames (SBProcess process, bool variables = false, bool verbose = false);
+	
+	static void
+	RunExpression (SBFrame frame, const char* expression, bool po = false, bool verbose = false);
+	
+	static void
+	Next (SBThread thread);
+	
+	static void
+	Continue (SBProcess process);
+	
+	static void
+	RunCommand (SBDebugger debugger, const char* cmd, bool verbose = false);
+	
+	static SBThread
+	GetThreadWithStopReason (SBProcess process, StopReason reason);
+    
+    static SBBreakpoint
+    CreateFileLineBreakpoint (SBTarget target, const char* file, uint32_t line);
+};
+} }
+
+#endif /* defined(__PerfTestDriver__Xcode__) */





More information about the lldb-commits mailing list