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.

llvm-svn: 176715
This commit is contained in:
Enrico Granata 2013-03-08 20:29:13 +00:00
parent 8106d8082c
commit f58cececaa
18 changed files with 1642 additions and 4 deletions

View File

@ -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()

View File

@ -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 = (

View File

@ -431,6 +431,44 @@ CFCMutableDictionary::SetValueUInt64(CFStringRef key, uint64_t value, bool can_c
return false;
}
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)
{

View File

@ -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);

View File

@ -1849,6 +1849,8 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
{
// 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::UpdateISAToDescriptorMapSharedCache()
{
// 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

View File

@ -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,@2,@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;
}

View File

@ -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

View File

@ -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__) */

View File

@ -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;
}

View File

@ -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__) */

View File

@ -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>;

View File

@ -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__) */

View File

@ -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();
}

View File

@ -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__) */

View File

@ -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;
}

View File

@ -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__) */

View File

@ -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);
}

View File

@ -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__) */