├── .gitignore ├── LICENSE ├── PerformanceMonitor.podspec ├── PerformanceMonitor.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ ├── ming.xcuserdatad │ │ ├── IDEFindNavigatorScopes.plist │ │ └── UserInterfaceState.xcuserstate │ │ └── roy.cao.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── roy.cao.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── PerformanceMonitor.xcworkspace └── contents.xcworkspacedata ├── PerformanceMonitor ├── Assets.xcassets │ └── Contents.json ├── CPU │ └── CPUMonitor.swift ├── FPS │ └── FPSMonitor.swift ├── Fluecy │ └── FluecyMonitor.swift ├── Info.plist ├── Memory │ └── MemoryMonitor.swift ├── MethodTimeMonitor │ ├── MethodTimeMonitor.h │ ├── MethodTimeMonitor.mm │ ├── MethodTimeMonitor.swift │ ├── ThreadLocal.swift │ ├── xt_forwarding_trampoline_arm64.s │ ├── xt_forwarding_trampoline_arm7.s │ ├── xt_forwarding_trampoline_x64.s │ └── xt_forwarding_trampoline_x86.s ├── PerformanceMonitor.h ├── PerformanceMonitor.swift └── UI │ ├── PerformanceView.swift │ └── PerformanceViewController.swift ├── PerformanceMonitorDemo ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── cat.imageset │ │ ├── Contents.json │ │ └── cat.png │ └── city.imageset │ │ ├── Contents.json │ │ └── city.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── FPSTestViewController.swift ├── Info.plist └── ViewController.swift ├── PerformanceMonitorTests ├── Info.plist └── PerformanceMonitorTests.swift ├── Podfile ├── Podfile.lock └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | IDEWorkspaceChecks.plist 20 | 21 | ## Other 22 | *.moved-aside 23 | *.xccheckout 24 | *.xcscmblueprint 25 | .DS_Store 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | .build/ 44 | 45 | # CocoaPods 46 | # 47 | # We recommend against adding the Pods directory to your .gitignore. However 48 | # you should judge for yourself, the pros and cons are mentioned at: 49 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 50 | Pods/ 51 | 52 | # Carthage 53 | # 54 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 55 | Carthage/Checkouts 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Kris 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PerformanceMonitor.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'PerformanceMonitor' 3 | spec.version = '0.0.6' 4 | spec.license = 'MIT' 5 | spec.summary = 'PerformanceMonitor is a non-invasive APM system, Including monitoring CPU,Memory,FPS,Recording all OC and Swift methods time consuming,etc.' 6 | spec.homepage = 'https://github.com/woshiccm/PerformanceMonitor' 7 | spec.author = "roy" 8 | spec.source = { :git => "https://github.com/woshiccm/PerformanceMonitor.git", :tag => spec.version } 9 | spec.license = 'Code is private.' 10 | 11 | spec.platforms = { :ios => '9.0' } 12 | spec.requires_arc = true 13 | 14 | spec.cocoapods_version = '>= 1.4' 15 | spec.swift_version = ['4.2', '5.0'] 16 | 17 | spec.source_files = 'PerformanceMonitor/**/*.{h,mm,swift,s}' 18 | 19 | spec.dependency 'RCBacktrace', '~> 0.1.7' 20 | end 21 | -------------------------------------------------------------------------------- /PerformanceMonitor.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3A4D8BE023111FC300C22EFD /* PerformanceMonitor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A4D8BD623111FC300C22EFD /* PerformanceMonitor.framework */; }; 11 | 3A4D8BE523111FC300C22EFD /* PerformanceMonitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D8BE423111FC300C22EFD /* PerformanceMonitorTests.swift */; }; 12 | 3A4D8BE723111FC300C22EFD /* PerformanceMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A4D8BD923111FC300C22EFD /* PerformanceMonitor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 3A4D8BF12311200E00C22EFD /* PerformanceMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D8BF02311200E00C22EFD /* PerformanceMonitor.swift */; }; 14 | 3A4D8BF32311253900C22EFD /* CPUMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D8BF22311253900C22EFD /* CPUMonitor.swift */; }; 15 | 3A4D8BF52311254900C22EFD /* MemoryMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D8BF42311254900C22EFD /* MemoryMonitor.swift */; }; 16 | 3A4D8C40231162A200C22EFD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D8C3F231162A200C22EFD /* AppDelegate.swift */; }; 17 | 3A4D8C42231162A200C22EFD /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D8C41231162A200C22EFD /* ViewController.swift */; }; 18 | 3A4D8C45231162A200C22EFD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3A4D8C43231162A200C22EFD /* Main.storyboard */; }; 19 | 3A4D8C47231162A400C22EFD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3A4D8C46231162A300C22EFD /* Assets.xcassets */; }; 20 | 3A4D8C4A231162A400C22EFD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3A4D8C48231162A400C22EFD /* LaunchScreen.storyboard */; }; 21 | 3A4D8C56231173C800C22EFD /* FPSMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D8C55231173C800C22EFD /* FPSMonitor.swift */; }; 22 | 3A4D8C94231299BE00C22EFD /* FluecyMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D8C93231299BE00C22EFD /* FluecyMonitor.swift */; }; 23 | 45039AE57284072FADDFFD41 /* Pods_PerformanceMonitorDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33CDBE8B399B0FD29828E8BB /* Pods_PerformanceMonitorDemo.framework */; }; 24 | 9C1017A42313CAF000158CA4 /* PerformanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C1017A32313CAF000158CA4 /* PerformanceView.swift */; }; 25 | 9C1017A72313DB2700158CA4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9C1017A62313DB2700158CA4 /* Assets.xcassets */; }; 26 | 9C1017A92313DCB700158CA4 /* PerformanceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C1017A82313DCB700158CA4 /* PerformanceViewController.swift */; }; 27 | 9C1017AB23140D7B00158CA4 /* FPSTestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C1017AA23140D7B00158CA4 /* FPSTestViewController.swift */; }; 28 | 9C1CD2AF2327A7D000B67B84 /* MethodTimeMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1CD2AE2327A7D000B67B84 /* MethodTimeMonitor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | 9C4A2B53231BCF160066342F /* RCBacktrace.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C4A2B52231BCF160066342F /* RCBacktrace.framework */; }; 30 | 9C4A2B55231BCF320066342F /* PerformanceMonitor.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3A4D8BD623111FC300C22EFD /* PerformanceMonitor.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 31 | 9CDEF88B232510E000E7D77B /* ThreadLocal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDEF882232510E000E7D77B /* ThreadLocal.swift */; }; 32 | 9CDEF88C232510E000E7D77B /* xt_forwarding_trampoline_arm7.s in Sources */ = {isa = PBXBuildFile; fileRef = 9CDEF883232510E000E7D77B /* xt_forwarding_trampoline_arm7.s */; }; 33 | 9CDEF88D232510E000E7D77B /* MethodTimeMonitor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9CDEF884232510E000E7D77B /* MethodTimeMonitor.mm */; }; 34 | 9CDEF88F232510E000E7D77B /* MethodTimeMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDEF886232510E000E7D77B /* MethodTimeMonitor.swift */; }; 35 | 9CDEF890232510E000E7D77B /* xt_forwarding_trampoline_x64.s in Sources */ = {isa = PBXBuildFile; fileRef = 9CDEF887232510E000E7D77B /* xt_forwarding_trampoline_x64.s */; }; 36 | 9CDEF892232510E000E7D77B /* xt_forwarding_trampoline_arm64.s in Sources */ = {isa = PBXBuildFile; fileRef = 9CDEF889232510E000E7D77B /* xt_forwarding_trampoline_arm64.s */; }; 37 | 9CDEF893232510E000E7D77B /* xt_forwarding_trampoline_x86.s in Sources */ = {isa = PBXBuildFile; fileRef = 9CDEF88A232510E000E7D77B /* xt_forwarding_trampoline_x86.s */; }; 38 | A0967CD0CF6A38CA8B0B8D33 /* Pods_PerformanceMonitor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BD76E55677865B920D13A14 /* Pods_PerformanceMonitor.framework */; }; 39 | /* End PBXBuildFile section */ 40 | 41 | /* Begin PBXContainerItemProxy section */ 42 | 3A4D8BE123111FC300C22EFD /* PBXContainerItemProxy */ = { 43 | isa = PBXContainerItemProxy; 44 | containerPortal = 3A4D8BCD23111FC300C22EFD /* Project object */; 45 | proxyType = 1; 46 | remoteGlobalIDString = 3A4D8BD523111FC300C22EFD; 47 | remoteInfo = PerformanceMonitor; 48 | }; 49 | 9C4A2B56231BCF320066342F /* PBXContainerItemProxy */ = { 50 | isa = PBXContainerItemProxy; 51 | containerPortal = 3A4D8BCD23111FC300C22EFD /* Project object */; 52 | proxyType = 1; 53 | remoteGlobalIDString = 3A4D8BD523111FC300C22EFD; 54 | remoteInfo = PerformanceMonitor; 55 | }; 56 | /* End PBXContainerItemProxy section */ 57 | 58 | /* Begin PBXCopyFilesBuildPhase section */ 59 | 9C4A2B58231BCF320066342F /* Embed Frameworks */ = { 60 | isa = PBXCopyFilesBuildPhase; 61 | buildActionMask = 2147483647; 62 | dstPath = ""; 63 | dstSubfolderSpec = 10; 64 | files = ( 65 | 9C4A2B55231BCF320066342F /* PerformanceMonitor.framework in Embed Frameworks */, 66 | ); 67 | name = "Embed Frameworks"; 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXCopyFilesBuildPhase section */ 71 | 72 | /* Begin PBXFileReference section */ 73 | 259A0830D9C0292A88E9DC94 /* Pods-PerformanceMonitorDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PerformanceMonitorDemo.debug.xcconfig"; path = "Target Support Files/Pods-PerformanceMonitorDemo/Pods-PerformanceMonitorDemo.debug.xcconfig"; sourceTree = ""; }; 74 | 33CDBE8B399B0FD29828E8BB /* Pods_PerformanceMonitorDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PerformanceMonitorDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | 3A4D8BD623111FC300C22EFD /* PerformanceMonitor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PerformanceMonitor.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | 3A4D8BD923111FC300C22EFD /* PerformanceMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PerformanceMonitor.h; sourceTree = ""; }; 77 | 3A4D8BDA23111FC300C22EFD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 78 | 3A4D8BDF23111FC300C22EFD /* PerformanceMonitorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PerformanceMonitorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 79 | 3A4D8BE423111FC300C22EFD /* PerformanceMonitorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceMonitorTests.swift; sourceTree = ""; }; 80 | 3A4D8BE623111FC300C22EFD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 81 | 3A4D8BF02311200E00C22EFD /* PerformanceMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceMonitor.swift; sourceTree = ""; }; 82 | 3A4D8BF22311253900C22EFD /* CPUMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPUMonitor.swift; sourceTree = ""; }; 83 | 3A4D8BF42311254900C22EFD /* MemoryMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryMonitor.swift; sourceTree = ""; }; 84 | 3A4D8C3D231162A200C22EFD /* PerformanceMonitorDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PerformanceMonitorDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 85 | 3A4D8C3F231162A200C22EFD /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 86 | 3A4D8C41231162A200C22EFD /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 87 | 3A4D8C44231162A200C22EFD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 88 | 3A4D8C46231162A300C22EFD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 89 | 3A4D8C49231162A400C22EFD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 90 | 3A4D8C4B231162A400C22EFD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 91 | 3A4D8C55231173C800C22EFD /* FPSMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FPSMonitor.swift; sourceTree = ""; }; 92 | 3A4D8C93231299BE00C22EFD /* FluecyMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FluecyMonitor.swift; sourceTree = ""; }; 93 | 4BD76E55677865B920D13A14 /* Pods_PerformanceMonitor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PerformanceMonitor.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 94 | 8DC3938C78D14B281EEA290C /* Pods-PerformanceMonitorDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PerformanceMonitorDemo.release.xcconfig"; path = "Target Support Files/Pods-PerformanceMonitorDemo/Pods-PerformanceMonitorDemo.release.xcconfig"; sourceTree = ""; }; 95 | 9C1017A32313CAF000158CA4 /* PerformanceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceView.swift; sourceTree = ""; }; 96 | 9C1017A62313DB2700158CA4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97 | 9C1017A82313DCB700158CA4 /* PerformanceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PerformanceViewController.swift; sourceTree = ""; }; 98 | 9C1017AA23140D7B00158CA4 /* FPSTestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FPSTestViewController.swift; sourceTree = ""; }; 99 | 9C1CD2AE2327A7D000B67B84 /* MethodTimeMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MethodTimeMonitor.h; sourceTree = ""; }; 100 | 9C4A2B52231BCF160066342F /* RCBacktrace.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RCBacktrace.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 101 | 9C4A2B59231BCF920066342F /* RCBacktrace.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = RCBacktrace.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 102 | 9CDEF882232510E000E7D77B /* ThreadLocal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThreadLocal.swift; sourceTree = ""; }; 103 | 9CDEF883232510E000E7D77B /* xt_forwarding_trampoline_arm7.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = xt_forwarding_trampoline_arm7.s; sourceTree = ""; }; 104 | 9CDEF884232510E000E7D77B /* MethodTimeMonitor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MethodTimeMonitor.mm; sourceTree = ""; }; 105 | 9CDEF886232510E000E7D77B /* MethodTimeMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MethodTimeMonitor.swift; sourceTree = ""; }; 106 | 9CDEF887232510E000E7D77B /* xt_forwarding_trampoline_x64.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = xt_forwarding_trampoline_x64.s; sourceTree = ""; }; 107 | 9CDEF889232510E000E7D77B /* xt_forwarding_trampoline_arm64.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = xt_forwarding_trampoline_arm64.s; sourceTree = ""; }; 108 | 9CDEF88A232510E000E7D77B /* xt_forwarding_trampoline_x86.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = xt_forwarding_trampoline_x86.s; sourceTree = ""; }; 109 | DF421D5C4F1CD3FDA166A652 /* Pods-PerformanceMonitor.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PerformanceMonitor.debug.xcconfig"; path = "Target Support Files/Pods-PerformanceMonitor/Pods-PerformanceMonitor.debug.xcconfig"; sourceTree = ""; }; 110 | E6B157F54F834692085A3B27 /* Pods-PerformanceMonitor.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PerformanceMonitor.release.xcconfig"; path = "Target Support Files/Pods-PerformanceMonitor/Pods-PerformanceMonitor.release.xcconfig"; sourceTree = ""; }; 111 | /* End PBXFileReference section */ 112 | 113 | /* Begin PBXFrameworksBuildPhase section */ 114 | 3A4D8BD323111FC300C22EFD /* Frameworks */ = { 115 | isa = PBXFrameworksBuildPhase; 116 | buildActionMask = 2147483647; 117 | files = ( 118 | 9C4A2B53231BCF160066342F /* RCBacktrace.framework in Frameworks */, 119 | A0967CD0CF6A38CA8B0B8D33 /* Pods_PerformanceMonitor.framework in Frameworks */, 120 | ); 121 | runOnlyForDeploymentPostprocessing = 0; 122 | }; 123 | 3A4D8BDC23111FC300C22EFD /* Frameworks */ = { 124 | isa = PBXFrameworksBuildPhase; 125 | buildActionMask = 2147483647; 126 | files = ( 127 | 3A4D8BE023111FC300C22EFD /* PerformanceMonitor.framework in Frameworks */, 128 | ); 129 | runOnlyForDeploymentPostprocessing = 0; 130 | }; 131 | 3A4D8C3A231162A200C22EFD /* Frameworks */ = { 132 | isa = PBXFrameworksBuildPhase; 133 | buildActionMask = 2147483647; 134 | files = ( 135 | 45039AE57284072FADDFFD41 /* Pods_PerformanceMonitorDemo.framework in Frameworks */, 136 | ); 137 | runOnlyForDeploymentPostprocessing = 0; 138 | }; 139 | /* End PBXFrameworksBuildPhase section */ 140 | 141 | /* Begin PBXGroup section */ 142 | 2E4AB3BEA38833A435DFEAEC /* Pods */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | DF421D5C4F1CD3FDA166A652 /* Pods-PerformanceMonitor.debug.xcconfig */, 146 | E6B157F54F834692085A3B27 /* Pods-PerformanceMonitor.release.xcconfig */, 147 | 259A0830D9C0292A88E9DC94 /* Pods-PerformanceMonitorDemo.debug.xcconfig */, 148 | 8DC3938C78D14B281EEA290C /* Pods-PerformanceMonitorDemo.release.xcconfig */, 149 | ); 150 | path = Pods; 151 | sourceTree = ""; 152 | }; 153 | 3A4D8BCC23111FC300C22EFD = { 154 | isa = PBXGroup; 155 | children = ( 156 | 3A4D8BD823111FC300C22EFD /* PerformanceMonitor */, 157 | 3A4D8BE323111FC300C22EFD /* PerformanceMonitorTests */, 158 | 3A4D8C3E231162A200C22EFD /* PerformanceMonitorDemo */, 159 | 3A4D8BD723111FC300C22EFD /* Products */, 160 | 2E4AB3BEA38833A435DFEAEC /* Pods */, 161 | EAFD2111C37D5BECD7573720 /* Frameworks */, 162 | ); 163 | sourceTree = ""; 164 | }; 165 | 3A4D8BD723111FC300C22EFD /* Products */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 3A4D8BD623111FC300C22EFD /* PerformanceMonitor.framework */, 169 | 3A4D8BDF23111FC300C22EFD /* PerformanceMonitorTests.xctest */, 170 | 3A4D8C3D231162A200C22EFD /* PerformanceMonitorDemo.app */, 171 | ); 172 | name = Products; 173 | sourceTree = ""; 174 | }; 175 | 3A4D8BD823111FC300C22EFD /* PerformanceMonitor */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | 9CDEF881232510CC00E7D77B /* MethodTimeMonitor */, 179 | 9C1017A52313D95B00158CA4 /* UI */, 180 | 3A4D8C592311806900C22EFD /* Fluecy */, 181 | 3A4D8C52231162FD00C22EFD /* FPS */, 182 | 3A4D8C51231162E100C22EFD /* Memory */, 183 | 3A4D8C50231162D300C22EFD /* CPU */, 184 | 3A4D8BD923111FC300C22EFD /* PerformanceMonitor.h */, 185 | 3A4D8BF02311200E00C22EFD /* PerformanceMonitor.swift */, 186 | 9C1017A62313DB2700158CA4 /* Assets.xcassets */, 187 | 3A4D8BDA23111FC300C22EFD /* Info.plist */, 188 | ); 189 | path = PerformanceMonitor; 190 | sourceTree = ""; 191 | }; 192 | 3A4D8BE323111FC300C22EFD /* PerformanceMonitorTests */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 3A4D8BE423111FC300C22EFD /* PerformanceMonitorTests.swift */, 196 | 3A4D8BE623111FC300C22EFD /* Info.plist */, 197 | ); 198 | path = PerformanceMonitorTests; 199 | sourceTree = ""; 200 | }; 201 | 3A4D8C3E231162A200C22EFD /* PerformanceMonitorDemo */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | 3A4D8C3F231162A200C22EFD /* AppDelegate.swift */, 205 | 3A4D8C41231162A200C22EFD /* ViewController.swift */, 206 | 9C1017AA23140D7B00158CA4 /* FPSTestViewController.swift */, 207 | 3A4D8C43231162A200C22EFD /* Main.storyboard */, 208 | 3A4D8C46231162A300C22EFD /* Assets.xcassets */, 209 | 3A4D8C48231162A400C22EFD /* LaunchScreen.storyboard */, 210 | 3A4D8C4B231162A400C22EFD /* Info.plist */, 211 | ); 212 | path = PerformanceMonitorDemo; 213 | sourceTree = ""; 214 | }; 215 | 3A4D8C50231162D300C22EFD /* CPU */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | 3A4D8BF22311253900C22EFD /* CPUMonitor.swift */, 219 | ); 220 | path = CPU; 221 | sourceTree = ""; 222 | }; 223 | 3A4D8C51231162E100C22EFD /* Memory */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | 3A4D8BF42311254900C22EFD /* MemoryMonitor.swift */, 227 | ); 228 | path = Memory; 229 | sourceTree = ""; 230 | }; 231 | 3A4D8C52231162FD00C22EFD /* FPS */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | 3A4D8C55231173C800C22EFD /* FPSMonitor.swift */, 235 | ); 236 | path = FPS; 237 | sourceTree = ""; 238 | }; 239 | 3A4D8C592311806900C22EFD /* Fluecy */ = { 240 | isa = PBXGroup; 241 | children = ( 242 | 3A4D8C93231299BE00C22EFD /* FluecyMonitor.swift */, 243 | ); 244 | path = Fluecy; 245 | sourceTree = ""; 246 | }; 247 | 9C1017A52313D95B00158CA4 /* UI */ = { 248 | isa = PBXGroup; 249 | children = ( 250 | 9C1017A32313CAF000158CA4 /* PerformanceView.swift */, 251 | 9C1017A82313DCB700158CA4 /* PerformanceViewController.swift */, 252 | ); 253 | path = UI; 254 | sourceTree = ""; 255 | }; 256 | 9CDEF881232510CC00E7D77B /* MethodTimeMonitor */ = { 257 | isa = PBXGroup; 258 | children = ( 259 | 9CDEF884232510E000E7D77B /* MethodTimeMonitor.mm */, 260 | 9C1CD2AE2327A7D000B67B84 /* MethodTimeMonitor.h */, 261 | 9CDEF886232510E000E7D77B /* MethodTimeMonitor.swift */, 262 | 9CDEF882232510E000E7D77B /* ThreadLocal.swift */, 263 | 9CDEF883232510E000E7D77B /* xt_forwarding_trampoline_arm7.s */, 264 | 9CDEF889232510E000E7D77B /* xt_forwarding_trampoline_arm64.s */, 265 | 9CDEF887232510E000E7D77B /* xt_forwarding_trampoline_x64.s */, 266 | 9CDEF88A232510E000E7D77B /* xt_forwarding_trampoline_x86.s */, 267 | ); 268 | path = MethodTimeMonitor; 269 | sourceTree = ""; 270 | }; 271 | EAFD2111C37D5BECD7573720 /* Frameworks */ = { 272 | isa = PBXGroup; 273 | children = ( 274 | 9C4A2B59231BCF920066342F /* RCBacktrace.framework */, 275 | 9C4A2B52231BCF160066342F /* RCBacktrace.framework */, 276 | 4BD76E55677865B920D13A14 /* Pods_PerformanceMonitor.framework */, 277 | 33CDBE8B399B0FD29828E8BB /* Pods_PerformanceMonitorDemo.framework */, 278 | ); 279 | name = Frameworks; 280 | sourceTree = ""; 281 | }; 282 | /* End PBXGroup section */ 283 | 284 | /* Begin PBXHeadersBuildPhase section */ 285 | 3A4D8BD123111FC300C22EFD /* Headers */ = { 286 | isa = PBXHeadersBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | 3A4D8BE723111FC300C22EFD /* PerformanceMonitor.h in Headers */, 290 | 9C1CD2AF2327A7D000B67B84 /* MethodTimeMonitor.h in Headers */, 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | }; 294 | /* End PBXHeadersBuildPhase section */ 295 | 296 | /* Begin PBXNativeTarget section */ 297 | 3A4D8BD523111FC300C22EFD /* PerformanceMonitor */ = { 298 | isa = PBXNativeTarget; 299 | buildConfigurationList = 3A4D8BEA23111FC300C22EFD /* Build configuration list for PBXNativeTarget "PerformanceMonitor" */; 300 | buildPhases = ( 301 | 6D2DB50D7F4AA364A907064D /* [CP] Check Pods Manifest.lock */, 302 | 3A4D8BD123111FC300C22EFD /* Headers */, 303 | 3A4D8BD223111FC300C22EFD /* Sources */, 304 | 3A4D8BD323111FC300C22EFD /* Frameworks */, 305 | 3A4D8BD423111FC300C22EFD /* Resources */, 306 | ); 307 | buildRules = ( 308 | ); 309 | dependencies = ( 310 | ); 311 | name = PerformanceMonitor; 312 | productName = PerformanceMonitor; 313 | productReference = 3A4D8BD623111FC300C22EFD /* PerformanceMonitor.framework */; 314 | productType = "com.apple.product-type.framework"; 315 | }; 316 | 3A4D8BDE23111FC300C22EFD /* PerformanceMonitorTests */ = { 317 | isa = PBXNativeTarget; 318 | buildConfigurationList = 3A4D8BED23111FC300C22EFD /* Build configuration list for PBXNativeTarget "PerformanceMonitorTests" */; 319 | buildPhases = ( 320 | 3A4D8BDB23111FC300C22EFD /* Sources */, 321 | 3A4D8BDC23111FC300C22EFD /* Frameworks */, 322 | 3A4D8BDD23111FC300C22EFD /* Resources */, 323 | ); 324 | buildRules = ( 325 | ); 326 | dependencies = ( 327 | 3A4D8BE223111FC300C22EFD /* PBXTargetDependency */, 328 | ); 329 | name = PerformanceMonitorTests; 330 | productName = PerformanceMonitorTests; 331 | productReference = 3A4D8BDF23111FC300C22EFD /* PerformanceMonitorTests.xctest */; 332 | productType = "com.apple.product-type.bundle.unit-test"; 333 | }; 334 | 3A4D8C3C231162A200C22EFD /* PerformanceMonitorDemo */ = { 335 | isa = PBXNativeTarget; 336 | buildConfigurationList = 3A4D8C4C231162A400C22EFD /* Build configuration list for PBXNativeTarget "PerformanceMonitorDemo" */; 337 | buildPhases = ( 338 | 9AFABB94AB8E7F5B2899BCD2 /* [CP] Check Pods Manifest.lock */, 339 | 3A4D8C39231162A200C22EFD /* Sources */, 340 | 3A4D8C3A231162A200C22EFD /* Frameworks */, 341 | 3A4D8C3B231162A200C22EFD /* Resources */, 342 | 9C4A2B58231BCF320066342F /* Embed Frameworks */, 343 | 05DA090563DB4ED1A6B354E8 /* [CP] Embed Pods Frameworks */, 344 | ); 345 | buildRules = ( 346 | ); 347 | dependencies = ( 348 | 9C4A2B57231BCF320066342F /* PBXTargetDependency */, 349 | ); 350 | name = PerformanceMonitorDemo; 351 | productName = PerformanceMonitorDemo; 352 | productReference = 3A4D8C3D231162A200C22EFD /* PerformanceMonitorDemo.app */; 353 | productType = "com.apple.product-type.application"; 354 | }; 355 | /* End PBXNativeTarget section */ 356 | 357 | /* Begin PBXProject section */ 358 | 3A4D8BCD23111FC300C22EFD /* Project object */ = { 359 | isa = PBXProject; 360 | attributes = { 361 | LastSwiftUpdateCheck = 1030; 362 | LastUpgradeCheck = 1030; 363 | ORGANIZATIONNAME = roy; 364 | TargetAttributes = { 365 | 3A4D8BD523111FC300C22EFD = { 366 | CreatedOnToolsVersion = 10.3; 367 | LastSwiftMigration = 1020; 368 | }; 369 | 3A4D8BDE23111FC300C22EFD = { 370 | CreatedOnToolsVersion = 10.3; 371 | }; 372 | 3A4D8C3C231162A200C22EFD = { 373 | CreatedOnToolsVersion = 10.3; 374 | }; 375 | }; 376 | }; 377 | buildConfigurationList = 3A4D8BD023111FC300C22EFD /* Build configuration list for PBXProject "PerformanceMonitor" */; 378 | compatibilityVersion = "Xcode 9.3"; 379 | developmentRegion = en; 380 | hasScannedForEncodings = 0; 381 | knownRegions = ( 382 | en, 383 | Base, 384 | ); 385 | mainGroup = 3A4D8BCC23111FC300C22EFD; 386 | productRefGroup = 3A4D8BD723111FC300C22EFD /* Products */; 387 | projectDirPath = ""; 388 | projectRoot = ""; 389 | targets = ( 390 | 3A4D8BD523111FC300C22EFD /* PerformanceMonitor */, 391 | 3A4D8BDE23111FC300C22EFD /* PerformanceMonitorTests */, 392 | 3A4D8C3C231162A200C22EFD /* PerformanceMonitorDemo */, 393 | ); 394 | }; 395 | /* End PBXProject section */ 396 | 397 | /* Begin PBXResourcesBuildPhase section */ 398 | 3A4D8BD423111FC300C22EFD /* Resources */ = { 399 | isa = PBXResourcesBuildPhase; 400 | buildActionMask = 2147483647; 401 | files = ( 402 | 9C1017A72313DB2700158CA4 /* Assets.xcassets in Resources */, 403 | ); 404 | runOnlyForDeploymentPostprocessing = 0; 405 | }; 406 | 3A4D8BDD23111FC300C22EFD /* Resources */ = { 407 | isa = PBXResourcesBuildPhase; 408 | buildActionMask = 2147483647; 409 | files = ( 410 | ); 411 | runOnlyForDeploymentPostprocessing = 0; 412 | }; 413 | 3A4D8C3B231162A200C22EFD /* Resources */ = { 414 | isa = PBXResourcesBuildPhase; 415 | buildActionMask = 2147483647; 416 | files = ( 417 | 3A4D8C4A231162A400C22EFD /* LaunchScreen.storyboard in Resources */, 418 | 3A4D8C47231162A400C22EFD /* Assets.xcassets in Resources */, 419 | 3A4D8C45231162A200C22EFD /* Main.storyboard in Resources */, 420 | ); 421 | runOnlyForDeploymentPostprocessing = 0; 422 | }; 423 | /* End PBXResourcesBuildPhase section */ 424 | 425 | /* Begin PBXShellScriptBuildPhase section */ 426 | 05DA090563DB4ED1A6B354E8 /* [CP] Embed Pods Frameworks */ = { 427 | isa = PBXShellScriptBuildPhase; 428 | buildActionMask = 2147483647; 429 | files = ( 430 | ); 431 | inputFileListPaths = ( 432 | "${PODS_ROOT}/Target Support Files/Pods-PerformanceMonitorDemo/Pods-PerformanceMonitorDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist", 433 | ); 434 | name = "[CP] Embed Pods Frameworks"; 435 | outputFileListPaths = ( 436 | "${PODS_ROOT}/Target Support Files/Pods-PerformanceMonitorDemo/Pods-PerformanceMonitorDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist", 437 | ); 438 | runOnlyForDeploymentPostprocessing = 0; 439 | shellPath = /bin/sh; 440 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PerformanceMonitorDemo/Pods-PerformanceMonitorDemo-frameworks.sh\"\n"; 441 | showEnvVarsInLog = 0; 442 | }; 443 | 6D2DB50D7F4AA364A907064D /* [CP] Check Pods Manifest.lock */ = { 444 | isa = PBXShellScriptBuildPhase; 445 | buildActionMask = 2147483647; 446 | files = ( 447 | ); 448 | inputFileListPaths = ( 449 | ); 450 | inputPaths = ( 451 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 452 | "${PODS_ROOT}/Manifest.lock", 453 | ); 454 | name = "[CP] Check Pods Manifest.lock"; 455 | outputFileListPaths = ( 456 | ); 457 | outputPaths = ( 458 | "$(DERIVED_FILE_DIR)/Pods-PerformanceMonitor-checkManifestLockResult.txt", 459 | ); 460 | runOnlyForDeploymentPostprocessing = 0; 461 | shellPath = /bin/sh; 462 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 463 | showEnvVarsInLog = 0; 464 | }; 465 | 9AFABB94AB8E7F5B2899BCD2 /* [CP] Check Pods Manifest.lock */ = { 466 | isa = PBXShellScriptBuildPhase; 467 | buildActionMask = 2147483647; 468 | files = ( 469 | ); 470 | inputFileListPaths = ( 471 | ); 472 | inputPaths = ( 473 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 474 | "${PODS_ROOT}/Manifest.lock", 475 | ); 476 | name = "[CP] Check Pods Manifest.lock"; 477 | outputFileListPaths = ( 478 | ); 479 | outputPaths = ( 480 | "$(DERIVED_FILE_DIR)/Pods-PerformanceMonitorDemo-checkManifestLockResult.txt", 481 | ); 482 | runOnlyForDeploymentPostprocessing = 0; 483 | shellPath = /bin/sh; 484 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 485 | showEnvVarsInLog = 0; 486 | }; 487 | /* End PBXShellScriptBuildPhase section */ 488 | 489 | /* Begin PBXSourcesBuildPhase section */ 490 | 3A4D8BD223111FC300C22EFD /* Sources */ = { 491 | isa = PBXSourcesBuildPhase; 492 | buildActionMask = 2147483647; 493 | files = ( 494 | 9CDEF88C232510E000E7D77B /* xt_forwarding_trampoline_arm7.s in Sources */, 495 | 9C1017A92313DCB700158CA4 /* PerformanceViewController.swift in Sources */, 496 | 9CDEF890232510E000E7D77B /* xt_forwarding_trampoline_x64.s in Sources */, 497 | 3A4D8BF12311200E00C22EFD /* PerformanceMonitor.swift in Sources */, 498 | 3A4D8BF52311254900C22EFD /* MemoryMonitor.swift in Sources */, 499 | 3A4D8C94231299BE00C22EFD /* FluecyMonitor.swift in Sources */, 500 | 3A4D8BF32311253900C22EFD /* CPUMonitor.swift in Sources */, 501 | 9CDEF88F232510E000E7D77B /* MethodTimeMonitor.swift in Sources */, 502 | 9C1017A42313CAF000158CA4 /* PerformanceView.swift in Sources */, 503 | 3A4D8C56231173C800C22EFD /* FPSMonitor.swift in Sources */, 504 | 9CDEF893232510E000E7D77B /* xt_forwarding_trampoline_x86.s in Sources */, 505 | 9CDEF88B232510E000E7D77B /* ThreadLocal.swift in Sources */, 506 | 9CDEF88D232510E000E7D77B /* MethodTimeMonitor.mm in Sources */, 507 | 9CDEF892232510E000E7D77B /* xt_forwarding_trampoline_arm64.s in Sources */, 508 | ); 509 | runOnlyForDeploymentPostprocessing = 0; 510 | }; 511 | 3A4D8BDB23111FC300C22EFD /* Sources */ = { 512 | isa = PBXSourcesBuildPhase; 513 | buildActionMask = 2147483647; 514 | files = ( 515 | 3A4D8BE523111FC300C22EFD /* PerformanceMonitorTests.swift in Sources */, 516 | ); 517 | runOnlyForDeploymentPostprocessing = 0; 518 | }; 519 | 3A4D8C39231162A200C22EFD /* Sources */ = { 520 | isa = PBXSourcesBuildPhase; 521 | buildActionMask = 2147483647; 522 | files = ( 523 | 3A4D8C42231162A200C22EFD /* ViewController.swift in Sources */, 524 | 9C1017AB23140D7B00158CA4 /* FPSTestViewController.swift in Sources */, 525 | 3A4D8C40231162A200C22EFD /* AppDelegate.swift in Sources */, 526 | ); 527 | runOnlyForDeploymentPostprocessing = 0; 528 | }; 529 | /* End PBXSourcesBuildPhase section */ 530 | 531 | /* Begin PBXTargetDependency section */ 532 | 3A4D8BE223111FC300C22EFD /* PBXTargetDependency */ = { 533 | isa = PBXTargetDependency; 534 | target = 3A4D8BD523111FC300C22EFD /* PerformanceMonitor */; 535 | targetProxy = 3A4D8BE123111FC300C22EFD /* PBXContainerItemProxy */; 536 | }; 537 | 9C4A2B57231BCF320066342F /* PBXTargetDependency */ = { 538 | isa = PBXTargetDependency; 539 | target = 3A4D8BD523111FC300C22EFD /* PerformanceMonitor */; 540 | targetProxy = 9C4A2B56231BCF320066342F /* PBXContainerItemProxy */; 541 | }; 542 | /* End PBXTargetDependency section */ 543 | 544 | /* Begin PBXVariantGroup section */ 545 | 3A4D8C43231162A200C22EFD /* Main.storyboard */ = { 546 | isa = PBXVariantGroup; 547 | children = ( 548 | 3A4D8C44231162A200C22EFD /* Base */, 549 | ); 550 | name = Main.storyboard; 551 | sourceTree = ""; 552 | }; 553 | 3A4D8C48231162A400C22EFD /* LaunchScreen.storyboard */ = { 554 | isa = PBXVariantGroup; 555 | children = ( 556 | 3A4D8C49231162A400C22EFD /* Base */, 557 | ); 558 | name = LaunchScreen.storyboard; 559 | sourceTree = ""; 560 | }; 561 | /* End PBXVariantGroup section */ 562 | 563 | /* Begin XCBuildConfiguration section */ 564 | 3A4D8BE823111FC300C22EFD /* Debug */ = { 565 | isa = XCBuildConfiguration; 566 | buildSettings = { 567 | ALWAYS_SEARCH_USER_PATHS = NO; 568 | CLANG_ANALYZER_NONNULL = YES; 569 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 570 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 571 | CLANG_CXX_LIBRARY = "libc++"; 572 | CLANG_ENABLE_MODULES = YES; 573 | CLANG_ENABLE_OBJC_ARC = YES; 574 | CLANG_ENABLE_OBJC_WEAK = YES; 575 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 576 | CLANG_WARN_BOOL_CONVERSION = YES; 577 | CLANG_WARN_COMMA = YES; 578 | CLANG_WARN_CONSTANT_CONVERSION = YES; 579 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 580 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 581 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 582 | CLANG_WARN_EMPTY_BODY = YES; 583 | CLANG_WARN_ENUM_CONVERSION = YES; 584 | CLANG_WARN_INFINITE_RECURSION = YES; 585 | CLANG_WARN_INT_CONVERSION = YES; 586 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 587 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 588 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 589 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 590 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 591 | CLANG_WARN_STRICT_PROTOTYPES = YES; 592 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 593 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 594 | CLANG_WARN_UNREACHABLE_CODE = YES; 595 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 596 | CODE_SIGN_IDENTITY = "iPhone Developer"; 597 | COPY_PHASE_STRIP = NO; 598 | CURRENT_PROJECT_VERSION = 1; 599 | DEBUG_INFORMATION_FORMAT = dwarf; 600 | DEFINES_MODULE = NO; 601 | ENABLE_STRICT_OBJC_MSGSEND = YES; 602 | ENABLE_TESTABILITY = YES; 603 | GCC_C_LANGUAGE_STANDARD = gnu11; 604 | GCC_DYNAMIC_NO_PIC = NO; 605 | GCC_NO_COMMON_BLOCKS = YES; 606 | GCC_OPTIMIZATION_LEVEL = 0; 607 | GCC_PREPROCESSOR_DEFINITIONS = ( 608 | "DEBUG=1", 609 | "$(inherited)", 610 | ); 611 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 612 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 613 | GCC_WARN_UNDECLARED_SELECTOR = YES; 614 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 615 | GCC_WARN_UNUSED_FUNCTION = YES; 616 | GCC_WARN_UNUSED_VARIABLE = YES; 617 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 618 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 619 | MTL_FAST_MATH = YES; 620 | ONLY_ACTIVE_ARCH = YES; 621 | SDKROOT = iphoneos; 622 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 623 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 624 | VERSIONING_SYSTEM = "apple-generic"; 625 | VERSION_INFO_PREFIX = ""; 626 | }; 627 | name = Debug; 628 | }; 629 | 3A4D8BE923111FC300C22EFD /* Release */ = { 630 | isa = XCBuildConfiguration; 631 | buildSettings = { 632 | ALWAYS_SEARCH_USER_PATHS = NO; 633 | CLANG_ANALYZER_NONNULL = YES; 634 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 635 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 636 | CLANG_CXX_LIBRARY = "libc++"; 637 | CLANG_ENABLE_MODULES = YES; 638 | CLANG_ENABLE_OBJC_ARC = YES; 639 | CLANG_ENABLE_OBJC_WEAK = YES; 640 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 641 | CLANG_WARN_BOOL_CONVERSION = YES; 642 | CLANG_WARN_COMMA = YES; 643 | CLANG_WARN_CONSTANT_CONVERSION = YES; 644 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 645 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 646 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 647 | CLANG_WARN_EMPTY_BODY = YES; 648 | CLANG_WARN_ENUM_CONVERSION = YES; 649 | CLANG_WARN_INFINITE_RECURSION = YES; 650 | CLANG_WARN_INT_CONVERSION = YES; 651 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 652 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 653 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 654 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 655 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 656 | CLANG_WARN_STRICT_PROTOTYPES = YES; 657 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 658 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 659 | CLANG_WARN_UNREACHABLE_CODE = YES; 660 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 661 | CODE_SIGN_IDENTITY = "iPhone Developer"; 662 | COPY_PHASE_STRIP = NO; 663 | CURRENT_PROJECT_VERSION = 1; 664 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 665 | DEFINES_MODULE = NO; 666 | ENABLE_NS_ASSERTIONS = NO; 667 | ENABLE_STRICT_OBJC_MSGSEND = YES; 668 | GCC_C_LANGUAGE_STANDARD = gnu11; 669 | GCC_NO_COMMON_BLOCKS = YES; 670 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 671 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 672 | GCC_WARN_UNDECLARED_SELECTOR = YES; 673 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 674 | GCC_WARN_UNUSED_FUNCTION = YES; 675 | GCC_WARN_UNUSED_VARIABLE = YES; 676 | IPHONEOS_DEPLOYMENT_TARGET = 12.4; 677 | MTL_ENABLE_DEBUG_INFO = NO; 678 | MTL_FAST_MATH = YES; 679 | SDKROOT = iphoneos; 680 | SWIFT_COMPILATION_MODE = wholemodule; 681 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 682 | VALIDATE_PRODUCT = YES; 683 | VERSIONING_SYSTEM = "apple-generic"; 684 | VERSION_INFO_PREFIX = ""; 685 | }; 686 | name = Release; 687 | }; 688 | 3A4D8BEB23111FC300C22EFD /* Debug */ = { 689 | isa = XCBuildConfiguration; 690 | baseConfigurationReference = DF421D5C4F1CD3FDA166A652 /* Pods-PerformanceMonitor.debug.xcconfig */; 691 | buildSettings = { 692 | CLANG_ENABLE_MODULES = YES; 693 | CODE_SIGN_IDENTITY = ""; 694 | CODE_SIGN_STYLE = Automatic; 695 | DEFINES_MODULE = YES; 696 | DEVELOPMENT_TEAM = Y7BCF82NHQ; 697 | DYLIB_COMPATIBILITY_VERSION = 1; 698 | DYLIB_CURRENT_VERSION = 1; 699 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 700 | ENABLE_ON_DEMAND_RESOURCES = NO; 701 | INFOPLIST_FILE = PerformanceMonitor/Info.plist; 702 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 703 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 704 | LD_RUNPATH_SEARCH_PATHS = ( 705 | "$(inherited)", 706 | "@executable_path/Frameworks", 707 | "@loader_path/Frameworks", 708 | ); 709 | PRODUCT_BUNDLE_IDENTIFIER = roy.cao.PerformanceMonitor; 710 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 711 | SKIP_INSTALL = YES; 712 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 713 | SWIFT_VERSION = 5.0; 714 | TARGETED_DEVICE_FAMILY = "1,2"; 715 | }; 716 | name = Debug; 717 | }; 718 | 3A4D8BEC23111FC300C22EFD /* Release */ = { 719 | isa = XCBuildConfiguration; 720 | baseConfigurationReference = E6B157F54F834692085A3B27 /* Pods-PerformanceMonitor.release.xcconfig */; 721 | buildSettings = { 722 | CLANG_ENABLE_MODULES = YES; 723 | CODE_SIGN_IDENTITY = ""; 724 | CODE_SIGN_STYLE = Automatic; 725 | DEFINES_MODULE = YES; 726 | DEVELOPMENT_TEAM = Y7BCF82NHQ; 727 | DYLIB_COMPATIBILITY_VERSION = 1; 728 | DYLIB_CURRENT_VERSION = 1; 729 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 730 | ENABLE_ON_DEMAND_RESOURCES = NO; 731 | INFOPLIST_FILE = PerformanceMonitor/Info.plist; 732 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 733 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 734 | LD_RUNPATH_SEARCH_PATHS = ( 735 | "$(inherited)", 736 | "@executable_path/Frameworks", 737 | "@loader_path/Frameworks", 738 | ); 739 | PRODUCT_BUNDLE_IDENTIFIER = roy.cao.PerformanceMonitor; 740 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 741 | SKIP_INSTALL = YES; 742 | SWIFT_VERSION = 5.0; 743 | TARGETED_DEVICE_FAMILY = "1,2"; 744 | }; 745 | name = Release; 746 | }; 747 | 3A4D8BEE23111FC300C22EFD /* Debug */ = { 748 | isa = XCBuildConfiguration; 749 | buildSettings = { 750 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 751 | CODE_SIGN_STYLE = Automatic; 752 | DEFINES_MODULE = NO; 753 | INFOPLIST_FILE = PerformanceMonitorTests/Info.plist; 754 | LD_RUNPATH_SEARCH_PATHS = ( 755 | "$(inherited)", 756 | "@executable_path/Frameworks", 757 | "@loader_path/Frameworks", 758 | ); 759 | PRODUCT_BUNDLE_IDENTIFIER = roy.cao.PerformanceMonitorTests; 760 | PRODUCT_NAME = "$(TARGET_NAME)"; 761 | SWIFT_VERSION = 5.0; 762 | TARGETED_DEVICE_FAMILY = "1,2"; 763 | }; 764 | name = Debug; 765 | }; 766 | 3A4D8BEF23111FC300C22EFD /* Release */ = { 767 | isa = XCBuildConfiguration; 768 | buildSettings = { 769 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 770 | CODE_SIGN_STYLE = Automatic; 771 | DEFINES_MODULE = NO; 772 | INFOPLIST_FILE = PerformanceMonitorTests/Info.plist; 773 | LD_RUNPATH_SEARCH_PATHS = ( 774 | "$(inherited)", 775 | "@executable_path/Frameworks", 776 | "@loader_path/Frameworks", 777 | ); 778 | PRODUCT_BUNDLE_IDENTIFIER = roy.cao.PerformanceMonitorTests; 779 | PRODUCT_NAME = "$(TARGET_NAME)"; 780 | SWIFT_VERSION = 5.0; 781 | TARGETED_DEVICE_FAMILY = "1,2"; 782 | }; 783 | name = Release; 784 | }; 785 | 3A4D8C4D231162A400C22EFD /* Debug */ = { 786 | isa = XCBuildConfiguration; 787 | baseConfigurationReference = 259A0830D9C0292A88E9DC94 /* Pods-PerformanceMonitorDemo.debug.xcconfig */; 788 | buildSettings = { 789 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 790 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 791 | CODE_SIGN_STYLE = Automatic; 792 | DEVELOPMENT_TEAM = Y7BCF82NHQ; 793 | INFOPLIST_FILE = PerformanceMonitorDemo/Info.plist; 794 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 795 | LD_RUNPATH_SEARCH_PATHS = ( 796 | "$(inherited)", 797 | "@executable_path/Frameworks", 798 | ); 799 | PRODUCT_BUNDLE_IDENTIFIER = roy.cao.PerformanceMonitorDemo; 800 | PRODUCT_NAME = "$(TARGET_NAME)"; 801 | SWIFT_VERSION = 5.0; 802 | TARGETED_DEVICE_FAMILY = "1,2"; 803 | }; 804 | name = Debug; 805 | }; 806 | 3A4D8C4E231162A400C22EFD /* Release */ = { 807 | isa = XCBuildConfiguration; 808 | baseConfigurationReference = 8DC3938C78D14B281EEA290C /* Pods-PerformanceMonitorDemo.release.xcconfig */; 809 | buildSettings = { 810 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 811 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 812 | CODE_SIGN_STYLE = Automatic; 813 | DEVELOPMENT_TEAM = Y7BCF82NHQ; 814 | INFOPLIST_FILE = PerformanceMonitorDemo/Info.plist; 815 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 816 | LD_RUNPATH_SEARCH_PATHS = ( 817 | "$(inherited)", 818 | "@executable_path/Frameworks", 819 | ); 820 | PRODUCT_BUNDLE_IDENTIFIER = roy.cao.PerformanceMonitorDemo; 821 | PRODUCT_NAME = "$(TARGET_NAME)"; 822 | SWIFT_VERSION = 5.0; 823 | TARGETED_DEVICE_FAMILY = "1,2"; 824 | }; 825 | name = Release; 826 | }; 827 | /* End XCBuildConfiguration section */ 828 | 829 | /* Begin XCConfigurationList section */ 830 | 3A4D8BD023111FC300C22EFD /* Build configuration list for PBXProject "PerformanceMonitor" */ = { 831 | isa = XCConfigurationList; 832 | buildConfigurations = ( 833 | 3A4D8BE823111FC300C22EFD /* Debug */, 834 | 3A4D8BE923111FC300C22EFD /* Release */, 835 | ); 836 | defaultConfigurationIsVisible = 0; 837 | defaultConfigurationName = Release; 838 | }; 839 | 3A4D8BEA23111FC300C22EFD /* Build configuration list for PBXNativeTarget "PerformanceMonitor" */ = { 840 | isa = XCConfigurationList; 841 | buildConfigurations = ( 842 | 3A4D8BEB23111FC300C22EFD /* Debug */, 843 | 3A4D8BEC23111FC300C22EFD /* Release */, 844 | ); 845 | defaultConfigurationIsVisible = 0; 846 | defaultConfigurationName = Release; 847 | }; 848 | 3A4D8BED23111FC300C22EFD /* Build configuration list for PBXNativeTarget "PerformanceMonitorTests" */ = { 849 | isa = XCConfigurationList; 850 | buildConfigurations = ( 851 | 3A4D8BEE23111FC300C22EFD /* Debug */, 852 | 3A4D8BEF23111FC300C22EFD /* Release */, 853 | ); 854 | defaultConfigurationIsVisible = 0; 855 | defaultConfigurationName = Release; 856 | }; 857 | 3A4D8C4C231162A400C22EFD /* Build configuration list for PBXNativeTarget "PerformanceMonitorDemo" */ = { 858 | isa = XCConfigurationList; 859 | buildConfigurations = ( 860 | 3A4D8C4D231162A400C22EFD /* Debug */, 861 | 3A4D8C4E231162A400C22EFD /* Release */, 862 | ); 863 | defaultConfigurationIsVisible = 0; 864 | defaultConfigurationName = Release; 865 | }; 866 | /* End XCConfigurationList section */ 867 | }; 868 | rootObject = 3A4D8BCD23111FC300C22EFD /* Project object */; 869 | } 870 | -------------------------------------------------------------------------------- /PerformanceMonitor.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PerformanceMonitor.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PerformanceMonitor.xcodeproj/project.xcworkspace/xcuserdata/ming.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /PerformanceMonitor.xcodeproj/project.xcworkspace/xcuserdata/ming.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woshiccm/PerformanceMonitor/b40745906068295ecee0b47215a94fe3c550ce76/PerformanceMonitor.xcodeproj/project.xcworkspace/xcuserdata/ming.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PerformanceMonitor.xcodeproj/project.xcworkspace/xcuserdata/roy.cao.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woshiccm/PerformanceMonitor/b40745906068295ecee0b47215a94fe3c550ce76/PerformanceMonitor.xcodeproj/project.xcworkspace/xcuserdata/roy.cao.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PerformanceMonitor.xcodeproj/xcuserdata/roy.cao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /PerformanceMonitor.xcodeproj/xcuserdata/roy.cao.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PerformanceMonitor.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 3 11 | 12 | PerformanceMonitorDemo.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 4 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /PerformanceMonitor.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PerformanceMonitor/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PerformanceMonitor/CPU/CPUMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CPUMonitor.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/8/24. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | private let HOST_CPU_LOAD_INFO_COUNT: natural_t = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size) 12 | 13 | public class CPUMonitor { 14 | 15 | public struct HostCPULoadInfo { 16 | public let user: Double 17 | public let system: Double 18 | public let idle: Double 19 | public let nice: Double 20 | 21 | /// 1、CPU_STATE_USER 22 | /// 2、CPU_STATE_SYSTEM 23 | /// 3、CPU_STATE_IDLE 24 | /// 4、CPU_STATE_NICE 25 | init(cpuLoadInfo: host_cpu_load_info) { 26 | user = Double(cpuLoadInfo.cpu_ticks.0) 27 | system = Double(cpuLoadInfo.cpu_ticks.1) 28 | idle = Double(cpuLoadInfo.cpu_ticks.2) 29 | nice = Double(cpuLoadInfo.cpu_ticks.3) 30 | } 31 | } 32 | 33 | // Current CPU usage for your Applicaiton 34 | public static func usage() -> Double { 35 | var usageOfCPU: Double = 0.0 36 | var threads = UnsafeMutablePointer(mutating: [thread_act_t]()) 37 | var count = mach_msg_type_number_t(0) 38 | 39 | defer { 40 | vm_deallocate(mach_task_self_, vm_address_t(UInt(bitPattern: threads)), vm_size_t(Int(count) * MemoryLayout.stride)) 41 | } 42 | 43 | let kerr = withUnsafeMutablePointer(to: &threads) { 44 | $0.withMemoryRebound(to: thread_act_array_t?.self, capacity: 1) { 45 | task_threads(mach_task_self_, $0, &count) 46 | } 47 | } 48 | 49 | guard kerr == KERN_SUCCESS else { return usageOfCPU } 50 | 51 | for index in 0.. HostCPULoadInfo? { 75 | var size = HOST_CPU_LOAD_INFO_COUNT 76 | var cpuLoadInfo = host_cpu_load_info() 77 | 78 | let kerr = withUnsafeMutablePointer(to: &cpuLoadInfo) { 79 | $0.withMemoryRebound(to: integer_t.self, capacity: Int(HOST_CPU_LOAD_INFO_COUNT)) { 80 | host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, $0, &size) 81 | } 82 | } 83 | 84 | if kerr != KERN_SUCCESS { 85 | #if DEBUG 86 | let errorString = String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error" 87 | print("Collecting host cpu load info failed: \(errorString)") 88 | #endif 89 | return nil 90 | } 91 | 92 | return HostCPULoadInfo(cpuLoadInfo: cpuLoadInfo) 93 | } 94 | 95 | // Current CPU total usage, CPU_STATE_USER + CPU_STATE_SYSTEM + CPU_STATE_NICE 96 | public static func totalUsage() -> Double { 97 | guard let hostCPULoadInfo = hostCPULoadInfo() else { 98 | return 0 99 | } 100 | 101 | let totalTicks = hostCPULoadInfo.user + hostCPULoadInfo.system + hostCPULoadInfo.idle + hostCPULoadInfo.nice 102 | 103 | return (hostCPULoadInfo.user + hostCPULoadInfo.system + hostCPULoadInfo.nice) / totalTicks * 100 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /PerformanceMonitor/FPS/FPSMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FPSHelper.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/8/24. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @objc public protocol FPSMonitorDelegate: class { 12 | 13 | func fpsMonitor(with monitor: FPSMonitor, fps: Double) 14 | } 15 | 16 | public class FPSMonitor: NSObject { 17 | 18 | class WeakProxy { 19 | weak var target: FPSMonitor? 20 | 21 | init(target: FPSMonitor) { 22 | self.target = target 23 | } 24 | 25 | @objc func tick(link: CADisplayLink) { 26 | target?.tick(link: link) 27 | } 28 | } 29 | 30 | enum Constants { 31 | static let timeInterval: TimeInterval = 1.0 32 | } 33 | 34 | public weak var delegate: FPSMonitorDelegate? 35 | 36 | private var link: CADisplayLink? 37 | private var count: Int = 0 38 | private var lastTime: TimeInterval = 0.0 39 | 40 | public override init() { 41 | super.init() 42 | 43 | link = CADisplayLink(target: WeakProxy.init(target: self), selector: #selector(WeakProxy.tick(link:))) 44 | link?.isPaused = true 45 | link?.add(to: RunLoop.main, forMode: .common) 46 | setupObservers() 47 | } 48 | 49 | public func start() { 50 | link?.isPaused = false 51 | } 52 | 53 | public func stop() { 54 | link?.isPaused = true 55 | } 56 | 57 | func setupObservers() { 58 | NotificationCenter.default.addObserver(self, 59 | selector: #selector(applicationWillResignActiveNotification), 60 | name: UIApplication.willResignActiveNotification, 61 | object: nil) 62 | 63 | NotificationCenter.default.addObserver(self, 64 | selector: #selector(applicationDidBecomeActiveNotification), 65 | name: UIApplication.didBecomeActiveNotification, 66 | object: nil) 67 | } 68 | 69 | deinit { 70 | link?.invalidate() 71 | NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil) 72 | NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil) 73 | } 74 | 75 | func tick(link: CADisplayLink) { 76 | count += 1 77 | let timePassed = link.timestamp - self.lastTime 78 | 79 | guard timePassed >= Constants.timeInterval else { 80 | return 81 | } 82 | 83 | self.lastTime = link.timestamp 84 | let fps = Double(self.count) / timePassed 85 | self.count = 0 86 | 87 | self.delegate?.fpsMonitor(with: self, fps: fps) 88 | } 89 | } 90 | 91 | private extension FPSMonitor { 92 | 93 | @objc func applicationWillResignActiveNotification() { 94 | stop() 95 | } 96 | 97 | @objc func applicationDidBecomeActiveNotification() { 98 | start() 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /PerformanceMonitor/Fluecy/FluecyMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FluecyMonitor.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/8/25. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import RCBacktrace 11 | 12 | public class FluecyMonitor { 13 | 14 | enum Constants { 15 | static let timeOutInterval: TimeInterval = 0.05 16 | static let queueTitle = "com.roy.PerformanceMonitor.CatonMonitor" 17 | } 18 | 19 | private var queue: DispatchQueue = DispatchQueue(label: Constants.queueTitle) 20 | private var isMonitoring = false 21 | private var semaphore: DispatchSemaphore = DispatchSemaphore(value: 0) 22 | 23 | public init() {} 24 | 25 | public func start() { 26 | guard !isMonitoring else { return } 27 | 28 | isMonitoring = true 29 | queue.async { 30 | while self.isMonitoring { 31 | 32 | var timeout = true 33 | 34 | DispatchQueue.main.async { 35 | timeout = false 36 | self.semaphore.signal() 37 | } 38 | 39 | Thread.sleep(forTimeInterval: Constants.timeOutInterval) 40 | 41 | if timeout { 42 | DispatchQueue.main.async { 43 | let symbols = RCBacktrace.callstack(.main) 44 | print("👁 Not fluecy ------------------------------------------------------------") 45 | for symbol in symbols { 46 | print(symbol.description) 47 | } 48 | print("👁 Not fluecy -------------------------------------------------------------") 49 | } 50 | } 51 | self.semaphore.wait() 52 | } 53 | } 54 | } 55 | 56 | public func stop() { 57 | guard isMonitoring else { return } 58 | 59 | isMonitoring = false 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /PerformanceMonitor/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /PerformanceMonitor/Memory/MemoryMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MemoryMonitor.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/8/24. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Memory state 12 | public typealias MemoryState = (freeBytes: Double, activeBytes: Double, inactiveBytes: Double, wiredBytes: Double, compressedBytes: Double, totalBytes: Double) 13 | 14 | public class MemoryMonitor { 15 | 16 | enum Constants { 17 | static let MB: Double = 1024 * 1024 18 | } 19 | 20 | public static let totalBytes: Double = Double(ProcessInfo.processInfo.physicalMemory) 21 | 22 | /// Current memory usage for your Applicaiton, equal Xcode Debug Gauge 23 | /// resident_size does not get accurate memory, and the correct way is to use phys_footprint, which can be proved from the source codes of WebKit and XNU. 24 | /// https://github.com/WebKit/webkit/blob/master/Source/WTF/wtf/cocoa/MemoryFootprintCocoa.cpp 25 | public static func usage() -> Double { 26 | var taskInfo = task_vm_info_data_t() 27 | var count = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size) 28 | let result: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) { 29 | $0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { 30 | task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), $0, &count) 31 | } 32 | } 33 | 34 | var used: Double = 0 35 | if result == KERN_SUCCESS { 36 | used = Double(taskInfo.phys_footprint) 37 | } 38 | 39 | return used / Constants.MB 40 | } 41 | 42 | /// Current memory usage for your device, not equal Xcode Debug Gauge 43 | public static func deviceUsage() -> Double { 44 | var taskInfo = mach_task_basic_info() 45 | var count = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size) 46 | let kerr: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) { 47 | $0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { 48 | task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count) 49 | } 50 | } 51 | 52 | var used: Double = 0 53 | if kerr == KERN_SUCCESS { 54 | used = Double(taskInfo.resident_size) 55 | } 56 | 57 | return used / Constants.MB 58 | } 59 | 60 | /// Obtain current memory state for your device. 61 | public static func state() -> MemoryState { 62 | var count: mach_msg_type_number_t = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size) 63 | 64 | let pageSize = Double(vm_kernel_page_size) 65 | 66 | let statisticsPointer = vm_statistics64_t.allocate(capacity: Int(count)) 67 | defer { statisticsPointer.deallocate() } 68 | 69 | let kerr = statisticsPointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { 70 | host_statistics64(mach_host_self(), host_flavor_t(HOST_VM_INFO64), $0, &count) 71 | } 72 | 73 | #if DEBUG 74 | if kerr != KERN_SUCCESS { 75 | let errorString = String(cString: mach_error_string(kerr), encoding: String.Encoding.ascii) ?? "unknown error" 76 | print("Collecting memroy detail failed: \(errorString)") 77 | } 78 | #endif 79 | 80 | let statistics: vm_statistics64 = statisticsPointer.move() 81 | let free = Double(statistics.free_count) * pageSize 82 | let active = Double(statistics.active_count) * pageSize 83 | let inactive = Double(statistics.inactive_count) * pageSize 84 | let wired = Double(statistics.wire_count) * pageSize 85 | let compressed = Double(statistics.compressor_page_count) * pageSize 86 | 87 | return (free, active, inactive, wired, compressed, totalBytes) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /PerformanceMonitor/MethodTimeMonitor/MethodTimeMonitor.h: -------------------------------------------------------------------------------- 1 | // 2 | // MethodTimeMonitor.h 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/9/10. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | #ifndef MethodTimeMonitor_h 10 | #define MethodTimeMonitor_h 11 | 12 | 13 | #endif /* MethodTimeMonitor_h */ 14 | 15 | #import 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | IMP _Nonnull imp_implementationForwardingToTracer(void * _Nonnull patch, IMP _Nonnull onEntry, IMP _Nonnull onExit); 21 | void findPureSwiftClasses(const char * _Nullable path, void (^ _Nonnull callback)(void * _Nonnull symbol)); 22 | int fast_dladdr(const void * _Nonnull, Dl_info * _Nonnull); 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /PerformanceMonitor/MethodTimeMonitor/MethodTimeMonitor.mm: -------------------------------------------------------------------------------- 1 | // 2 | // MethodTimeMonitor.m 3 | // MethodTimeMonitor 4 | // 5 | // Repo: https://github.com/johnno1962/SwiftTrace 6 | // $Id: //depot/SwiftTrace/SwiftTrace/SwiftTrace.mm#37 $ 7 | // 8 | // Trampoline code thanks to: 9 | // https://github.com/OliverLetterer/imp_implementationForwardingToSelector 10 | // 11 | // imp_implementationForwardingToSelector.m 12 | // imp_implementationForwardingToSelector 13 | // 14 | // Created by Oliver Letterer on 22.03.14. 15 | // Copyright (c) 2014 Oliver Letterer 16 | // 17 | // Permission is hereby granted, free of charge, to any person obtaining a copy 18 | // of this software and associated documentation files (the "Software"), to deal 19 | // in the Software without restriction, including without limitation the rights 20 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 21 | // copies of the Software, and to permit persons to whom the Software is 22 | // furnished to do so, subject to the following conditions: 23 | // 24 | // The above copyright notice and this permission notice shall be included in 25 | // all copies or substantial portions of the Software. 26 | // 27 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 33 | // THE SOFTWARE. 34 | // 35 | 36 | #import "PerformanceMonitor.h" 37 | 38 | #import 39 | #import 40 | 41 | #import 42 | #import 43 | #import 44 | 45 | extern char xt_forwarding_trampoline_page, xt_forwarding_trampolines_start, 46 | xt_forwarding_trampolines_next, xt_forwarding_trampolines_end; 47 | 48 | static OSSpinLock lock = OS_SPINLOCK_INIT; 49 | 50 | // trampoline implementation specific stuff... 51 | typedef struct { 52 | #if !defined(__LP64__) 53 | IMP tracer; 54 | #endif 55 | void *patch; // Pointer to SwiftTrace.Patch instance retained elsewhere 56 | } XtraceTrampolineDataBlock; 57 | 58 | typedef int32_t SPLForwardingTrampolineEntryPointBlock[2]; 59 | #if defined(__i386__) 60 | static const int32_t SPLForwardingTrampolineInstructionCount = 8; 61 | #elif defined(_ARM_ARCH_7) 62 | static const int32_t SPLForwardingTrampolineInstructionCount = 12; 63 | #undef PAGE_SIZE 64 | #define PAGE_SIZE (1<<14) 65 | #elif defined(__arm64__) 66 | static const int32_t SPLForwardingTrampolineInstructionCount = 62; 67 | #undef PAGE_SIZE 68 | #define PAGE_SIZE (1<<14) 69 | #elif defined(__LP64__) // x86_64 70 | static const int32_t SPLForwardingTrampolineInstructionCount = 84; 71 | #else 72 | #error SwiftTrace is not supported on this platform 73 | #endif 74 | 75 | static const size_t numberOfTrampolinesPerPage = (PAGE_SIZE - SPLForwardingTrampolineInstructionCount * sizeof(int32_t)) / sizeof(SPLForwardingTrampolineEntryPointBlock); 76 | 77 | typedef struct { 78 | union { 79 | struct { 80 | #if defined(__LP64__) 81 | IMP onEntry; 82 | IMP onExit; 83 | #endif 84 | int32_t nextAvailableTrampolineIndex; 85 | }; 86 | int32_t trampolineSize[SPLForwardingTrampolineInstructionCount]; 87 | }; 88 | 89 | XtraceTrampolineDataBlock trampolineData[numberOfTrampolinesPerPage]; 90 | 91 | int32_t trampolineInstructions[SPLForwardingTrampolineInstructionCount]; 92 | SPLForwardingTrampolineEntryPointBlock trampolineEntryPoints[numberOfTrampolinesPerPage]; 93 | } SPLForwardingTrampolinePage; 94 | 95 | //check_compile_time(sizeof(SPLForwardingTrampolineEntryPointBlock) == sizeof(XtraceTrampolineDataBlock)); 96 | //check_compile_time(sizeof(SPLForwardingTrampolinePage) == 2 * PAGE_SIZE); 97 | //check_compile_time(offsetof(SPLForwardingTrampolinePage, trampolineInstructions) == PAGE_SIZE); 98 | 99 | static SPLForwardingTrampolinePage *SPLForwardingTrampolinePageAlloc() 100 | { 101 | vm_address_t trampolineTemplatePage = (vm_address_t)&xt_forwarding_trampoline_page; 102 | 103 | vm_address_t newTrampolinePage = 0; 104 | kern_return_t kernReturn = KERN_SUCCESS; 105 | 106 | //printf( "%d %d %d %d %d\n", vm_page_size, &xt_forwarding_trampolines_start - &xt_forwarding_trampoline_page, SPLForwardingTrampolineInstructionCount*4, &xt_forwarding_trampolines_end - &xt_forwarding_trampoline_page, &xt_forwarding_trampolines_next - &xt_forwarding_trampolines_start ); 107 | 108 | assert( &xt_forwarding_trampolines_start - &xt_forwarding_trampoline_page == 109 | SPLForwardingTrampolineInstructionCount * sizeof(int32_t) ); 110 | assert( &xt_forwarding_trampolines_end - &xt_forwarding_trampoline_page == PAGE_SIZE ); 111 | assert( &xt_forwarding_trampolines_next - &xt_forwarding_trampolines_start == sizeof(XtraceTrampolineDataBlock) ); 112 | 113 | // allocate two consequent memory pages 114 | kernReturn = vm_allocate(mach_task_self(), &newTrampolinePage, PAGE_SIZE * 2, VM_FLAGS_ANYWHERE); 115 | NSCAssert1(kernReturn == KERN_SUCCESS, @"vm_allocate failed", kernReturn); 116 | 117 | // deallocate second page where we will store our trampoline 118 | vm_address_t trampoline_page = newTrampolinePage + PAGE_SIZE; 119 | kernReturn = vm_deallocate(mach_task_self(), trampoline_page, PAGE_SIZE); 120 | NSCAssert1(kernReturn == KERN_SUCCESS, @"vm_deallocate failed", kernReturn); 121 | 122 | // trampoline page will be remapped with implementation of spl_objc_forwarding_trampoline 123 | vm_prot_t cur_protection, max_protection; 124 | kernReturn = vm_remap(mach_task_self(), &trampoline_page, PAGE_SIZE, 0, 0, mach_task_self(), trampolineTemplatePage, FALSE, &cur_protection, &max_protection, VM_INHERIT_SHARE); 125 | NSCAssert1(kernReturn == KERN_SUCCESS, @"vm_remap failed", kernReturn); 126 | 127 | return (SPLForwardingTrampolinePage *)newTrampolinePage; 128 | } 129 | 130 | static SPLForwardingTrampolinePage *nextTrampolinePage() 131 | { 132 | static NSMutableArray *normalTrampolinePages = nil; 133 | static dispatch_once_t onceToken; 134 | dispatch_once(&onceToken, ^{ 135 | normalTrampolinePages = [NSMutableArray array]; 136 | }); 137 | 138 | NSMutableArray *thisArray = normalTrampolinePages; 139 | 140 | SPLForwardingTrampolinePage *trampolinePage = (SPLForwardingTrampolinePage *)[thisArray.lastObject pointerValue]; 141 | 142 | if (!trampolinePage || (trampolinePage->nextAvailableTrampolineIndex == numberOfTrampolinesPerPage) ) { 143 | trampolinePage = SPLForwardingTrampolinePageAlloc(); 144 | [thisArray addObject:[NSValue valueWithPointer:trampolinePage]]; 145 | } 146 | 147 | return trampolinePage; 148 | } 149 | 150 | IMP imp_implementationForwardingToTracer(void *patch, IMP onEntry, IMP onExit) 151 | { 152 | 153 | OSSpinLockLock(&lock); 154 | 155 | SPLForwardingTrampolinePage *dataPageLayout = nextTrampolinePage(); 156 | 157 | int32_t nextAvailableTrampolineIndex = dataPageLayout->nextAvailableTrampolineIndex; 158 | 159 | #if !defined(__LP64__) 160 | dataPageLayout->trampolineData[nextAvailableTrampolineIndex].tracer = onEntry; 161 | #else 162 | dataPageLayout->onEntry = onEntry; 163 | dataPageLayout->onExit = onExit; 164 | #endif 165 | dataPageLayout->trampolineData[nextAvailableTrampolineIndex].patch = patch; 166 | dataPageLayout->nextAvailableTrampolineIndex++; 167 | 168 | IMP implementation = (IMP)&dataPageLayout->trampolineEntryPoints[nextAvailableTrampolineIndex]; 169 | 170 | OSSpinLockUnlock(&lock); 171 | 172 | return implementation; 173 | } 174 | 175 | // From here on added to the original code for use by "SwiftTrace". 176 | // https://stackoverflow.com/questions/20481058/find-pathname-from-dlopen-handle-on-osx 177 | 178 | #import 179 | #import 180 | #import 181 | #import 182 | #import 183 | 184 | #ifdef __LP64__ 185 | typedef struct mach_header_64 mach_header_t; 186 | typedef struct segment_command_64 segment_command_t; 187 | typedef struct nlist_64 nlist_t; 188 | #else 189 | typedef struct mach_header mach_header_t; 190 | typedef struct segment_command segment_command_t; 191 | typedef struct nlist nlist_t; 192 | #endif 193 | 194 | void findPureSwiftClasses(const char *path, void (^callback)(void *aClass)) { 195 | for (int32_t i = _dyld_image_count(); i >= 0 ; i--) { 196 | const mach_header_t *header = (const mach_header_t *)_dyld_get_image_header(i); 197 | const char *imageName = _dyld_get_image_name(i); 198 | if (imageName && (imageName == path || strcmp(imageName, path) == 0)) { 199 | segment_command_t *seg_linkedit = NULL; 200 | segment_command_t *seg_text = NULL; 201 | struct symtab_command *symtab = NULL; 202 | 203 | struct load_command *cmd = (struct load_command *)((intptr_t)header + sizeof(mach_header_t)); 204 | for (uint32_t i = 0; i < header->ncmds; i++, cmd = (struct load_command *)((intptr_t)cmd + cmd->cmdsize)) 205 | { 206 | switch(cmd->cmd) 207 | { 208 | case LC_SEGMENT: 209 | case LC_SEGMENT_64: 210 | if (!strcmp(((segment_command_t *)cmd)->segname, SEG_TEXT)) 211 | seg_text = (segment_command_t *)cmd; 212 | else if (!strcmp(((segment_command_t *)cmd)->segname, SEG_LINKEDIT)) 213 | seg_linkedit = (segment_command_t *)cmd; 214 | break; 215 | 216 | case LC_SYMTAB: { 217 | symtab = (struct symtab_command *)cmd; 218 | intptr_t file_slide = ((intptr_t)seg_linkedit->vmaddr - (intptr_t)seg_text->vmaddr) - seg_linkedit->fileoff; 219 | const char *strings = (const char *)header + (symtab->stroff + file_slide); 220 | nlist_t *sym = (nlist_t *)((intptr_t)header + (symtab->symoff + file_slide)); 221 | 222 | for (uint32_t i = 0; i < symtab->nsyms; i++, sym++) { 223 | const char *sptr = strings + sym->n_un.n_strx; 224 | void *aClass; 225 | if (sym->n_type == 0xf && 226 | strncmp(sptr, "_$s", 3) == 0 && 227 | strcmp(sptr+strlen(sptr)-2, "CN") == 0 && 228 | (aClass = (void *)(sym->n_value + (intptr_t)header - (intptr_t)seg_text->vmaddr))) { 229 | callback(aClass); 230 | } 231 | } 232 | 233 | return; 234 | } 235 | } 236 | } 237 | } 238 | } 239 | } 240 | 241 | #import 242 | #import 243 | 244 | using namespace std; 245 | 246 | class Symbol { 247 | public: 248 | nlist_t *sym; 249 | Symbol(nlist_t *sym) { 250 | this->sym = sym; 251 | } 252 | }; 253 | 254 | static bool operator < (Symbol s1, Symbol s2) { 255 | return s1.sym->n_value < s2.sym->n_value; 256 | } 257 | 258 | class Dylib { 259 | const mach_header_t *header; 260 | segment_command_t *seg_linkedit = NULL; 261 | segment_command_t *seg_text = NULL; 262 | struct symtab_command *symtab = NULL; 263 | vector symbols; 264 | 265 | public: 266 | char *start = nullptr, *stop = nullptr; 267 | const char *imageName; 268 | 269 | Dylib(int imageIndex) { 270 | imageName = _dyld_get_image_name(imageIndex); 271 | header = (const mach_header_t *)_dyld_get_image_header(imageIndex); 272 | struct load_command *cmd = (struct load_command *)((intptr_t)header + sizeof(mach_header_t)); 273 | assert(header); 274 | 275 | for (uint32_t i = 0; i < header->ncmds; i++, cmd = (struct load_command *)((intptr_t)cmd + cmd->cmdsize)) 276 | { 277 | switch(cmd->cmd) 278 | { 279 | case LC_SEGMENT: 280 | case LC_SEGMENT_64: 281 | if (!strcmp(((segment_command_t *)cmd)->segname, SEG_TEXT)) 282 | seg_text = (segment_command_t *)cmd; 283 | else if (!strcmp(((segment_command_t *)cmd)->segname, SEG_LINKEDIT)) 284 | seg_linkedit = (segment_command_t *)cmd; 285 | break; 286 | 287 | case LC_SYMTAB: 288 | symtab = (struct symtab_command *)cmd; 289 | } 290 | } 291 | 292 | const struct section_64 *section = getsectbynamefromheader_64( (const struct mach_header_64 *)header, SEG_TEXT, SECT_TEXT ); 293 | if (section == 0) return; 294 | start = (char *)(section->addr + _dyld_get_image_vmaddr_slide( (uint32_t)imageIndex )); 295 | stop = start + section->size; 296 | } 297 | 298 | bool contains(const void *p) { 299 | return p >= start && p <= stop; 300 | } 301 | 302 | int dladdr(const void *ptr, Dl_info *info) { 303 | intptr_t file_slide = ((intptr_t)seg_linkedit->vmaddr - (intptr_t)seg_text->vmaddr) - seg_linkedit->fileoff; 304 | const char *strings = (const char *)header + (symtab->stroff + file_slide); 305 | 306 | if (symbols.empty()) { 307 | nlist_t *sym = (nlist_t *)((intptr_t)header + (symtab->symoff + file_slide)); 308 | 309 | for (uint32_t i = 0; i < symtab->nsyms; i++, sym++) 310 | if (sym->n_type == 0xf) 311 | symbols.push_back(Symbol(sym)); 312 | 313 | sort(symbols.begin(), symbols.end()); 314 | } 315 | 316 | nlist_t nlist; 317 | nlist.n_value = (intptr_t)ptr - ((intptr_t)header - (intptr_t)seg_text->vmaddr); 318 | 319 | auto it = lower_bound(symbols.begin(), symbols.end(), Symbol(&nlist)); 320 | if (it != symbols.end()) { 321 | info->dli_fname = imageName; 322 | info->dli_sname = strings + it->sym->n_un.n_strx + 1; 323 | return 1; 324 | } 325 | 326 | return 0; 327 | } 328 | }; 329 | 330 | class DylibPtr { 331 | public: 332 | Dylib *dylib; 333 | const char *start; 334 | DylibPtr(Dylib *dylib) { 335 | if ((this->dylib = dylib)) 336 | this->start = dylib->start; 337 | } 338 | }; 339 | 340 | bool operator < (DylibPtr s1, DylibPtr s2) { 341 | return s1.start < s2.start; 342 | } 343 | 344 | int fast_dladdr(const void *ptr, Dl_info *info) { 345 | #if !TRY_TO_OPTIMISE_DLADDR 346 | return dladdr(ptr, info); 347 | #else 348 | static vector dylibs; 349 | 350 | if (dylibs.empty()) { 351 | for (int32_t i = 0; i < _dyld_image_count(); i++) 352 | dylibs.push_back(DylibPtr(new Dylib(i))); 353 | 354 | sort(dylibs.begin(), dylibs.end()); 355 | } 356 | 357 | if (ptr < dylibs[0].dylib->start) 358 | return 0; 359 | 360 | DylibPtr dylibPtr(NULL); 361 | dylibPtr.start = (const char *)ptr; 362 | auto it = lower_bound(dylibs.begin(), dylibs.end(), dylibPtr); 363 | if (it != dylibs.end()) { 364 | Dylib *dylib = dylibs[distance(dylibs.begin(), it)-1].dylib; 365 | if (!dylib || !dylib->contains(ptr)) 366 | return 0; 367 | return dylib->dladdr(ptr, info); 368 | } 369 | 370 | return 0; 371 | #endif 372 | } 373 | -------------------------------------------------------------------------------- /PerformanceMonitor/MethodTimeMonitor/MethodTimeMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MethodTimeMonitor.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/9/8. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // https://github.com/apple/swift/blob/master/docs/ABI/TypeMetadata.rst#class-metadata 12 | struct SwiftClassMetada { 13 | let metaClass: Int 14 | let superClass: Any.Type 15 | let reserved1: Int 16 | let reserved2: Int 17 | let rodataPointer: Int 18 | let flags: UInt32 19 | let instanceAddressPoint: UInt32 20 | let instanceSize: UInt32 21 | let instanceAlignmentMask: UInt16 22 | let reserved: UInt16 23 | 24 | let classSize: UInt32 25 | let classAddressPoint: UInt32 26 | let descriptor: Int 27 | var ivarDestroyer: UnsafeMutableRawPointer? 28 | // the follow is vtable 29 | } 30 | 31 | // Reference: https://github.com/johnno1962/SwiftTrace 32 | 33 | #if arch(arm64) 34 | 35 | /// Stack layout on entry from xt_forwarding_trampoline_arm64.s 36 | struct EntryStack { 37 | static let maxFloatArgs = 8 38 | static let maxIntArgs = 8 39 | 40 | public var floatArg1: Double = 0.0 41 | public var floatArg2: Double = 0.0 42 | public var floatArg3: Double = 0.0 43 | public var floatArg4: Double = 0.0 44 | public var floatArg5: Double = 0.0 45 | public var floatArg6: Double = 0.0 46 | public var floatArg7: Double = 0.0 47 | public var floatArg8: Double = 0.0 48 | public var intArg1: intptr_t = 0 49 | public var intArg2: intptr_t = 0 50 | public var intArg3: intptr_t = 0 51 | public var intArg4: intptr_t = 0 52 | public var intArg5: intptr_t = 0 53 | public var intArg6: intptr_t = 0 54 | public var intArg7: intptr_t = 0 55 | public var intArg8: intptr_t = 0 56 | public var structReturn: intptr_t = 0 // x8 57 | public var framePointer: intptr_t = 0 58 | public var swiftSelf: intptr_t = 0 // x20 59 | public var thrownError: intptr_t = 0 // x21 60 | } 61 | 62 | /// Stack layout on exit from xt_forwarding_trampoline_arm64.s 63 | struct ExitStack { 64 | static let returnRegs = 4 65 | 66 | public var floatReturn1: Double = 0.0 67 | public var floatReturn2: Double = 0.0 68 | public var floatReturn3: Double = 0.0 69 | public var floatReturn4: Double = 0.0 70 | public var d4: Double = 0.0 71 | public var d5: Double = 0.0 72 | public var d6: Double = 0.0 73 | public var d7: Double = 0.0 74 | public var intReturn1: intptr_t = 0 75 | public var intReturn2: intptr_t = 0 76 | public var intReturn3: intptr_t = 0 77 | public var intReturn4: intptr_t = 0 78 | public var x4: intptr_t = 0 79 | public var x5: intptr_t = 0 80 | public var x6: intptr_t = 0 81 | public var x7: intptr_t = 0 82 | public var structReturn: intptr_t = 0 // x8 83 | public var framePointer: intptr_t = 0 84 | public var swiftSelf: intptr_t = 0 // x20 85 | public var thrownError: intptr_t = 0 // x21 86 | 87 | mutating func resyncStructReturn() { 88 | structReturn = autoBitCast(invocation.structReturn) 89 | } 90 | } 91 | #else // x86_64 92 | /// Stack layout on entry from xt_forwarding_trampoline_x64.s 93 | struct EntryStack { 94 | static let maxFloatArgs = 8 95 | static let maxIntArgs = 6 96 | 97 | public var floatArg1: Double = 0.0 98 | public var floatArg2: Double = 0.0 99 | public var floatArg3: Double = 0.0 100 | public var floatArg4: Double = 0.0 101 | public var floatArg5: Double = 0.0 102 | public var floatArg6: Double = 0.0 103 | public var floatArg7: Double = 0.0 104 | public var floatArg8: Double = 0.0 105 | public var framePointer: intptr_t = 0 106 | public var r10: intptr_t = 0 107 | public var r12: intptr_t = 0 108 | public var swiftSelf: intptr_t = 0 // r13 109 | public var r14: intptr_t = 0 110 | public var r15: intptr_t = 0 111 | public var intArg1: intptr_t = 0 // rdi 112 | public var intArg2: intptr_t = 0 // rsi 113 | public var intArg3: intptr_t = 0 // rcx 114 | public var intArg4: intptr_t = 0 // rdx 115 | public var intArg5: intptr_t = 0 // r8 116 | public var intArg6: intptr_t = 0 // r9 117 | public var structReturn: intptr_t = 0 // rax 118 | public var rbx: intptr_t = 0 119 | } 120 | 121 | /// Stack layout on exit from xt_forwarding_trampoline_x64.s 122 | struct ExitStack { 123 | static let returnRegs = 4 124 | 125 | public var stackShift1: intptr_t = 0 126 | public var stackShift2: intptr_t = 0 127 | public var floatReturn1: Double = 0.0 // xmm0 128 | public var floatReturn2: Double = 0.0 // xmm1 129 | public var floatReturn3: Double = 0.0 // xmm2 130 | public var floatReturn4: Double = 0.0 // xmm3 131 | public var xmm4: Double = 0.0 132 | public var xmm5: Double = 0.0 133 | public var xmm6: Double = 0.0 134 | public var xmm7: Double = 0.0 135 | public var framePointer: intptr_t = 0 136 | public var r10: intptr_t = 0 137 | public var thrownError: intptr_t = 0 // r12 138 | public var swiftSelf: intptr_t = 0 // r13 139 | public var r14: intptr_t = 0 140 | public var r15: intptr_t = 0 141 | public var rdi: intptr_t = 0 142 | public var rsi: intptr_t = 0 143 | public var intReturn1: intptr_t = 0 // rax (also struct Return) 144 | public var intReturn2: intptr_t = 0 // rdx 145 | public var intReturn3: intptr_t = 0 // rcx 146 | public var intReturn4: intptr_t = 0 // r8 147 | public var r9: intptr_t = 0 148 | public var rbx: intptr_t = 0 149 | public var structReturn: intptr_t { 150 | return intReturn1 151 | } 152 | } 153 | #endif 154 | 155 | private func autoBitCast(_ arg: IN) -> OUT { 156 | return unsafeBitCast(arg, to: OUT.self) 157 | } 158 | 159 | /// pointer to a function implementing a Swift method */ 160 | typealias SIMP = UnsafeMutableRawPointer 161 | 162 | extension NSObject { 163 | 164 | public class func traceBundle() { 165 | MethodTimeMonitor.traceBundle(containing: self) 166 | } 167 | 168 | public class func traceClass() { 169 | MethodTimeMonitor.trace(aClass: self) 170 | } 171 | } 172 | 173 | public struct MethodTimeMonitorRecord: CustomStringConvertible { 174 | 175 | public let timeCost: String 176 | public let methodName: String 177 | 178 | public var description: String { 179 | var cost = timeCost 180 | let timeCostPointer = UnsafeRawPointer(&cost) 181 | return String(format: "%-10s %@ ", UInt(bitPattern: timeCostPointer), methodName) 182 | } 183 | } 184 | 185 | public protocol MethodTimeMonitorDelegate: AnyObject { 186 | 187 | func methodTimeMonitor(_ record: MethodTimeMonitorRecord) 188 | } 189 | 190 | open class MethodTimeMonitor: NSObject { 191 | 192 | public static weak var delegate: MethodTimeMonitorDelegate? 193 | 194 | static var threadLocal = ThreadLocal<[Patch.Invocation]>([]) 195 | 196 | /// Class used to create "Invocation" instances representing a specific call to a member function on the "ThreadLocal" stack. 197 | static var defaultInvocationFactory = Patch.Invocation.self 198 | 199 | /// Strace "info" instance used to store information about a patch on a method 200 | class Patch: NSObject { 201 | /// Dictionary of patch objects created by trampoline */ 202 | static var active = [IMP: Patch]() 203 | 204 | /// follow chain of Patches through to find original patch 205 | class func originalPatch(for implementation: IMP) -> Patch? { 206 | var implementation = implementation 207 | var patch: Patch? 208 | while active[implementation] != nil { 209 | patch = active[implementation] 210 | implementation = patch!.implementation 211 | } 212 | return patch 213 | } 214 | 215 | /// string representing Swift or Objective-C method to user 216 | let name: String 217 | 218 | /// pointer to original function implementing method 219 | var implementation: IMP 220 | 221 | /// vtable slot patched for unpatching 222 | var vtableSlot: UnsafeMutablePointer? 223 | 224 | /// Original objc method swizzled 225 | let objcMethod: Method? 226 | 227 | /// Closure that can be called instead of original implementation 228 | let nullImplmentation: UnsafeMutableRawPointer? 229 | 230 | /// designated initialiser 231 | /// 232 | /// - Parameters: 233 | /// - name: string representing method being traced 234 | /// - vtableSlot: pointer to vtable slot patched 235 | /// - objcMethod: pointer to original Method patched 236 | /// - replaceWith: implementation to replace that of class 237 | required init?(name: String, 238 | vtableSlot: UnsafeMutablePointer? = nil, 239 | objcMethod: Method? = nil, 240 | replaceWith: UnsafeMutableRawPointer? = nil) { 241 | self.name = name 242 | self.vtableSlot = vtableSlot 243 | self.objcMethod = objcMethod 244 | if let vtableSlot = vtableSlot { 245 | implementation = autoBitCast(vtableSlot.pointee) 246 | } 247 | else { 248 | implementation = method_getImplementation(objcMethod!) 249 | } 250 | nullImplmentation = replaceWith 251 | } 252 | 253 | /// Called from assembly code on entry to Patched method 254 | static var onEntry: @convention(c) (_ patch: Patch, _ returnAddress: UnsafeRawPointer, _ stackPointer: UnsafeMutablePointer) -> IMP? = { 255 | (patch, returnAddress, stackPointer) -> IMP? in 256 | let invocation = patch.invocationFactory.init(stackDepth: MethodTimeMonitor.threadLocal.value.count, patch: patch, 257 | returnAddress: returnAddress, stackPointer: stackPointer ) 258 | 259 | MethodTimeMonitor.threadLocal.value.append(invocation) 260 | patch.onEntry(stack: &invocation.entryStack.pointee) 261 | return patch.nullImplmentation != nil ? 262 | autoBitCast(patch.nullImplmentation) : patch.implementation 263 | } 264 | 265 | /// Called from assembly code when Patched method returns 266 | static var onExit: @convention(c) () -> UnsafeRawPointer = { 267 | let invocation = Invocation.current! 268 | invocation.patch.onExit(stack: &invocation.exitStack.pointee) 269 | MethodTimeMonitor.threadLocal.value.removeLast() 270 | return invocation.returnAddress 271 | } 272 | 273 | /// Return a unique pointer to a trampoline that will callback the oneEntry() and onExit() method in this class 274 | func forwardingImplementation() -> SIMP { 275 | // create trampoline 276 | let impl = imp_implementationForwardingToTracer(autoBitCast(self), 277 | autoBitCast(Patch.onEntry), autoBitCast(Patch.onExit)) 278 | Patch.active[impl] = self // track Patches by trampoline and retain them 279 | return autoBitCast(impl) 280 | } 281 | 282 | /// method called before trampoline enters the target "Patch" 283 | func onEntry(stack: inout EntryStack) { 284 | } 285 | 286 | /// method called after trampoline exits the target "Patch" 287 | func onExit(stack: inout ExitStack) { 288 | if let invocation = Invocation.current { 289 | let elapsed = Invocation.usecTime() - invocation.timeEntered 290 | let timeCost = String(format: "%.1fms", elapsed * 1000.0) 291 | let methodName = "\(String(repeating: " ", count: invocation.stackDepth))\(name)" 292 | let record = MethodTimeMonitorRecord(timeCost: timeCost, methodName: methodName) 293 | MethodTimeMonitor.delegate?.methodTimeMonitor(record) 294 | } 295 | } 296 | 297 | /// Class used to create a specific "Invocation" of the "Patch" on entry 298 | var invocationFactory: Invocation.Type { 299 | return defaultInvocationFactory 300 | } 301 | 302 | /// The inner invocation instance on the stack of the current thread. 303 | func invocation() -> Invocation! { 304 | return Invocation.current 305 | } 306 | 307 | /// Remove this patch 308 | func remove() { 309 | if let vtableSlot = vtableSlot { 310 | vtableSlot.pointee = autoBitCast(implementation) 311 | } 312 | else if let objcMethod = objcMethod { 313 | method_setImplementation(objcMethod, implementation) 314 | } 315 | } 316 | 317 | /// Remove all patches recursively 318 | func removeAll() { 319 | (Patch.originalPatch(for: implementation) ?? self).remove() 320 | } 321 | 322 | /// find "self" for the current invocation 323 | func getSelf(as: T.Type = T.self) -> T { 324 | return autoBitCast(invocation().swiftSelf) 325 | } 326 | 327 | /// pointer to memory for return of struct 328 | func structReturn(as: T.Type = T.self) -> UnsafeMutablePointer { 329 | return invocation().structReturn!.assumingMemoryBound(to: T.self) 330 | } 331 | 332 | /// convert arguments & return results to a specifi type 333 | func rebind(_ pointer: UnsafeMutablePointer, to: OUT.Type = OUT.self) -> UnsafeMutablePointer { 334 | return pointer.withMemoryRebound(to: OUT.self, capacity: 1) { $0 } 335 | } 336 | 337 | /// Represents a specific call to a member function on the "ThreadLocal" stack 338 | class Invocation { 339 | /// Time call was started 340 | let timeEntered: Double 341 | 342 | /// Number of calls above this on the stack of the current thread 343 | let stackDepth: Int 344 | 345 | /// "Patch" related to this call 346 | let patch: Patch 347 | 348 | /// Original return address of call to trampoline 349 | let returnAddress: UnsafeRawPointer 350 | 351 | /// Architecture depenent place on stack where arguments stored 352 | let entryStack: UnsafeMutablePointer 353 | 354 | var exitStack: UnsafeMutablePointer { 355 | return patch.rebind(entryStack) 356 | } 357 | 358 | /// copy of struct return register in case function throws 359 | var structReturn: UnsafeMutableRawPointer? = nil 360 | 361 | /// "self" for method invocations 362 | let swiftSelf: intptr_t 363 | 364 | /// for use relaying data from entry to exit 365 | var userInfo: AnyObject? 366 | 367 | /// micro-second precision time. 368 | static public func usecTime() -> Double { 369 | var tv = timeval() 370 | gettimeofday(&tv, nil) 371 | return Double(tv.tv_sec) + Double(tv.tv_usec)/1_000_000.0 372 | } 373 | 374 | /// designated initialiser 375 | /// 376 | /// - Parameters: 377 | /// - stackDepth: number of calls that have been made on the stack 378 | /// - patch: associated Patch instance 379 | /// - returnAddress: adress in process trampoline was called from 380 | /// - stackPointer: stack pointer of thread with saved registers 381 | required init(stackDepth: Int, 382 | patch: Patch, 383 | returnAddress: UnsafeRawPointer, 384 | stackPointer: UnsafeMutablePointer) { 385 | timeEntered = Invocation.usecTime() 386 | self.stackDepth = stackDepth 387 | self.patch = patch 388 | self.returnAddress = returnAddress 389 | self.entryStack = patch.rebind(stackPointer) 390 | self.swiftSelf = patch.objcMethod != nil ? 391 | self.entryStack.pointee.intArg1 : self.entryStack.pointee.swiftSelf 392 | self.structReturn = UnsafeMutableRawPointer(bitPattern: self.entryStack.pointee.structReturn) 393 | } 394 | 395 | /// The inner invocation instance on the current thread. 396 | static var current: Invocation! { 397 | return MethodTimeMonitor.threadLocal.value.last 398 | } 399 | } 400 | } 401 | 402 | 403 | /// default pattern of symbols to be excluded from tracing 404 | static public let defaultMethodExclusions = "\\.getter|retain]|release]|_tryRetain]|.cxx_destruct]|initWithCoder|_isDeallocating]|^\\+\\[(Reader_Base64|UI(NibStringIDTable|NibDecoder|CollectionViewData|WebTouchEventsGestureRecognizer)) |^.\\[UIView |UIButton _defaultBackgroundImageForType:andState:|RxSwift.ScheduledDisposable.dispose" 405 | 406 | static var inclusionRegexp: NSRegularExpression? 407 | static var exclusionRegexp: NSRegularExpression? = NSRegularExpression(pattern: defaultMethodExclusions) 408 | 409 | /// Include symbols matching pattern only 410 | /// 411 | /// - Parameter pattern: regexp for symbols to include 412 | public class func include(_ pattern: String) { 413 | inclusionRegexp = NSRegularExpression(pattern: pattern) 414 | } 415 | 416 | /// Exclude symbols matching this pattern. If not specified a default pattern in swiftTraceDefaultExclusions is used. 417 | /// 418 | /// - Parameter pattern: regexp for symbols to exclude 419 | public class func exclude(_ pattern: String) { 420 | exclusionRegexp = NSRegularExpression(pattern: pattern) 421 | } 422 | 423 | class func included(symbol: String) -> Bool { 424 | return (inclusionRegexp?.matches(symbol) != false) && (exclusionRegexp?.matches(symbol) != true) 425 | } 426 | 427 | /// Intercepts and tracess all classes linked into the bundle containing a class. 428 | /// 429 | /// - Parameter theClass: the class to specify the bundle 430 | @objc open class func traceBundle(containing theClass: AnyClass) { 431 | trace(bundlePath: class_getImageName(theClass)) 432 | } 433 | 434 | /// Trace all user developed classes in the main bundle of an app 435 | @objc open class func traceMainBundle() { 436 | let main = dlsym(UnsafeMutableRawPointer(bitPattern: -2), "main") 437 | var info = Dl_info() 438 | if main != nil && dladdr(main, &info) != 0 && info.dli_fname != nil { 439 | trace(bundlePath: info.dli_fname) 440 | } else { 441 | fatalError("Could not locate main bundle") 442 | } 443 | } 444 | 445 | /// Trace a classes defined in a specific bundlePath (executable image) 446 | @objc public class func trace(bundlePath: UnsafePointer?) { 447 | var registered = Set() 448 | forAllClasses { aClass, _ in 449 | if class_getImageName(aClass) == bundlePath { 450 | trace(aClass: aClass) 451 | registered.insert(autoBitCast(aClass)) 452 | } 453 | } 454 | // This should pick up and Pure Swift classes 455 | findPureSwiftClasses(bundlePath, { aClass in 456 | if !registered.contains(aClass) { 457 | trace(aClass: autoBitCast(aClass)) 458 | } 459 | }) 460 | } 461 | 462 | /// Lists Swift classes in an app or framework. 463 | /// 464 | /// - Parameter bundlePath: bundlePath 465 | /// - Returns: all the Swift classes 466 | open class func swiftClassList(bundlePath: UnsafePointer) -> [AnyClass] { 467 | var classes = [AnyClass]() 468 | findPureSwiftClasses(bundlePath, { aClass in 469 | classes.append(autoBitCast(aClass)) 470 | }) 471 | return classes 472 | } 473 | 474 | /// Intercepts and tracess all classes with names matching regexp pattern 475 | /// 476 | /// - Parameter pattern: regexp patten to specify classes to trace 477 | @objc public class func traceClassesMatching(pattern: String) { 478 | if let regexp = NSRegularExpression(pattern: pattern) { 479 | forAllClasses { aClass, _ in 480 | let className = NSStringFromClass(aClass) as NSString 481 | if regexp.firstMatch(in: String(describing: className) as String, range: NSMakeRange(0, className.length)) != nil { 482 | trace(aClass: aClass) 483 | } 484 | } 485 | } 486 | } 487 | 488 | /// Specify an individual classs to trace 489 | /// 490 | /// - Parameter aClass: the class, the methods of which to trace 491 | @objc public class func trace(aClass: AnyClass) { 492 | let className = NSStringFromClass(aClass) 493 | if className.hasPrefix("Swift.") || className.hasPrefix("__") { 494 | return 495 | } 496 | 497 | var tClass: AnyClass? = aClass 498 | while tClass != nil { 499 | if NSStringFromClass(tClass!).contains("SwiftTrace") { 500 | return 501 | } 502 | tClass = class_getSuperclass(tClass) 503 | } 504 | 505 | interceptObjcMethods(of: object_getClass(aClass)!, which: "+") 506 | interceptObjcMethods(of: aClass, which: "-") 507 | 508 | iterateVtableMethods(of: aClass) { name, vtableSlot, _ in 509 | if included(symbol: name), 510 | let patch = Patch(name: name, vtableSlot: vtableSlot) { 511 | vtableSlot.pointee = patch.forwardingImplementation() 512 | } 513 | } 514 | } 515 | 516 | @objc public class func removeAllPatches() { 517 | for (_, patch) in Patch.active { 518 | patch.removeAll() 519 | } 520 | } 521 | } 522 | 523 | extension MethodTimeMonitor { 524 | 525 | /// Iterate over all methods in the vtable that follows the class information of a Swift class (TargetClassMetadata) 526 | @discardableResult 527 | class func iterateVtableMethods(of aClass: AnyClass, 528 | callback: @escaping (_ name: String, _ vtableSlot: UnsafeMutablePointer, _ stop: inout Bool) -> Void) -> Bool { 529 | let swiftMeta: UnsafeMutablePointer = autoBitCast(aClass) 530 | let className = NSStringFromClass(aClass) 531 | var stop = false 532 | 533 | guard (className.hasPrefix("_Tt") || className.contains(".")) && !className.hasPrefix("Swift.") else { 534 | return false 535 | } 536 | 537 | withUnsafeMutablePointer(to: &swiftMeta.pointee.ivarDestroyer) { vtableStart in 538 | swiftMeta.withMemoryRebound(to: Int8.self, capacity: 1) { 539 | let endMeta = ($0 - Int(swiftMeta.pointee.classAddressPoint) + Int(swiftMeta.pointee.classSize)) 540 | endMeta.withMemoryRebound(to: Optional.self, capacity: 1) { vtableEnd in 541 | 542 | var info = Dl_info() 543 | for i in 0..<(vtableEnd - vtableStart) { 544 | if var impl: IMP = autoBitCast(vtableStart[i]) { 545 | if let patch = Patch.originalPatch(for: impl) { 546 | impl = patch.implementation 547 | } 548 | let voidPtr: UnsafeMutableRawPointer = autoBitCast(impl) 549 | if fast_dladdr(voidPtr, &info) != 0 && info.dli_sname != nil, 550 | let demangled = demangle(symbol: info.dli_sname) { 551 | callback(demangled, &vtableStart[i]!, &stop) 552 | if stop { 553 | break 554 | } 555 | } 556 | } 557 | } 558 | } 559 | } 560 | } 561 | 562 | return stop 563 | } 564 | 565 | /// Intercept Objective-C class' methods using swizzling 566 | /// 567 | /// - Parameters: 568 | /// - aClass: meta-class or class to be swizzled 569 | /// - which: "+" for class methods, "-" for instance methods 570 | class func interceptObjcMethods(of aClass: AnyClass, which: String) { 571 | var mc: UInt32 = 0 572 | guard let methods = class_copyMethodList(aClass, &mc) else { 573 | return 574 | } 575 | for method in (0.. Void ) -> Bool { 598 | var stopped = false 599 | var nc: UInt32 = 0 600 | guard let classes = objc_copyClassList(&nc) else { 601 | return stopped 602 | } 603 | 604 | for aClass in (0.. Bool { 621 | var name = [Int8](repeating: 0, count: 5000) 622 | strcpy(&name, sel_getName(sel)) 623 | if strncmp(name, "is", 2) == 0 && isupper(Int32(name[2])) != 0 { 624 | name[2] = Int8(towlower(Int32(name[2]))) 625 | return class_getProperty(aClass, &name[2]) != nil 626 | } else if strncmp(name, "set", 3) != 0 || islower(Int32(name[3])) != 0 { 627 | return class_getProperty(aClass, name) != nil 628 | } else { 629 | name[3] = Int8(tolower(Int32(name[3]))) 630 | name[Int(strlen(name))-1] = 0 631 | return class_getProperty(aClass, &name[3]) != nil 632 | } 633 | } 634 | 635 | class func demangle(symbol: UnsafePointer) -> String? { 636 | if let demangledNamePtr = _stdlib_demangleImpl( 637 | symbol, mangledNameLength: UInt(strlen(symbol)), 638 | outputBuffer: nil, outputBufferSize: nil, flags: 0) { 639 | let demangledName = String(cString: demangledNamePtr) 640 | free(demangledNamePtr) 641 | return demangledName 642 | } 643 | return nil 644 | } 645 | } 646 | 647 | @_silgen_name("swift_demangle") 648 | private 649 | func _stdlib_demangleImpl( 650 | _ mangledName: UnsafePointer?, 651 | mangledNameLength: UInt, 652 | outputBuffer: UnsafeMutablePointer?, 653 | outputBufferSize: UnsafeMutablePointer?, 654 | flags: UInt32 655 | ) -> UnsafeMutablePointer? 656 | 657 | extension EntryStack { 658 | var invocation: MethodTimeMonitor.Patch.Invocation! { 659 | return MethodTimeMonitor.Patch.Invocation.current 660 | } 661 | } 662 | 663 | extension ExitStack { 664 | var invocation: MethodTimeMonitor.Patch.Invocation! { 665 | return MethodTimeMonitor.Patch.Invocation.current 666 | } 667 | } 668 | 669 | /// Convenience extension to trap regex errors and report them 670 | private extension NSRegularExpression { 671 | 672 | convenience init?(pattern: String) { 673 | do { 674 | try self.init(pattern: pattern, options: []) 675 | } catch let error as NSError { 676 | fatalError(error.localizedDescription) 677 | } 678 | } 679 | 680 | func matches(_ string: String) -> Bool { 681 | return rangeOfFirstMatch(in: string, options: [], range: NSMakeRange(0, string.utf16.count)).location != NSNotFound 682 | } 683 | } 684 | -------------------------------------------------------------------------------- /PerformanceMonitor/MethodTimeMonitor/ThreadLocal.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThreadLocal.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/9/8. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | /// A type that allows for storing a value that's unique to the current thread. 10 | final class ThreadLocal { 11 | 12 | private final class Box { 13 | var value: Value 14 | 15 | init(_ value: Value) { 16 | self.value = value 17 | } 18 | } 19 | 20 | fileprivate var key: pthread_key_t 21 | 22 | private let _value: Value 23 | 24 | init(_ value: Value) { 25 | _value = value 26 | key = pthread_key_t() 27 | pthread_key_create(&key, { 28 | guard let rawPointer = ($0 as UnsafeMutableRawPointer?) else { 29 | return 30 | } 31 | Unmanaged.fromOpaque(rawPointer).release() 32 | }) 33 | } 34 | 35 | var value: Value { 36 | get { 37 | guard let pointer = pthread_getspecific(key) else { 38 | return _value 39 | } 40 | return Unmanaged>.fromOpaque(pointer).takeUnretainedValue().value 41 | } 42 | set { 43 | if let pointer = pthread_getspecific(key) { 44 | Unmanaged.fromOpaque(pointer).release() 45 | } 46 | pthread_setspecific(key, Unmanaged.passRetained(Box(newValue)).toOpaque()) 47 | } 48 | } 49 | 50 | deinit { pthread_key_delete(key) } 51 | } 52 | 53 | extension ThreadLocal: Hashable { 54 | 55 | func hash(into hasher: inout Hasher) { 56 | hasher.combine(key.hashValue) 57 | } 58 | 59 | static func == (lhs: ThreadLocal, rhs: ThreadLocal) -> Bool { 60 | return lhs.key == rhs.key 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /PerformanceMonitor/MethodTimeMonitor/xt_forwarding_trampoline_x64.s: -------------------------------------------------------------------------------- 1 | 2 | // $Id: //depot/SwiftTrace/SwiftTrace/xt_forwarding_trampoline_x64.s#27 $ 3 | 4 | // https://en.wikipedia.org/wiki/X86_calling_conventions 5 | 6 | #if defined(__LP64__) && !defined(__arm64__) 7 | .text 8 | .align 12 9 | onEntry: 10 | .quad 0 // pointer to function to trace call 11 | onExit: 12 | .quad 0 // pointer to function to trace call 13 | // tracer instance stored at trampoline offset 14 | 15 | .align 12 16 | .globl _xt_forwarding_trampoline_page 17 | .globl _xt_forwarding_trampolines_start 18 | .globl _xt_forwarding_trampolines_next 19 | .globl _xt_forwarding_trampolines_end 20 | 21 | _xt_forwarding_trampoline_page: 22 | _xt_forwarding_trampoline: 23 | pushq %rbx 24 | pushq %rax // pointer for return of struct 25 | pushq %r9 // push all registers used as paremters 26 | pushq %r8 27 | pushq %rcx 28 | pushq %rdx 29 | pushq %rsi 30 | pushq %rdi 31 | pushq %r15 32 | pushq %r14 33 | pushq %r13 // Swift "call context" register for self 34 | pushq %r12 35 | pushq %r10 36 | pushq %rbp 37 | movq %rsp, %rbp 38 | subq $64, %rsp // make space for floating point regeisters and save 39 | movsd %xmm7, -8(%rbp) 40 | movsd %xmm6, -16(%rbp) 41 | movsd %xmm5, -24(%rbp) 42 | movsd %xmm4, -32(%rbp) 43 | movsd %xmm3, -40(%rbp) 44 | movsd %xmm2, -48(%rbp) 45 | movsd %xmm1, -56(%rbp) 46 | movsd %xmm0, -64(%rbp) 47 | movq 112(%rbp), %r11 // recover trampoline return address 48 | subq $4096+5, %r11 // find trampoline info relative to return address 49 | movq (%r11), %rdi // first argument is pointer to forwarding info 50 | movq 120(%rbp), %rsi // recover original return address 51 | movq %rsp, %rdx // pass through stack 52 | leaq onEntry(%rip), %r11 53 | callq *(%r11) // call tracing entry routine (saves return address) 54 | leaq returning(%rip), %r11 55 | movq %r11, 120(%rbp) // patch return address to "returning" code 56 | movq %rax, %r11 // pointer to original implementation returned 57 | movsd -64(%rbp), %xmm0 // restore all registers 58 | movsd -56(%rbp), %xmm1 59 | movsd -48(%rbp), %xmm2 60 | movsd -40(%rbp), %xmm3 61 | movsd -32(%rbp), %xmm4 62 | movsd -24(%rbp), %xmm5 63 | movsd -16(%rbp), %xmm6 64 | movsd -8(%rbp), %xmm7 65 | addq $64, %rsp 66 | popq %rbp 67 | popq %r10 68 | popq %r12 69 | popq %r13 70 | popq %r14 71 | popq %r15 72 | popq %rdi 73 | popq %rsi 74 | popq %rdx 75 | popq %rcx 76 | popq %r8 77 | popq %r9 78 | popq %rax 79 | popq %rbx 80 | addq $8, %rsp // remove trampoline return address 81 | jmpq *%r11 // forward onto original implementation 82 | 83 | returning: 84 | pushq %rbx 85 | pushq %r9 86 | pushq %r8 // push regs used for int returns 87 | pushq %rcx 88 | pushq %rdx 89 | pushq %rax // pointer for return of struct 90 | pushq %rsi 91 | pushq %rdi 92 | pushq %r15 93 | pushq %r14 94 | pushq %r13 // Swift "call context" register for self 95 | pushq %r12 96 | pushq %r10 97 | pushq %rbp 98 | movq %rsp, %rbp 99 | subq $64, %rsp // make space for floating point regeisters and save 100 | movsd %xmm7, -8(%rbp) 101 | movsd %xmm6, -16(%rbp) 102 | movsd %xmm5, -24(%rbp) 103 | movsd %xmm4, -32(%rbp) 104 | movsd %xmm3, -40(%rbp) 105 | movsd %xmm2, -48(%rbp) 106 | movsd %xmm1, -56(%rbp) 107 | movsd %xmm0, -64(%rbp) 108 | leaq onExit(%rip), %r11 109 | callq *(%r11) // call tracing exit routine 110 | movq %rax, %r11 // returns original return address 111 | movsd -64(%rbp), %xmm0 // restore all registers 112 | movsd -56(%rbp), %xmm1 113 | movsd -48(%rbp), %xmm2 114 | movsd -40(%rbp), %xmm3 115 | movsd -32(%rbp), %xmm4 116 | movsd -24(%rbp), %xmm5 117 | movsd -16(%rbp), %xmm6 118 | movsd -8(%rbp), %xmm7 119 | addq $64, %rsp 120 | popq %rbp 121 | popq %r10 122 | popq %r12 123 | popq %r13 124 | popq %r14 125 | popq %r15 126 | popq %rdi 127 | popq %rsi 128 | popq %rax 129 | popq %rdx 130 | popq %rcx 131 | popq %r8 132 | popq %r9 133 | popq %rbx 134 | pushq %r11 135 | ret // return to original caller 136 | 137 | nop 138 | nop 139 | 140 | _xt_forwarding_trampolines_start: 141 | 142 | // 469 trampoline entry points 143 | callq _xt_forwarding_trampoline 144 | nop 145 | nop 146 | nop 147 | _xt_forwarding_trampolines_next: 148 | callq _xt_forwarding_trampoline 149 | nop 150 | nop 151 | nop 152 | callq _xt_forwarding_trampoline 153 | nop 154 | nop 155 | nop 156 | callq _xt_forwarding_trampoline 157 | nop 158 | nop 159 | nop 160 | callq _xt_forwarding_trampoline 161 | nop 162 | nop 163 | nop 164 | callq _xt_forwarding_trampoline 165 | nop 166 | nop 167 | nop 168 | callq _xt_forwarding_trampoline 169 | nop 170 | nop 171 | nop 172 | callq _xt_forwarding_trampoline 173 | nop 174 | nop 175 | nop 176 | callq _xt_forwarding_trampoline 177 | nop 178 | nop 179 | nop 180 | callq _xt_forwarding_trampoline 181 | nop 182 | nop 183 | nop 184 | callq _xt_forwarding_trampoline 185 | nop 186 | nop 187 | nop 188 | callq _xt_forwarding_trampoline 189 | nop 190 | nop 191 | nop 192 | callq _xt_forwarding_trampoline 193 | nop 194 | nop 195 | nop 196 | callq _xt_forwarding_trampoline 197 | nop 198 | nop 199 | nop 200 | callq _xt_forwarding_trampoline 201 | nop 202 | nop 203 | nop 204 | callq _xt_forwarding_trampoline 205 | nop 206 | nop 207 | nop 208 | callq _xt_forwarding_trampoline 209 | nop 210 | nop 211 | nop 212 | callq _xt_forwarding_trampoline 213 | nop 214 | nop 215 | nop 216 | callq _xt_forwarding_trampoline 217 | nop 218 | nop 219 | nop 220 | callq _xt_forwarding_trampoline 221 | nop 222 | nop 223 | nop 224 | callq _xt_forwarding_trampoline 225 | nop 226 | nop 227 | nop 228 | callq _xt_forwarding_trampoline 229 | nop 230 | nop 231 | nop 232 | callq _xt_forwarding_trampoline 233 | nop 234 | nop 235 | nop 236 | callq _xt_forwarding_trampoline 237 | nop 238 | nop 239 | nop 240 | callq _xt_forwarding_trampoline 241 | nop 242 | nop 243 | nop 244 | callq _xt_forwarding_trampoline 245 | nop 246 | nop 247 | nop 248 | callq _xt_forwarding_trampoline 249 | nop 250 | nop 251 | nop 252 | callq _xt_forwarding_trampoline 253 | nop 254 | nop 255 | nop 256 | callq _xt_forwarding_trampoline 257 | nop 258 | nop 259 | nop 260 | callq _xt_forwarding_trampoline 261 | nop 262 | nop 263 | nop 264 | callq _xt_forwarding_trampoline 265 | nop 266 | nop 267 | nop 268 | callq _xt_forwarding_trampoline 269 | nop 270 | nop 271 | nop 272 | callq _xt_forwarding_trampoline 273 | nop 274 | nop 275 | nop 276 | callq _xt_forwarding_trampoline 277 | nop 278 | nop 279 | nop 280 | callq _xt_forwarding_trampoline 281 | nop 282 | nop 283 | nop 284 | callq _xt_forwarding_trampoline 285 | nop 286 | nop 287 | nop 288 | callq _xt_forwarding_trampoline 289 | nop 290 | nop 291 | nop 292 | callq _xt_forwarding_trampoline 293 | nop 294 | nop 295 | nop 296 | callq _xt_forwarding_trampoline 297 | nop 298 | nop 299 | nop 300 | callq _xt_forwarding_trampoline 301 | nop 302 | nop 303 | nop 304 | callq _xt_forwarding_trampoline 305 | nop 306 | nop 307 | nop 308 | callq _xt_forwarding_trampoline 309 | nop 310 | nop 311 | nop 312 | callq _xt_forwarding_trampoline 313 | nop 314 | nop 315 | nop 316 | callq _xt_forwarding_trampoline 317 | nop 318 | nop 319 | nop 320 | callq _xt_forwarding_trampoline 321 | nop 322 | nop 323 | nop 324 | callq _xt_forwarding_trampoline 325 | nop 326 | nop 327 | nop 328 | callq _xt_forwarding_trampoline 329 | nop 330 | nop 331 | nop 332 | callq _xt_forwarding_trampoline 333 | nop 334 | nop 335 | nop 336 | callq _xt_forwarding_trampoline 337 | nop 338 | nop 339 | nop 340 | callq _xt_forwarding_trampoline 341 | nop 342 | nop 343 | nop 344 | callq _xt_forwarding_trampoline 345 | nop 346 | nop 347 | nop 348 | callq _xt_forwarding_trampoline 349 | nop 350 | nop 351 | nop 352 | callq _xt_forwarding_trampoline 353 | nop 354 | nop 355 | nop 356 | callq _xt_forwarding_trampoline 357 | nop 358 | nop 359 | nop 360 | callq _xt_forwarding_trampoline 361 | nop 362 | nop 363 | nop 364 | callq _xt_forwarding_trampoline 365 | nop 366 | nop 367 | nop 368 | callq _xt_forwarding_trampoline 369 | nop 370 | nop 371 | nop 372 | callq _xt_forwarding_trampoline 373 | nop 374 | nop 375 | nop 376 | callq _xt_forwarding_trampoline 377 | nop 378 | nop 379 | nop 380 | callq _xt_forwarding_trampoline 381 | nop 382 | nop 383 | nop 384 | callq _xt_forwarding_trampoline 385 | nop 386 | nop 387 | nop 388 | callq _xt_forwarding_trampoline 389 | nop 390 | nop 391 | nop 392 | callq _xt_forwarding_trampoline 393 | nop 394 | nop 395 | nop 396 | callq _xt_forwarding_trampoline 397 | nop 398 | nop 399 | nop 400 | callq _xt_forwarding_trampoline 401 | nop 402 | nop 403 | nop 404 | callq _xt_forwarding_trampoline 405 | nop 406 | nop 407 | nop 408 | callq _xt_forwarding_trampoline 409 | nop 410 | nop 411 | nop 412 | callq _xt_forwarding_trampoline 413 | nop 414 | nop 415 | nop 416 | callq _xt_forwarding_trampoline 417 | nop 418 | nop 419 | nop 420 | callq _xt_forwarding_trampoline 421 | nop 422 | nop 423 | nop 424 | callq _xt_forwarding_trampoline 425 | nop 426 | nop 427 | nop 428 | callq _xt_forwarding_trampoline 429 | nop 430 | nop 431 | nop 432 | callq _xt_forwarding_trampoline 433 | nop 434 | nop 435 | nop 436 | callq _xt_forwarding_trampoline 437 | nop 438 | nop 439 | nop 440 | callq _xt_forwarding_trampoline 441 | nop 442 | nop 443 | nop 444 | callq _xt_forwarding_trampoline 445 | nop 446 | nop 447 | nop 448 | callq _xt_forwarding_trampoline 449 | nop 450 | nop 451 | nop 452 | callq _xt_forwarding_trampoline 453 | nop 454 | nop 455 | nop 456 | callq _xt_forwarding_trampoline 457 | nop 458 | nop 459 | nop 460 | callq _xt_forwarding_trampoline 461 | nop 462 | nop 463 | nop 464 | callq _xt_forwarding_trampoline 465 | nop 466 | nop 467 | nop 468 | callq _xt_forwarding_trampoline 469 | nop 470 | nop 471 | nop 472 | callq _xt_forwarding_trampoline 473 | nop 474 | nop 475 | nop 476 | callq _xt_forwarding_trampoline 477 | nop 478 | nop 479 | nop 480 | callq _xt_forwarding_trampoline 481 | nop 482 | nop 483 | nop 484 | callq _xt_forwarding_trampoline 485 | nop 486 | nop 487 | nop 488 | callq _xt_forwarding_trampoline 489 | nop 490 | nop 491 | nop 492 | callq _xt_forwarding_trampoline 493 | nop 494 | nop 495 | nop 496 | callq _xt_forwarding_trampoline 497 | nop 498 | nop 499 | nop 500 | callq _xt_forwarding_trampoline 501 | nop 502 | nop 503 | nop 504 | callq _xt_forwarding_trampoline 505 | nop 506 | nop 507 | nop 508 | callq _xt_forwarding_trampoline 509 | nop 510 | nop 511 | nop 512 | callq _xt_forwarding_trampoline 513 | nop 514 | nop 515 | nop 516 | callq _xt_forwarding_trampoline 517 | nop 518 | nop 519 | nop 520 | callq _xt_forwarding_trampoline 521 | nop 522 | nop 523 | nop 524 | callq _xt_forwarding_trampoline 525 | nop 526 | nop 527 | nop 528 | callq _xt_forwarding_trampoline 529 | nop 530 | nop 531 | nop 532 | callq _xt_forwarding_trampoline 533 | nop 534 | nop 535 | nop 536 | callq _xt_forwarding_trampoline 537 | nop 538 | nop 539 | nop 540 | callq _xt_forwarding_trampoline 541 | nop 542 | nop 543 | nop 544 | callq _xt_forwarding_trampoline 545 | nop 546 | nop 547 | nop 548 | callq _xt_forwarding_trampoline 549 | nop 550 | nop 551 | nop 552 | callq _xt_forwarding_trampoline 553 | nop 554 | nop 555 | nop 556 | callq _xt_forwarding_trampoline 557 | nop 558 | nop 559 | nop 560 | callq _xt_forwarding_trampoline 561 | nop 562 | nop 563 | nop 564 | callq _xt_forwarding_trampoline 565 | nop 566 | nop 567 | nop 568 | callq _xt_forwarding_trampoline 569 | nop 570 | nop 571 | nop 572 | callq _xt_forwarding_trampoline 573 | nop 574 | nop 575 | nop 576 | callq _xt_forwarding_trampoline 577 | nop 578 | nop 579 | nop 580 | callq _xt_forwarding_trampoline 581 | nop 582 | nop 583 | nop 584 | callq _xt_forwarding_trampoline 585 | nop 586 | nop 587 | nop 588 | callq _xt_forwarding_trampoline 589 | nop 590 | nop 591 | nop 592 | callq _xt_forwarding_trampoline 593 | nop 594 | nop 595 | nop 596 | callq _xt_forwarding_trampoline 597 | nop 598 | nop 599 | nop 600 | callq _xt_forwarding_trampoline 601 | nop 602 | nop 603 | nop 604 | callq _xt_forwarding_trampoline 605 | nop 606 | nop 607 | nop 608 | callq _xt_forwarding_trampoline 609 | nop 610 | nop 611 | nop 612 | callq _xt_forwarding_trampoline 613 | nop 614 | nop 615 | nop 616 | callq _xt_forwarding_trampoline 617 | nop 618 | nop 619 | nop 620 | callq _xt_forwarding_trampoline 621 | nop 622 | nop 623 | nop 624 | callq _xt_forwarding_trampoline 625 | nop 626 | nop 627 | nop 628 | callq _xt_forwarding_trampoline 629 | nop 630 | nop 631 | nop 632 | callq _xt_forwarding_trampoline 633 | nop 634 | nop 635 | nop 636 | callq _xt_forwarding_trampoline 637 | nop 638 | nop 639 | nop 640 | callq _xt_forwarding_trampoline 641 | nop 642 | nop 643 | nop 644 | callq _xt_forwarding_trampoline 645 | nop 646 | nop 647 | nop 648 | callq _xt_forwarding_trampoline 649 | nop 650 | nop 651 | nop 652 | callq _xt_forwarding_trampoline 653 | nop 654 | nop 655 | nop 656 | callq _xt_forwarding_trampoline 657 | nop 658 | nop 659 | nop 660 | callq _xt_forwarding_trampoline 661 | nop 662 | nop 663 | nop 664 | callq _xt_forwarding_trampoline 665 | nop 666 | nop 667 | nop 668 | callq _xt_forwarding_trampoline 669 | nop 670 | nop 671 | nop 672 | callq _xt_forwarding_trampoline 673 | nop 674 | nop 675 | nop 676 | callq _xt_forwarding_trampoline 677 | nop 678 | nop 679 | nop 680 | callq _xt_forwarding_trampoline 681 | nop 682 | nop 683 | nop 684 | callq _xt_forwarding_trampoline 685 | nop 686 | nop 687 | nop 688 | callq _xt_forwarding_trampoline 689 | nop 690 | nop 691 | nop 692 | callq _xt_forwarding_trampoline 693 | nop 694 | nop 695 | nop 696 | callq _xt_forwarding_trampoline 697 | nop 698 | nop 699 | nop 700 | callq _xt_forwarding_trampoline 701 | nop 702 | nop 703 | nop 704 | callq _xt_forwarding_trampoline 705 | nop 706 | nop 707 | nop 708 | callq _xt_forwarding_trampoline 709 | nop 710 | nop 711 | nop 712 | callq _xt_forwarding_trampoline 713 | nop 714 | nop 715 | nop 716 | callq _xt_forwarding_trampoline 717 | nop 718 | nop 719 | nop 720 | callq _xt_forwarding_trampoline 721 | nop 722 | nop 723 | nop 724 | callq _xt_forwarding_trampoline 725 | nop 726 | nop 727 | nop 728 | callq _xt_forwarding_trampoline 729 | nop 730 | nop 731 | nop 732 | callq _xt_forwarding_trampoline 733 | nop 734 | nop 735 | nop 736 | callq _xt_forwarding_trampoline 737 | nop 738 | nop 739 | nop 740 | callq _xt_forwarding_trampoline 741 | nop 742 | nop 743 | nop 744 | callq _xt_forwarding_trampoline 745 | nop 746 | nop 747 | nop 748 | callq _xt_forwarding_trampoline 749 | nop 750 | nop 751 | nop 752 | callq _xt_forwarding_trampoline 753 | nop 754 | nop 755 | nop 756 | callq _xt_forwarding_trampoline 757 | nop 758 | nop 759 | nop 760 | callq _xt_forwarding_trampoline 761 | nop 762 | nop 763 | nop 764 | callq _xt_forwarding_trampoline 765 | nop 766 | nop 767 | nop 768 | callq _xt_forwarding_trampoline 769 | nop 770 | nop 771 | nop 772 | callq _xt_forwarding_trampoline 773 | nop 774 | nop 775 | nop 776 | callq _xt_forwarding_trampoline 777 | nop 778 | nop 779 | nop 780 | callq _xt_forwarding_trampoline 781 | nop 782 | nop 783 | nop 784 | callq _xt_forwarding_trampoline 785 | nop 786 | nop 787 | nop 788 | callq _xt_forwarding_trampoline 789 | nop 790 | nop 791 | nop 792 | callq _xt_forwarding_trampoline 793 | nop 794 | nop 795 | nop 796 | callq _xt_forwarding_trampoline 797 | nop 798 | nop 799 | nop 800 | callq _xt_forwarding_trampoline 801 | nop 802 | nop 803 | nop 804 | callq _xt_forwarding_trampoline 805 | nop 806 | nop 807 | nop 808 | callq _xt_forwarding_trampoline 809 | nop 810 | nop 811 | nop 812 | callq _xt_forwarding_trampoline 813 | nop 814 | nop 815 | nop 816 | callq _xt_forwarding_trampoline 817 | nop 818 | nop 819 | nop 820 | callq _xt_forwarding_trampoline 821 | nop 822 | nop 823 | nop 824 | callq _xt_forwarding_trampoline 825 | nop 826 | nop 827 | nop 828 | callq _xt_forwarding_trampoline 829 | nop 830 | nop 831 | nop 832 | callq _xt_forwarding_trampoline 833 | nop 834 | nop 835 | nop 836 | callq _xt_forwarding_trampoline 837 | nop 838 | nop 839 | nop 840 | callq _xt_forwarding_trampoline 841 | nop 842 | nop 843 | nop 844 | callq _xt_forwarding_trampoline 845 | nop 846 | nop 847 | nop 848 | callq _xt_forwarding_trampoline 849 | nop 850 | nop 851 | nop 852 | callq _xt_forwarding_trampoline 853 | nop 854 | nop 855 | nop 856 | callq _xt_forwarding_trampoline 857 | nop 858 | nop 859 | nop 860 | callq _xt_forwarding_trampoline 861 | nop 862 | nop 863 | nop 864 | callq _xt_forwarding_trampoline 865 | nop 866 | nop 867 | nop 868 | callq _xt_forwarding_trampoline 869 | nop 870 | nop 871 | nop 872 | callq _xt_forwarding_trampoline 873 | nop 874 | nop 875 | nop 876 | callq _xt_forwarding_trampoline 877 | nop 878 | nop 879 | nop 880 | callq _xt_forwarding_trampoline 881 | nop 882 | nop 883 | nop 884 | callq _xt_forwarding_trampoline 885 | nop 886 | nop 887 | nop 888 | callq _xt_forwarding_trampoline 889 | nop 890 | nop 891 | nop 892 | callq _xt_forwarding_trampoline 893 | nop 894 | nop 895 | nop 896 | callq _xt_forwarding_trampoline 897 | nop 898 | nop 899 | nop 900 | callq _xt_forwarding_trampoline 901 | nop 902 | nop 903 | nop 904 | callq _xt_forwarding_trampoline 905 | nop 906 | nop 907 | nop 908 | callq _xt_forwarding_trampoline 909 | nop 910 | nop 911 | nop 912 | callq _xt_forwarding_trampoline 913 | nop 914 | nop 915 | nop 916 | callq _xt_forwarding_trampoline 917 | nop 918 | nop 919 | nop 920 | callq _xt_forwarding_trampoline 921 | nop 922 | nop 923 | nop 924 | callq _xt_forwarding_trampoline 925 | nop 926 | nop 927 | nop 928 | callq _xt_forwarding_trampoline 929 | nop 930 | nop 931 | nop 932 | callq _xt_forwarding_trampoline 933 | nop 934 | nop 935 | nop 936 | callq _xt_forwarding_trampoline 937 | nop 938 | nop 939 | nop 940 | callq _xt_forwarding_trampoline 941 | nop 942 | nop 943 | nop 944 | callq _xt_forwarding_trampoline 945 | nop 946 | nop 947 | nop 948 | callq _xt_forwarding_trampoline 949 | nop 950 | nop 951 | nop 952 | callq _xt_forwarding_trampoline 953 | nop 954 | nop 955 | nop 956 | callq _xt_forwarding_trampoline 957 | nop 958 | nop 959 | nop 960 | callq _xt_forwarding_trampoline 961 | nop 962 | nop 963 | nop 964 | callq _xt_forwarding_trampoline 965 | nop 966 | nop 967 | nop 968 | callq _xt_forwarding_trampoline 969 | nop 970 | nop 971 | nop 972 | callq _xt_forwarding_trampoline 973 | nop 974 | nop 975 | nop 976 | callq _xt_forwarding_trampoline 977 | nop 978 | nop 979 | nop 980 | callq _xt_forwarding_trampoline 981 | nop 982 | nop 983 | nop 984 | callq _xt_forwarding_trampoline 985 | nop 986 | nop 987 | nop 988 | callq _xt_forwarding_trampoline 989 | nop 990 | nop 991 | nop 992 | callq _xt_forwarding_trampoline 993 | nop 994 | nop 995 | nop 996 | callq _xt_forwarding_trampoline 997 | nop 998 | nop 999 | nop 1000 | callq _xt_forwarding_trampoline 1001 | nop 1002 | nop 1003 | nop 1004 | callq _xt_forwarding_trampoline 1005 | nop 1006 | nop 1007 | nop 1008 | callq _xt_forwarding_trampoline 1009 | nop 1010 | nop 1011 | nop 1012 | callq _xt_forwarding_trampoline 1013 | nop 1014 | nop 1015 | nop 1016 | callq _xt_forwarding_trampoline 1017 | nop 1018 | nop 1019 | nop 1020 | callq _xt_forwarding_trampoline 1021 | nop 1022 | nop 1023 | nop 1024 | callq _xt_forwarding_trampoline 1025 | nop 1026 | nop 1027 | nop 1028 | callq _xt_forwarding_trampoline 1029 | nop 1030 | nop 1031 | nop 1032 | callq _xt_forwarding_trampoline 1033 | nop 1034 | nop 1035 | nop 1036 | callq _xt_forwarding_trampoline 1037 | nop 1038 | nop 1039 | nop 1040 | callq _xt_forwarding_trampoline 1041 | nop 1042 | nop 1043 | nop 1044 | callq _xt_forwarding_trampoline 1045 | nop 1046 | nop 1047 | nop 1048 | callq _xt_forwarding_trampoline 1049 | nop 1050 | nop 1051 | nop 1052 | callq _xt_forwarding_trampoline 1053 | nop 1054 | nop 1055 | nop 1056 | callq _xt_forwarding_trampoline 1057 | nop 1058 | nop 1059 | nop 1060 | callq _xt_forwarding_trampoline 1061 | nop 1062 | nop 1063 | nop 1064 | callq _xt_forwarding_trampoline 1065 | nop 1066 | nop 1067 | nop 1068 | callq _xt_forwarding_trampoline 1069 | nop 1070 | nop 1071 | nop 1072 | callq _xt_forwarding_trampoline 1073 | nop 1074 | nop 1075 | nop 1076 | callq _xt_forwarding_trampoline 1077 | nop 1078 | nop 1079 | nop 1080 | callq _xt_forwarding_trampoline 1081 | nop 1082 | nop 1083 | nop 1084 | callq _xt_forwarding_trampoline 1085 | nop 1086 | nop 1087 | nop 1088 | callq _xt_forwarding_trampoline 1089 | nop 1090 | nop 1091 | nop 1092 | callq _xt_forwarding_trampoline 1093 | nop 1094 | nop 1095 | nop 1096 | callq _xt_forwarding_trampoline 1097 | nop 1098 | nop 1099 | nop 1100 | callq _xt_forwarding_trampoline 1101 | nop 1102 | nop 1103 | nop 1104 | callq _xt_forwarding_trampoline 1105 | nop 1106 | nop 1107 | nop 1108 | callq _xt_forwarding_trampoline 1109 | nop 1110 | nop 1111 | nop 1112 | callq _xt_forwarding_trampoline 1113 | nop 1114 | nop 1115 | nop 1116 | callq _xt_forwarding_trampoline 1117 | nop 1118 | nop 1119 | nop 1120 | callq _xt_forwarding_trampoline 1121 | nop 1122 | nop 1123 | nop 1124 | callq _xt_forwarding_trampoline 1125 | nop 1126 | nop 1127 | nop 1128 | callq _xt_forwarding_trampoline 1129 | nop 1130 | nop 1131 | nop 1132 | callq _xt_forwarding_trampoline 1133 | nop 1134 | nop 1135 | nop 1136 | callq _xt_forwarding_trampoline 1137 | nop 1138 | nop 1139 | nop 1140 | callq _xt_forwarding_trampoline 1141 | nop 1142 | nop 1143 | nop 1144 | callq _xt_forwarding_trampoline 1145 | nop 1146 | nop 1147 | nop 1148 | callq _xt_forwarding_trampoline 1149 | nop 1150 | nop 1151 | nop 1152 | callq _xt_forwarding_trampoline 1153 | nop 1154 | nop 1155 | nop 1156 | callq _xt_forwarding_trampoline 1157 | nop 1158 | nop 1159 | nop 1160 | callq _xt_forwarding_trampoline 1161 | nop 1162 | nop 1163 | nop 1164 | callq _xt_forwarding_trampoline 1165 | nop 1166 | nop 1167 | nop 1168 | callq _xt_forwarding_trampoline 1169 | nop 1170 | nop 1171 | nop 1172 | callq _xt_forwarding_trampoline 1173 | nop 1174 | nop 1175 | nop 1176 | callq _xt_forwarding_trampoline 1177 | nop 1178 | nop 1179 | nop 1180 | callq _xt_forwarding_trampoline 1181 | nop 1182 | nop 1183 | nop 1184 | callq _xt_forwarding_trampoline 1185 | nop 1186 | nop 1187 | nop 1188 | callq _xt_forwarding_trampoline 1189 | nop 1190 | nop 1191 | nop 1192 | callq _xt_forwarding_trampoline 1193 | nop 1194 | nop 1195 | nop 1196 | callq _xt_forwarding_trampoline 1197 | nop 1198 | nop 1199 | nop 1200 | callq _xt_forwarding_trampoline 1201 | nop 1202 | nop 1203 | nop 1204 | callq _xt_forwarding_trampoline 1205 | nop 1206 | nop 1207 | nop 1208 | callq _xt_forwarding_trampoline 1209 | nop 1210 | nop 1211 | nop 1212 | callq _xt_forwarding_trampoline 1213 | nop 1214 | nop 1215 | nop 1216 | callq _xt_forwarding_trampoline 1217 | nop 1218 | nop 1219 | nop 1220 | callq _xt_forwarding_trampoline 1221 | nop 1222 | nop 1223 | nop 1224 | callq _xt_forwarding_trampoline 1225 | nop 1226 | nop 1227 | nop 1228 | callq _xt_forwarding_trampoline 1229 | nop 1230 | nop 1231 | nop 1232 | callq _xt_forwarding_trampoline 1233 | nop 1234 | nop 1235 | nop 1236 | callq _xt_forwarding_trampoline 1237 | nop 1238 | nop 1239 | nop 1240 | callq _xt_forwarding_trampoline 1241 | nop 1242 | nop 1243 | nop 1244 | callq _xt_forwarding_trampoline 1245 | nop 1246 | nop 1247 | nop 1248 | callq _xt_forwarding_trampoline 1249 | nop 1250 | nop 1251 | nop 1252 | callq _xt_forwarding_trampoline 1253 | nop 1254 | nop 1255 | nop 1256 | callq _xt_forwarding_trampoline 1257 | nop 1258 | nop 1259 | nop 1260 | callq _xt_forwarding_trampoline 1261 | nop 1262 | nop 1263 | nop 1264 | callq _xt_forwarding_trampoline 1265 | nop 1266 | nop 1267 | nop 1268 | callq _xt_forwarding_trampoline 1269 | nop 1270 | nop 1271 | nop 1272 | callq _xt_forwarding_trampoline 1273 | nop 1274 | nop 1275 | nop 1276 | callq _xt_forwarding_trampoline 1277 | nop 1278 | nop 1279 | nop 1280 | callq _xt_forwarding_trampoline 1281 | nop 1282 | nop 1283 | nop 1284 | callq _xt_forwarding_trampoline 1285 | nop 1286 | nop 1287 | nop 1288 | callq _xt_forwarding_trampoline 1289 | nop 1290 | nop 1291 | nop 1292 | callq _xt_forwarding_trampoline 1293 | nop 1294 | nop 1295 | nop 1296 | callq _xt_forwarding_trampoline 1297 | nop 1298 | nop 1299 | nop 1300 | callq _xt_forwarding_trampoline 1301 | nop 1302 | nop 1303 | nop 1304 | callq _xt_forwarding_trampoline 1305 | nop 1306 | nop 1307 | nop 1308 | callq _xt_forwarding_trampoline 1309 | nop 1310 | nop 1311 | nop 1312 | callq _xt_forwarding_trampoline 1313 | nop 1314 | nop 1315 | nop 1316 | callq _xt_forwarding_trampoline 1317 | nop 1318 | nop 1319 | nop 1320 | callq _xt_forwarding_trampoline 1321 | nop 1322 | nop 1323 | nop 1324 | callq _xt_forwarding_trampoline 1325 | nop 1326 | nop 1327 | nop 1328 | callq _xt_forwarding_trampoline 1329 | nop 1330 | nop 1331 | nop 1332 | callq _xt_forwarding_trampoline 1333 | nop 1334 | nop 1335 | nop 1336 | callq _xt_forwarding_trampoline 1337 | nop 1338 | nop 1339 | nop 1340 | callq _xt_forwarding_trampoline 1341 | nop 1342 | nop 1343 | nop 1344 | callq _xt_forwarding_trampoline 1345 | nop 1346 | nop 1347 | nop 1348 | callq _xt_forwarding_trampoline 1349 | nop 1350 | nop 1351 | nop 1352 | callq _xt_forwarding_trampoline 1353 | nop 1354 | nop 1355 | nop 1356 | callq _xt_forwarding_trampoline 1357 | nop 1358 | nop 1359 | nop 1360 | callq _xt_forwarding_trampoline 1361 | nop 1362 | nop 1363 | nop 1364 | callq _xt_forwarding_trampoline 1365 | nop 1366 | nop 1367 | nop 1368 | callq _xt_forwarding_trampoline 1369 | nop 1370 | nop 1371 | nop 1372 | callq _xt_forwarding_trampoline 1373 | nop 1374 | nop 1375 | nop 1376 | callq _xt_forwarding_trampoline 1377 | nop 1378 | nop 1379 | nop 1380 | callq _xt_forwarding_trampoline 1381 | nop 1382 | nop 1383 | nop 1384 | callq _xt_forwarding_trampoline 1385 | nop 1386 | nop 1387 | nop 1388 | callq _xt_forwarding_trampoline 1389 | nop 1390 | nop 1391 | nop 1392 | callq _xt_forwarding_trampoline 1393 | nop 1394 | nop 1395 | nop 1396 | callq _xt_forwarding_trampoline 1397 | nop 1398 | nop 1399 | nop 1400 | callq _xt_forwarding_trampoline 1401 | nop 1402 | nop 1403 | nop 1404 | callq _xt_forwarding_trampoline 1405 | nop 1406 | nop 1407 | nop 1408 | callq _xt_forwarding_trampoline 1409 | nop 1410 | nop 1411 | nop 1412 | callq _xt_forwarding_trampoline 1413 | nop 1414 | nop 1415 | nop 1416 | callq _xt_forwarding_trampoline 1417 | nop 1418 | nop 1419 | nop 1420 | callq _xt_forwarding_trampoline 1421 | nop 1422 | nop 1423 | nop 1424 | callq _xt_forwarding_trampoline 1425 | nop 1426 | nop 1427 | nop 1428 | callq _xt_forwarding_trampoline 1429 | nop 1430 | nop 1431 | nop 1432 | callq _xt_forwarding_trampoline 1433 | nop 1434 | nop 1435 | nop 1436 | callq _xt_forwarding_trampoline 1437 | nop 1438 | nop 1439 | nop 1440 | callq _xt_forwarding_trampoline 1441 | nop 1442 | nop 1443 | nop 1444 | callq _xt_forwarding_trampoline 1445 | nop 1446 | nop 1447 | nop 1448 | callq _xt_forwarding_trampoline 1449 | nop 1450 | nop 1451 | nop 1452 | callq _xt_forwarding_trampoline 1453 | nop 1454 | nop 1455 | nop 1456 | callq _xt_forwarding_trampoline 1457 | nop 1458 | nop 1459 | nop 1460 | callq _xt_forwarding_trampoline 1461 | nop 1462 | nop 1463 | nop 1464 | callq _xt_forwarding_trampoline 1465 | nop 1466 | nop 1467 | nop 1468 | callq _xt_forwarding_trampoline 1469 | nop 1470 | nop 1471 | nop 1472 | callq _xt_forwarding_trampoline 1473 | nop 1474 | nop 1475 | nop 1476 | callq _xt_forwarding_trampoline 1477 | nop 1478 | nop 1479 | nop 1480 | callq _xt_forwarding_trampoline 1481 | nop 1482 | nop 1483 | nop 1484 | callq _xt_forwarding_trampoline 1485 | nop 1486 | nop 1487 | nop 1488 | callq _xt_forwarding_trampoline 1489 | nop 1490 | nop 1491 | nop 1492 | callq _xt_forwarding_trampoline 1493 | nop 1494 | nop 1495 | nop 1496 | callq _xt_forwarding_trampoline 1497 | nop 1498 | nop 1499 | nop 1500 | callq _xt_forwarding_trampoline 1501 | nop 1502 | nop 1503 | nop 1504 | callq _xt_forwarding_trampoline 1505 | nop 1506 | nop 1507 | nop 1508 | callq _xt_forwarding_trampoline 1509 | nop 1510 | nop 1511 | nop 1512 | callq _xt_forwarding_trampoline 1513 | nop 1514 | nop 1515 | nop 1516 | callq _xt_forwarding_trampoline 1517 | nop 1518 | nop 1519 | nop 1520 | callq _xt_forwarding_trampoline 1521 | nop 1522 | nop 1523 | nop 1524 | callq _xt_forwarding_trampoline 1525 | nop 1526 | nop 1527 | nop 1528 | callq _xt_forwarding_trampoline 1529 | nop 1530 | nop 1531 | nop 1532 | callq _xt_forwarding_trampoline 1533 | nop 1534 | nop 1535 | nop 1536 | callq _xt_forwarding_trampoline 1537 | nop 1538 | nop 1539 | nop 1540 | callq _xt_forwarding_trampoline 1541 | nop 1542 | nop 1543 | nop 1544 | callq _xt_forwarding_trampoline 1545 | nop 1546 | nop 1547 | nop 1548 | callq _xt_forwarding_trampoline 1549 | nop 1550 | nop 1551 | nop 1552 | callq _xt_forwarding_trampoline 1553 | nop 1554 | nop 1555 | nop 1556 | callq _xt_forwarding_trampoline 1557 | nop 1558 | nop 1559 | nop 1560 | callq _xt_forwarding_trampoline 1561 | nop 1562 | nop 1563 | nop 1564 | callq _xt_forwarding_trampoline 1565 | nop 1566 | nop 1567 | nop 1568 | callq _xt_forwarding_trampoline 1569 | nop 1570 | nop 1571 | nop 1572 | callq _xt_forwarding_trampoline 1573 | nop 1574 | nop 1575 | nop 1576 | callq _xt_forwarding_trampoline 1577 | nop 1578 | nop 1579 | nop 1580 | callq _xt_forwarding_trampoline 1581 | nop 1582 | nop 1583 | nop 1584 | callq _xt_forwarding_trampoline 1585 | nop 1586 | nop 1587 | nop 1588 | callq _xt_forwarding_trampoline 1589 | nop 1590 | nop 1591 | nop 1592 | callq _xt_forwarding_trampoline 1593 | nop 1594 | nop 1595 | nop 1596 | callq _xt_forwarding_trampoline 1597 | nop 1598 | nop 1599 | nop 1600 | callq _xt_forwarding_trampoline 1601 | nop 1602 | nop 1603 | nop 1604 | callq _xt_forwarding_trampoline 1605 | nop 1606 | nop 1607 | nop 1608 | callq _xt_forwarding_trampoline 1609 | nop 1610 | nop 1611 | nop 1612 | callq _xt_forwarding_trampoline 1613 | nop 1614 | nop 1615 | nop 1616 | callq _xt_forwarding_trampoline 1617 | nop 1618 | nop 1619 | nop 1620 | callq _xt_forwarding_trampoline 1621 | nop 1622 | nop 1623 | nop 1624 | callq _xt_forwarding_trampoline 1625 | nop 1626 | nop 1627 | nop 1628 | callq _xt_forwarding_trampoline 1629 | nop 1630 | nop 1631 | nop 1632 | callq _xt_forwarding_trampoline 1633 | nop 1634 | nop 1635 | nop 1636 | callq _xt_forwarding_trampoline 1637 | nop 1638 | nop 1639 | nop 1640 | callq _xt_forwarding_trampoline 1641 | nop 1642 | nop 1643 | nop 1644 | callq _xt_forwarding_trampoline 1645 | nop 1646 | nop 1647 | nop 1648 | callq _xt_forwarding_trampoline 1649 | nop 1650 | nop 1651 | nop 1652 | callq _xt_forwarding_trampoline 1653 | nop 1654 | nop 1655 | nop 1656 | callq _xt_forwarding_trampoline 1657 | nop 1658 | nop 1659 | nop 1660 | callq _xt_forwarding_trampoline 1661 | nop 1662 | nop 1663 | nop 1664 | callq _xt_forwarding_trampoline 1665 | nop 1666 | nop 1667 | nop 1668 | callq _xt_forwarding_trampoline 1669 | nop 1670 | nop 1671 | nop 1672 | callq _xt_forwarding_trampoline 1673 | nop 1674 | nop 1675 | nop 1676 | callq _xt_forwarding_trampoline 1677 | nop 1678 | nop 1679 | nop 1680 | callq _xt_forwarding_trampoline 1681 | nop 1682 | nop 1683 | nop 1684 | callq _xt_forwarding_trampoline 1685 | nop 1686 | nop 1687 | nop 1688 | callq _xt_forwarding_trampoline 1689 | nop 1690 | nop 1691 | nop 1692 | callq _xt_forwarding_trampoline 1693 | nop 1694 | nop 1695 | nop 1696 | callq _xt_forwarding_trampoline 1697 | nop 1698 | nop 1699 | nop 1700 | callq _xt_forwarding_trampoline 1701 | nop 1702 | nop 1703 | nop 1704 | callq _xt_forwarding_trampoline 1705 | nop 1706 | nop 1707 | nop 1708 | callq _xt_forwarding_trampoline 1709 | nop 1710 | nop 1711 | nop 1712 | callq _xt_forwarding_trampoline 1713 | nop 1714 | nop 1715 | nop 1716 | callq _xt_forwarding_trampoline 1717 | nop 1718 | nop 1719 | nop 1720 | callq _xt_forwarding_trampoline 1721 | nop 1722 | nop 1723 | nop 1724 | callq _xt_forwarding_trampoline 1725 | nop 1726 | nop 1727 | nop 1728 | callq _xt_forwarding_trampoline 1729 | nop 1730 | nop 1731 | nop 1732 | callq _xt_forwarding_trampoline 1733 | nop 1734 | nop 1735 | nop 1736 | callq _xt_forwarding_trampoline 1737 | nop 1738 | nop 1739 | nop 1740 | callq _xt_forwarding_trampoline 1741 | nop 1742 | nop 1743 | nop 1744 | callq _xt_forwarding_trampoline 1745 | nop 1746 | nop 1747 | nop 1748 | callq _xt_forwarding_trampoline 1749 | nop 1750 | nop 1751 | nop 1752 | callq _xt_forwarding_trampoline 1753 | nop 1754 | nop 1755 | nop 1756 | callq _xt_forwarding_trampoline 1757 | nop 1758 | nop 1759 | nop 1760 | callq _xt_forwarding_trampoline 1761 | nop 1762 | nop 1763 | nop 1764 | callq _xt_forwarding_trampoline 1765 | nop 1766 | nop 1767 | nop 1768 | callq _xt_forwarding_trampoline 1769 | nop 1770 | nop 1771 | nop 1772 | callq _xt_forwarding_trampoline 1773 | nop 1774 | nop 1775 | nop 1776 | callq _xt_forwarding_trampoline 1777 | nop 1778 | nop 1779 | nop 1780 | callq _xt_forwarding_trampoline 1781 | nop 1782 | nop 1783 | nop 1784 | callq _xt_forwarding_trampoline 1785 | nop 1786 | nop 1787 | nop 1788 | callq _xt_forwarding_trampoline 1789 | nop 1790 | nop 1791 | nop 1792 | callq _xt_forwarding_trampoline 1793 | nop 1794 | nop 1795 | nop 1796 | callq _xt_forwarding_trampoline 1797 | nop 1798 | nop 1799 | nop 1800 | callq _xt_forwarding_trampoline 1801 | nop 1802 | nop 1803 | nop 1804 | callq _xt_forwarding_trampoline 1805 | nop 1806 | nop 1807 | nop 1808 | callq _xt_forwarding_trampoline 1809 | nop 1810 | nop 1811 | nop 1812 | callq _xt_forwarding_trampoline 1813 | nop 1814 | nop 1815 | nop 1816 | callq _xt_forwarding_trampoline 1817 | nop 1818 | nop 1819 | nop 1820 | callq _xt_forwarding_trampoline 1821 | nop 1822 | nop 1823 | nop 1824 | callq _xt_forwarding_trampoline 1825 | nop 1826 | nop 1827 | nop 1828 | callq _xt_forwarding_trampoline 1829 | nop 1830 | nop 1831 | nop 1832 | callq _xt_forwarding_trampoline 1833 | nop 1834 | nop 1835 | nop 1836 | callq _xt_forwarding_trampoline 1837 | nop 1838 | nop 1839 | nop 1840 | callq _xt_forwarding_trampoline 1841 | nop 1842 | nop 1843 | nop 1844 | callq _xt_forwarding_trampoline 1845 | nop 1846 | nop 1847 | nop 1848 | callq _xt_forwarding_trampoline 1849 | nop 1850 | nop 1851 | nop 1852 | callq _xt_forwarding_trampoline 1853 | nop 1854 | nop 1855 | nop 1856 | callq _xt_forwarding_trampoline 1857 | nop 1858 | nop 1859 | nop 1860 | callq _xt_forwarding_trampoline 1861 | nop 1862 | nop 1863 | nop 1864 | callq _xt_forwarding_trampoline 1865 | nop 1866 | nop 1867 | nop 1868 | callq _xt_forwarding_trampoline 1869 | nop 1870 | nop 1871 | nop 1872 | callq _xt_forwarding_trampoline 1873 | nop 1874 | nop 1875 | nop 1876 | callq _xt_forwarding_trampoline 1877 | nop 1878 | nop 1879 | nop 1880 | callq _xt_forwarding_trampoline 1881 | nop 1882 | nop 1883 | nop 1884 | callq _xt_forwarding_trampoline 1885 | nop 1886 | nop 1887 | nop 1888 | callq _xt_forwarding_trampoline 1889 | nop 1890 | nop 1891 | nop 1892 | callq _xt_forwarding_trampoline 1893 | nop 1894 | nop 1895 | nop 1896 | callq _xt_forwarding_trampoline 1897 | nop 1898 | nop 1899 | nop 1900 | callq _xt_forwarding_trampoline 1901 | nop 1902 | nop 1903 | nop 1904 | callq _xt_forwarding_trampoline 1905 | nop 1906 | nop 1907 | nop 1908 | callq _xt_forwarding_trampoline 1909 | nop 1910 | nop 1911 | nop 1912 | callq _xt_forwarding_trampoline 1913 | nop 1914 | nop 1915 | nop 1916 | callq _xt_forwarding_trampoline 1917 | nop 1918 | nop 1919 | nop 1920 | callq _xt_forwarding_trampoline 1921 | nop 1922 | nop 1923 | nop 1924 | callq _xt_forwarding_trampoline 1925 | nop 1926 | nop 1927 | nop 1928 | callq _xt_forwarding_trampoline 1929 | nop 1930 | nop 1931 | nop 1932 | callq _xt_forwarding_trampoline 1933 | nop 1934 | nop 1935 | nop 1936 | callq _xt_forwarding_trampoline 1937 | nop 1938 | nop 1939 | nop 1940 | callq _xt_forwarding_trampoline 1941 | nop 1942 | nop 1943 | nop 1944 | callq _xt_forwarding_trampoline 1945 | nop 1946 | nop 1947 | nop 1948 | callq _xt_forwarding_trampoline 1949 | nop 1950 | nop 1951 | nop 1952 | callq _xt_forwarding_trampoline 1953 | nop 1954 | nop 1955 | nop 1956 | callq _xt_forwarding_trampoline 1957 | nop 1958 | nop 1959 | nop 1960 | callq _xt_forwarding_trampoline 1961 | nop 1962 | nop 1963 | nop 1964 | callq _xt_forwarding_trampoline 1965 | nop 1966 | nop 1967 | nop 1968 | callq _xt_forwarding_trampoline 1969 | nop 1970 | nop 1971 | nop 1972 | callq _xt_forwarding_trampoline 1973 | nop 1974 | nop 1975 | nop 1976 | callq _xt_forwarding_trampoline 1977 | nop 1978 | nop 1979 | nop 1980 | callq _xt_forwarding_trampoline 1981 | nop 1982 | nop 1983 | nop 1984 | callq _xt_forwarding_trampoline 1985 | nop 1986 | nop 1987 | nop 1988 | callq _xt_forwarding_trampoline 1989 | nop 1990 | nop 1991 | nop 1992 | callq _xt_forwarding_trampoline 1993 | nop 1994 | nop 1995 | nop 1996 | callq _xt_forwarding_trampoline 1997 | nop 1998 | nop 1999 | nop 2000 | callq _xt_forwarding_trampoline 2001 | nop 2002 | nop 2003 | nop 2004 | callq _xt_forwarding_trampoline 2005 | nop 2006 | nop 2007 | nop 2008 | callq _xt_forwarding_trampoline 2009 | nop 2010 | nop 2011 | nop 2012 | callq _xt_forwarding_trampoline 2013 | nop 2014 | nop 2015 | nop 2016 | callq _xt_forwarding_trampoline 2017 | nop 2018 | nop 2019 | nop 2020 | callq _xt_forwarding_trampoline 2021 | nop 2022 | nop 2023 | nop 2024 | _xt_forwarding_trampolines_end: 2025 | 2026 | #endif 2027 | -------------------------------------------------------------------------------- /PerformanceMonitor/MethodTimeMonitor/xt_forwarding_trampoline_x86.s: -------------------------------------------------------------------------------- 1 | 2 | // $Id: //depot/SwiftTrace/SwiftTrace/xt_forwarding_trampoline_x86.s#4 $ 3 | 4 | // This architecture is no longer supported 5 | 6 | #if defined(__i386__) 7 | .text 8 | .align 12 9 | .globl _xt_forwarding_trampoline_page 10 | .globl _xt_forwarding_trampolines_start 11 | .globl _xt_forwarding_trampolines_next 12 | .globl _xt_forwarding_trampolines_end 13 | 14 | _xt_forwarding_trampoline_page: 15 | _xt_forwarding_trampoline: 16 | popl %eax // pop saved pc (address of first of the three nops) 17 | pushl %ebp // save frame pointer 18 | movl %esp, %ebp // set up new frame 19 | subl $4096+5, %eax // offset address by one page and the length of the call instrux 20 | pushl %eax // save pointer to trampoline data (func+data) 21 | movl 4(%eax), %eax 22 | pushl %eax // save pointer to user data 23 | movl 4(%esp), %eax // fetch pointer to C aspect handler 24 | call *(%eax) // call trace handler 25 | popl %ebp 26 | popl %ebp 27 | popl %ebp // restore frame pointer 28 | jmpl *%eax // pass on to original implementation 29 | nop 30 | nop 31 | nop 32 | nop 33 | nop 34 | nop 35 | nop 36 | 37 | _xt_forwarding_trampolines_start: 38 | // 508 trampoline entry points 39 | call _xt_forwarding_trampoline 40 | nop 41 | nop 42 | nop 43 | _xt_forwarding_trampolines_next: 44 | call _xt_forwarding_trampoline 45 | nop 46 | nop 47 | nop 48 | call _xt_forwarding_trampoline 49 | nop 50 | nop 51 | nop 52 | call _xt_forwarding_trampoline 53 | nop 54 | nop 55 | nop 56 | call _xt_forwarding_trampoline 57 | nop 58 | nop 59 | nop 60 | call _xt_forwarding_trampoline 61 | nop 62 | nop 63 | nop 64 | call _xt_forwarding_trampoline 65 | nop 66 | nop 67 | nop 68 | call _xt_forwarding_trampoline 69 | nop 70 | nop 71 | nop 72 | call _xt_forwarding_trampoline 73 | nop 74 | nop 75 | nop 76 | call _xt_forwarding_trampoline 77 | nop 78 | nop 79 | nop 80 | call _xt_forwarding_trampoline 81 | nop 82 | nop 83 | nop 84 | call _xt_forwarding_trampoline 85 | nop 86 | nop 87 | nop 88 | call _xt_forwarding_trampoline 89 | nop 90 | nop 91 | nop 92 | call _xt_forwarding_trampoline 93 | nop 94 | nop 95 | nop 96 | call _xt_forwarding_trampoline 97 | nop 98 | nop 99 | nop 100 | call _xt_forwarding_trampoline 101 | nop 102 | nop 103 | nop 104 | call _xt_forwarding_trampoline 105 | nop 106 | nop 107 | nop 108 | call _xt_forwarding_trampoline 109 | nop 110 | nop 111 | nop 112 | call _xt_forwarding_trampoline 113 | nop 114 | nop 115 | nop 116 | call _xt_forwarding_trampoline 117 | nop 118 | nop 119 | nop 120 | call _xt_forwarding_trampoline 121 | nop 122 | nop 123 | nop 124 | call _xt_forwarding_trampoline 125 | nop 126 | nop 127 | nop 128 | call _xt_forwarding_trampoline 129 | nop 130 | nop 131 | nop 132 | call _xt_forwarding_trampoline 133 | nop 134 | nop 135 | nop 136 | call _xt_forwarding_trampoline 137 | nop 138 | nop 139 | nop 140 | call _xt_forwarding_trampoline 141 | nop 142 | nop 143 | nop 144 | call _xt_forwarding_trampoline 145 | nop 146 | nop 147 | nop 148 | call _xt_forwarding_trampoline 149 | nop 150 | nop 151 | nop 152 | call _xt_forwarding_trampoline 153 | nop 154 | nop 155 | nop 156 | call _xt_forwarding_trampoline 157 | nop 158 | nop 159 | nop 160 | call _xt_forwarding_trampoline 161 | nop 162 | nop 163 | nop 164 | call _xt_forwarding_trampoline 165 | nop 166 | nop 167 | nop 168 | call _xt_forwarding_trampoline 169 | nop 170 | nop 171 | nop 172 | call _xt_forwarding_trampoline 173 | nop 174 | nop 175 | nop 176 | call _xt_forwarding_trampoline 177 | nop 178 | nop 179 | nop 180 | call _xt_forwarding_trampoline 181 | nop 182 | nop 183 | nop 184 | call _xt_forwarding_trampoline 185 | nop 186 | nop 187 | nop 188 | call _xt_forwarding_trampoline 189 | nop 190 | nop 191 | nop 192 | call _xt_forwarding_trampoline 193 | nop 194 | nop 195 | nop 196 | call _xt_forwarding_trampoline 197 | nop 198 | nop 199 | nop 200 | call _xt_forwarding_trampoline 201 | nop 202 | nop 203 | nop 204 | call _xt_forwarding_trampoline 205 | nop 206 | nop 207 | nop 208 | call _xt_forwarding_trampoline 209 | nop 210 | nop 211 | nop 212 | call _xt_forwarding_trampoline 213 | nop 214 | nop 215 | nop 216 | call _xt_forwarding_trampoline 217 | nop 218 | nop 219 | nop 220 | call _xt_forwarding_trampoline 221 | nop 222 | nop 223 | nop 224 | call _xt_forwarding_trampoline 225 | nop 226 | nop 227 | nop 228 | call _xt_forwarding_trampoline 229 | nop 230 | nop 231 | nop 232 | call _xt_forwarding_trampoline 233 | nop 234 | nop 235 | nop 236 | call _xt_forwarding_trampoline 237 | nop 238 | nop 239 | nop 240 | call _xt_forwarding_trampoline 241 | nop 242 | nop 243 | nop 244 | call _xt_forwarding_trampoline 245 | nop 246 | nop 247 | nop 248 | call _xt_forwarding_trampoline 249 | nop 250 | nop 251 | nop 252 | call _xt_forwarding_trampoline 253 | nop 254 | nop 255 | nop 256 | call _xt_forwarding_trampoline 257 | nop 258 | nop 259 | nop 260 | call _xt_forwarding_trampoline 261 | nop 262 | nop 263 | nop 264 | call _xt_forwarding_trampoline 265 | nop 266 | nop 267 | nop 268 | call _xt_forwarding_trampoline 269 | nop 270 | nop 271 | nop 272 | call _xt_forwarding_trampoline 273 | nop 274 | nop 275 | nop 276 | call _xt_forwarding_trampoline 277 | nop 278 | nop 279 | nop 280 | call _xt_forwarding_trampoline 281 | nop 282 | nop 283 | nop 284 | call _xt_forwarding_trampoline 285 | nop 286 | nop 287 | nop 288 | call _xt_forwarding_trampoline 289 | nop 290 | nop 291 | nop 292 | call _xt_forwarding_trampoline 293 | nop 294 | nop 295 | nop 296 | call _xt_forwarding_trampoline 297 | nop 298 | nop 299 | nop 300 | call _xt_forwarding_trampoline 301 | nop 302 | nop 303 | nop 304 | call _xt_forwarding_trampoline 305 | nop 306 | nop 307 | nop 308 | call _xt_forwarding_trampoline 309 | nop 310 | nop 311 | nop 312 | call _xt_forwarding_trampoline 313 | nop 314 | nop 315 | nop 316 | call _xt_forwarding_trampoline 317 | nop 318 | nop 319 | nop 320 | call _xt_forwarding_trampoline 321 | nop 322 | nop 323 | nop 324 | call _xt_forwarding_trampoline 325 | nop 326 | nop 327 | nop 328 | call _xt_forwarding_trampoline 329 | nop 330 | nop 331 | nop 332 | call _xt_forwarding_trampoline 333 | nop 334 | nop 335 | nop 336 | call _xt_forwarding_trampoline 337 | nop 338 | nop 339 | nop 340 | call _xt_forwarding_trampoline 341 | nop 342 | nop 343 | nop 344 | call _xt_forwarding_trampoline 345 | nop 346 | nop 347 | nop 348 | call _xt_forwarding_trampoline 349 | nop 350 | nop 351 | nop 352 | call _xt_forwarding_trampoline 353 | nop 354 | nop 355 | nop 356 | call _xt_forwarding_trampoline 357 | nop 358 | nop 359 | nop 360 | call _xt_forwarding_trampoline 361 | nop 362 | nop 363 | nop 364 | call _xt_forwarding_trampoline 365 | nop 366 | nop 367 | nop 368 | call _xt_forwarding_trampoline 369 | nop 370 | nop 371 | nop 372 | call _xt_forwarding_trampoline 373 | nop 374 | nop 375 | nop 376 | call _xt_forwarding_trampoline 377 | nop 378 | nop 379 | nop 380 | call _xt_forwarding_trampoline 381 | nop 382 | nop 383 | nop 384 | call _xt_forwarding_trampoline 385 | nop 386 | nop 387 | nop 388 | call _xt_forwarding_trampoline 389 | nop 390 | nop 391 | nop 392 | call _xt_forwarding_trampoline 393 | nop 394 | nop 395 | nop 396 | call _xt_forwarding_trampoline 397 | nop 398 | nop 399 | nop 400 | call _xt_forwarding_trampoline 401 | nop 402 | nop 403 | nop 404 | call _xt_forwarding_trampoline 405 | nop 406 | nop 407 | nop 408 | call _xt_forwarding_trampoline 409 | nop 410 | nop 411 | nop 412 | call _xt_forwarding_trampoline 413 | nop 414 | nop 415 | nop 416 | call _xt_forwarding_trampoline 417 | nop 418 | nop 419 | nop 420 | call _xt_forwarding_trampoline 421 | nop 422 | nop 423 | nop 424 | call _xt_forwarding_trampoline 425 | nop 426 | nop 427 | nop 428 | call _xt_forwarding_trampoline 429 | nop 430 | nop 431 | nop 432 | call _xt_forwarding_trampoline 433 | nop 434 | nop 435 | nop 436 | call _xt_forwarding_trampoline 437 | nop 438 | nop 439 | nop 440 | call _xt_forwarding_trampoline 441 | nop 442 | nop 443 | nop 444 | call _xt_forwarding_trampoline 445 | nop 446 | nop 447 | nop 448 | call _xt_forwarding_trampoline 449 | nop 450 | nop 451 | nop 452 | call _xt_forwarding_trampoline 453 | nop 454 | nop 455 | nop 456 | call _xt_forwarding_trampoline 457 | nop 458 | nop 459 | nop 460 | call _xt_forwarding_trampoline 461 | nop 462 | nop 463 | nop 464 | call _xt_forwarding_trampoline 465 | nop 466 | nop 467 | nop 468 | call _xt_forwarding_trampoline 469 | nop 470 | nop 471 | nop 472 | call _xt_forwarding_trampoline 473 | nop 474 | nop 475 | nop 476 | call _xt_forwarding_trampoline 477 | nop 478 | nop 479 | nop 480 | call _xt_forwarding_trampoline 481 | nop 482 | nop 483 | nop 484 | call _xt_forwarding_trampoline 485 | nop 486 | nop 487 | nop 488 | call _xt_forwarding_trampoline 489 | nop 490 | nop 491 | nop 492 | call _xt_forwarding_trampoline 493 | nop 494 | nop 495 | nop 496 | call _xt_forwarding_trampoline 497 | nop 498 | nop 499 | nop 500 | call _xt_forwarding_trampoline 501 | nop 502 | nop 503 | nop 504 | call _xt_forwarding_trampoline 505 | nop 506 | nop 507 | nop 508 | call _xt_forwarding_trampoline 509 | nop 510 | nop 511 | nop 512 | call _xt_forwarding_trampoline 513 | nop 514 | nop 515 | nop 516 | call _xt_forwarding_trampoline 517 | nop 518 | nop 519 | nop 520 | call _xt_forwarding_trampoline 521 | nop 522 | nop 523 | nop 524 | call _xt_forwarding_trampoline 525 | nop 526 | nop 527 | nop 528 | call _xt_forwarding_trampoline 529 | nop 530 | nop 531 | nop 532 | call _xt_forwarding_trampoline 533 | nop 534 | nop 535 | nop 536 | call _xt_forwarding_trampoline 537 | nop 538 | nop 539 | nop 540 | call _xt_forwarding_trampoline 541 | nop 542 | nop 543 | nop 544 | call _xt_forwarding_trampoline 545 | nop 546 | nop 547 | nop 548 | call _xt_forwarding_trampoline 549 | nop 550 | nop 551 | nop 552 | call _xt_forwarding_trampoline 553 | nop 554 | nop 555 | nop 556 | call _xt_forwarding_trampoline 557 | nop 558 | nop 559 | nop 560 | call _xt_forwarding_trampoline 561 | nop 562 | nop 563 | nop 564 | call _xt_forwarding_trampoline 565 | nop 566 | nop 567 | nop 568 | call _xt_forwarding_trampoline 569 | nop 570 | nop 571 | nop 572 | call _xt_forwarding_trampoline 573 | nop 574 | nop 575 | nop 576 | call _xt_forwarding_trampoline 577 | nop 578 | nop 579 | nop 580 | call _xt_forwarding_trampoline 581 | nop 582 | nop 583 | nop 584 | call _xt_forwarding_trampoline 585 | nop 586 | nop 587 | nop 588 | call _xt_forwarding_trampoline 589 | nop 590 | nop 591 | nop 592 | call _xt_forwarding_trampoline 593 | nop 594 | nop 595 | nop 596 | call _xt_forwarding_trampoline 597 | nop 598 | nop 599 | nop 600 | call _xt_forwarding_trampoline 601 | nop 602 | nop 603 | nop 604 | call _xt_forwarding_trampoline 605 | nop 606 | nop 607 | nop 608 | call _xt_forwarding_trampoline 609 | nop 610 | nop 611 | nop 612 | call _xt_forwarding_trampoline 613 | nop 614 | nop 615 | nop 616 | call _xt_forwarding_trampoline 617 | nop 618 | nop 619 | nop 620 | call _xt_forwarding_trampoline 621 | nop 622 | nop 623 | nop 624 | call _xt_forwarding_trampoline 625 | nop 626 | nop 627 | nop 628 | call _xt_forwarding_trampoline 629 | nop 630 | nop 631 | nop 632 | call _xt_forwarding_trampoline 633 | nop 634 | nop 635 | nop 636 | call _xt_forwarding_trampoline 637 | nop 638 | nop 639 | nop 640 | call _xt_forwarding_trampoline 641 | nop 642 | nop 643 | nop 644 | call _xt_forwarding_trampoline 645 | nop 646 | nop 647 | nop 648 | call _xt_forwarding_trampoline 649 | nop 650 | nop 651 | nop 652 | call _xt_forwarding_trampoline 653 | nop 654 | nop 655 | nop 656 | call _xt_forwarding_trampoline 657 | nop 658 | nop 659 | nop 660 | call _xt_forwarding_trampoline 661 | nop 662 | nop 663 | nop 664 | call _xt_forwarding_trampoline 665 | nop 666 | nop 667 | nop 668 | call _xt_forwarding_trampoline 669 | nop 670 | nop 671 | nop 672 | call _xt_forwarding_trampoline 673 | nop 674 | nop 675 | nop 676 | call _xt_forwarding_trampoline 677 | nop 678 | nop 679 | nop 680 | call _xt_forwarding_trampoline 681 | nop 682 | nop 683 | nop 684 | call _xt_forwarding_trampoline 685 | nop 686 | nop 687 | nop 688 | call _xt_forwarding_trampoline 689 | nop 690 | nop 691 | nop 692 | call _xt_forwarding_trampoline 693 | nop 694 | nop 695 | nop 696 | call _xt_forwarding_trampoline 697 | nop 698 | nop 699 | nop 700 | call _xt_forwarding_trampoline 701 | nop 702 | nop 703 | nop 704 | call _xt_forwarding_trampoline 705 | nop 706 | nop 707 | nop 708 | call _xt_forwarding_trampoline 709 | nop 710 | nop 711 | nop 712 | call _xt_forwarding_trampoline 713 | nop 714 | nop 715 | nop 716 | call _xt_forwarding_trampoline 717 | nop 718 | nop 719 | nop 720 | call _xt_forwarding_trampoline 721 | nop 722 | nop 723 | nop 724 | call _xt_forwarding_trampoline 725 | nop 726 | nop 727 | nop 728 | call _xt_forwarding_trampoline 729 | nop 730 | nop 731 | nop 732 | call _xt_forwarding_trampoline 733 | nop 734 | nop 735 | nop 736 | call _xt_forwarding_trampoline 737 | nop 738 | nop 739 | nop 740 | call _xt_forwarding_trampoline 741 | nop 742 | nop 743 | nop 744 | call _xt_forwarding_trampoline 745 | nop 746 | nop 747 | nop 748 | call _xt_forwarding_trampoline 749 | nop 750 | nop 751 | nop 752 | call _xt_forwarding_trampoline 753 | nop 754 | nop 755 | nop 756 | call _xt_forwarding_trampoline 757 | nop 758 | nop 759 | nop 760 | call _xt_forwarding_trampoline 761 | nop 762 | nop 763 | nop 764 | call _xt_forwarding_trampoline 765 | nop 766 | nop 767 | nop 768 | call _xt_forwarding_trampoline 769 | nop 770 | nop 771 | nop 772 | call _xt_forwarding_trampoline 773 | nop 774 | nop 775 | nop 776 | call _xt_forwarding_trampoline 777 | nop 778 | nop 779 | nop 780 | call _xt_forwarding_trampoline 781 | nop 782 | nop 783 | nop 784 | call _xt_forwarding_trampoline 785 | nop 786 | nop 787 | nop 788 | call _xt_forwarding_trampoline 789 | nop 790 | nop 791 | nop 792 | call _xt_forwarding_trampoline 793 | nop 794 | nop 795 | nop 796 | call _xt_forwarding_trampoline 797 | nop 798 | nop 799 | nop 800 | call _xt_forwarding_trampoline 801 | nop 802 | nop 803 | nop 804 | call _xt_forwarding_trampoline 805 | nop 806 | nop 807 | nop 808 | call _xt_forwarding_trampoline 809 | nop 810 | nop 811 | nop 812 | call _xt_forwarding_trampoline 813 | nop 814 | nop 815 | nop 816 | call _xt_forwarding_trampoline 817 | nop 818 | nop 819 | nop 820 | call _xt_forwarding_trampoline 821 | nop 822 | nop 823 | nop 824 | call _xt_forwarding_trampoline 825 | nop 826 | nop 827 | nop 828 | call _xt_forwarding_trampoline 829 | nop 830 | nop 831 | nop 832 | call _xt_forwarding_trampoline 833 | nop 834 | nop 835 | nop 836 | call _xt_forwarding_trampoline 837 | nop 838 | nop 839 | nop 840 | call _xt_forwarding_trampoline 841 | nop 842 | nop 843 | nop 844 | call _xt_forwarding_trampoline 845 | nop 846 | nop 847 | nop 848 | call _xt_forwarding_trampoline 849 | nop 850 | nop 851 | nop 852 | call _xt_forwarding_trampoline 853 | nop 854 | nop 855 | nop 856 | call _xt_forwarding_trampoline 857 | nop 858 | nop 859 | nop 860 | call _xt_forwarding_trampoline 861 | nop 862 | nop 863 | nop 864 | call _xt_forwarding_trampoline 865 | nop 866 | nop 867 | nop 868 | call _xt_forwarding_trampoline 869 | nop 870 | nop 871 | nop 872 | call _xt_forwarding_trampoline 873 | nop 874 | nop 875 | nop 876 | call _xt_forwarding_trampoline 877 | nop 878 | nop 879 | nop 880 | call _xt_forwarding_trampoline 881 | nop 882 | nop 883 | nop 884 | call _xt_forwarding_trampoline 885 | nop 886 | nop 887 | nop 888 | call _xt_forwarding_trampoline 889 | nop 890 | nop 891 | nop 892 | call _xt_forwarding_trampoline 893 | nop 894 | nop 895 | nop 896 | call _xt_forwarding_trampoline 897 | nop 898 | nop 899 | nop 900 | call _xt_forwarding_trampoline 901 | nop 902 | nop 903 | nop 904 | call _xt_forwarding_trampoline 905 | nop 906 | nop 907 | nop 908 | call _xt_forwarding_trampoline 909 | nop 910 | nop 911 | nop 912 | call _xt_forwarding_trampoline 913 | nop 914 | nop 915 | nop 916 | call _xt_forwarding_trampoline 917 | nop 918 | nop 919 | nop 920 | call _xt_forwarding_trampoline 921 | nop 922 | nop 923 | nop 924 | call _xt_forwarding_trampoline 925 | nop 926 | nop 927 | nop 928 | call _xt_forwarding_trampoline 929 | nop 930 | nop 931 | nop 932 | call _xt_forwarding_trampoline 933 | nop 934 | nop 935 | nop 936 | call _xt_forwarding_trampoline 937 | nop 938 | nop 939 | nop 940 | call _xt_forwarding_trampoline 941 | nop 942 | nop 943 | nop 944 | call _xt_forwarding_trampoline 945 | nop 946 | nop 947 | nop 948 | call _xt_forwarding_trampoline 949 | nop 950 | nop 951 | nop 952 | call _xt_forwarding_trampoline 953 | nop 954 | nop 955 | nop 956 | call _xt_forwarding_trampoline 957 | nop 958 | nop 959 | nop 960 | call _xt_forwarding_trampoline 961 | nop 962 | nop 963 | nop 964 | call _xt_forwarding_trampoline 965 | nop 966 | nop 967 | nop 968 | call _xt_forwarding_trampoline 969 | nop 970 | nop 971 | nop 972 | call _xt_forwarding_trampoline 973 | nop 974 | nop 975 | nop 976 | call _xt_forwarding_trampoline 977 | nop 978 | nop 979 | nop 980 | call _xt_forwarding_trampoline 981 | nop 982 | nop 983 | nop 984 | call _xt_forwarding_trampoline 985 | nop 986 | nop 987 | nop 988 | call _xt_forwarding_trampoline 989 | nop 990 | nop 991 | nop 992 | call _xt_forwarding_trampoline 993 | nop 994 | nop 995 | nop 996 | call _xt_forwarding_trampoline 997 | nop 998 | nop 999 | nop 1000 | call _xt_forwarding_trampoline 1001 | nop 1002 | nop 1003 | nop 1004 | call _xt_forwarding_trampoline 1005 | nop 1006 | nop 1007 | nop 1008 | call _xt_forwarding_trampoline 1009 | nop 1010 | nop 1011 | nop 1012 | call _xt_forwarding_trampoline 1013 | nop 1014 | nop 1015 | nop 1016 | call _xt_forwarding_trampoline 1017 | nop 1018 | nop 1019 | nop 1020 | call _xt_forwarding_trampoline 1021 | nop 1022 | nop 1023 | nop 1024 | call _xt_forwarding_trampoline 1025 | nop 1026 | nop 1027 | nop 1028 | call _xt_forwarding_trampoline 1029 | nop 1030 | nop 1031 | nop 1032 | call _xt_forwarding_trampoline 1033 | nop 1034 | nop 1035 | nop 1036 | call _xt_forwarding_trampoline 1037 | nop 1038 | nop 1039 | nop 1040 | call _xt_forwarding_trampoline 1041 | nop 1042 | nop 1043 | nop 1044 | call _xt_forwarding_trampoline 1045 | nop 1046 | nop 1047 | nop 1048 | call _xt_forwarding_trampoline 1049 | nop 1050 | nop 1051 | nop 1052 | call _xt_forwarding_trampoline 1053 | nop 1054 | nop 1055 | nop 1056 | call _xt_forwarding_trampoline 1057 | nop 1058 | nop 1059 | nop 1060 | call _xt_forwarding_trampoline 1061 | nop 1062 | nop 1063 | nop 1064 | call _xt_forwarding_trampoline 1065 | nop 1066 | nop 1067 | nop 1068 | call _xt_forwarding_trampoline 1069 | nop 1070 | nop 1071 | nop 1072 | call _xt_forwarding_trampoline 1073 | nop 1074 | nop 1075 | nop 1076 | call _xt_forwarding_trampoline 1077 | nop 1078 | nop 1079 | nop 1080 | call _xt_forwarding_trampoline 1081 | nop 1082 | nop 1083 | nop 1084 | call _xt_forwarding_trampoline 1085 | nop 1086 | nop 1087 | nop 1088 | call _xt_forwarding_trampoline 1089 | nop 1090 | nop 1091 | nop 1092 | call _xt_forwarding_trampoline 1093 | nop 1094 | nop 1095 | nop 1096 | call _xt_forwarding_trampoline 1097 | nop 1098 | nop 1099 | nop 1100 | call _xt_forwarding_trampoline 1101 | nop 1102 | nop 1103 | nop 1104 | call _xt_forwarding_trampoline 1105 | nop 1106 | nop 1107 | nop 1108 | call _xt_forwarding_trampoline 1109 | nop 1110 | nop 1111 | nop 1112 | call _xt_forwarding_trampoline 1113 | nop 1114 | nop 1115 | nop 1116 | call _xt_forwarding_trampoline 1117 | nop 1118 | nop 1119 | nop 1120 | call _xt_forwarding_trampoline 1121 | nop 1122 | nop 1123 | nop 1124 | call _xt_forwarding_trampoline 1125 | nop 1126 | nop 1127 | nop 1128 | call _xt_forwarding_trampoline 1129 | nop 1130 | nop 1131 | nop 1132 | call _xt_forwarding_trampoline 1133 | nop 1134 | nop 1135 | nop 1136 | call _xt_forwarding_trampoline 1137 | nop 1138 | nop 1139 | nop 1140 | call _xt_forwarding_trampoline 1141 | nop 1142 | nop 1143 | nop 1144 | call _xt_forwarding_trampoline 1145 | nop 1146 | nop 1147 | nop 1148 | call _xt_forwarding_trampoline 1149 | nop 1150 | nop 1151 | nop 1152 | call _xt_forwarding_trampoline 1153 | nop 1154 | nop 1155 | nop 1156 | call _xt_forwarding_trampoline 1157 | nop 1158 | nop 1159 | nop 1160 | call _xt_forwarding_trampoline 1161 | nop 1162 | nop 1163 | nop 1164 | call _xt_forwarding_trampoline 1165 | nop 1166 | nop 1167 | nop 1168 | call _xt_forwarding_trampoline 1169 | nop 1170 | nop 1171 | nop 1172 | call _xt_forwarding_trampoline 1173 | nop 1174 | nop 1175 | nop 1176 | call _xt_forwarding_trampoline 1177 | nop 1178 | nop 1179 | nop 1180 | call _xt_forwarding_trampoline 1181 | nop 1182 | nop 1183 | nop 1184 | call _xt_forwarding_trampoline 1185 | nop 1186 | nop 1187 | nop 1188 | call _xt_forwarding_trampoline 1189 | nop 1190 | nop 1191 | nop 1192 | call _xt_forwarding_trampoline 1193 | nop 1194 | nop 1195 | nop 1196 | call _xt_forwarding_trampoline 1197 | nop 1198 | nop 1199 | nop 1200 | call _xt_forwarding_trampoline 1201 | nop 1202 | nop 1203 | nop 1204 | call _xt_forwarding_trampoline 1205 | nop 1206 | nop 1207 | nop 1208 | call _xt_forwarding_trampoline 1209 | nop 1210 | nop 1211 | nop 1212 | call _xt_forwarding_trampoline 1213 | nop 1214 | nop 1215 | nop 1216 | call _xt_forwarding_trampoline 1217 | nop 1218 | nop 1219 | nop 1220 | call _xt_forwarding_trampoline 1221 | nop 1222 | nop 1223 | nop 1224 | call _xt_forwarding_trampoline 1225 | nop 1226 | nop 1227 | nop 1228 | call _xt_forwarding_trampoline 1229 | nop 1230 | nop 1231 | nop 1232 | call _xt_forwarding_trampoline 1233 | nop 1234 | nop 1235 | nop 1236 | call _xt_forwarding_trampoline 1237 | nop 1238 | nop 1239 | nop 1240 | call _xt_forwarding_trampoline 1241 | nop 1242 | nop 1243 | nop 1244 | call _xt_forwarding_trampoline 1245 | nop 1246 | nop 1247 | nop 1248 | call _xt_forwarding_trampoline 1249 | nop 1250 | nop 1251 | nop 1252 | call _xt_forwarding_trampoline 1253 | nop 1254 | nop 1255 | nop 1256 | call _xt_forwarding_trampoline 1257 | nop 1258 | nop 1259 | nop 1260 | call _xt_forwarding_trampoline 1261 | nop 1262 | nop 1263 | nop 1264 | call _xt_forwarding_trampoline 1265 | nop 1266 | nop 1267 | nop 1268 | call _xt_forwarding_trampoline 1269 | nop 1270 | nop 1271 | nop 1272 | call _xt_forwarding_trampoline 1273 | nop 1274 | nop 1275 | nop 1276 | call _xt_forwarding_trampoline 1277 | nop 1278 | nop 1279 | nop 1280 | call _xt_forwarding_trampoline 1281 | nop 1282 | nop 1283 | nop 1284 | call _xt_forwarding_trampoline 1285 | nop 1286 | nop 1287 | nop 1288 | call _xt_forwarding_trampoline 1289 | nop 1290 | nop 1291 | nop 1292 | call _xt_forwarding_trampoline 1293 | nop 1294 | nop 1295 | nop 1296 | call _xt_forwarding_trampoline 1297 | nop 1298 | nop 1299 | nop 1300 | call _xt_forwarding_trampoline 1301 | nop 1302 | nop 1303 | nop 1304 | call _xt_forwarding_trampoline 1305 | nop 1306 | nop 1307 | nop 1308 | call _xt_forwarding_trampoline 1309 | nop 1310 | nop 1311 | nop 1312 | call _xt_forwarding_trampoline 1313 | nop 1314 | nop 1315 | nop 1316 | call _xt_forwarding_trampoline 1317 | nop 1318 | nop 1319 | nop 1320 | call _xt_forwarding_trampoline 1321 | nop 1322 | nop 1323 | nop 1324 | call _xt_forwarding_trampoline 1325 | nop 1326 | nop 1327 | nop 1328 | call _xt_forwarding_trampoline 1329 | nop 1330 | nop 1331 | nop 1332 | call _xt_forwarding_trampoline 1333 | nop 1334 | nop 1335 | nop 1336 | call _xt_forwarding_trampoline 1337 | nop 1338 | nop 1339 | nop 1340 | call _xt_forwarding_trampoline 1341 | nop 1342 | nop 1343 | nop 1344 | call _xt_forwarding_trampoline 1345 | nop 1346 | nop 1347 | nop 1348 | call _xt_forwarding_trampoline 1349 | nop 1350 | nop 1351 | nop 1352 | call _xt_forwarding_trampoline 1353 | nop 1354 | nop 1355 | nop 1356 | call _xt_forwarding_trampoline 1357 | nop 1358 | nop 1359 | nop 1360 | call _xt_forwarding_trampoline 1361 | nop 1362 | nop 1363 | nop 1364 | call _xt_forwarding_trampoline 1365 | nop 1366 | nop 1367 | nop 1368 | call _xt_forwarding_trampoline 1369 | nop 1370 | nop 1371 | nop 1372 | call _xt_forwarding_trampoline 1373 | nop 1374 | nop 1375 | nop 1376 | call _xt_forwarding_trampoline 1377 | nop 1378 | nop 1379 | nop 1380 | call _xt_forwarding_trampoline 1381 | nop 1382 | nop 1383 | nop 1384 | call _xt_forwarding_trampoline 1385 | nop 1386 | nop 1387 | nop 1388 | call _xt_forwarding_trampoline 1389 | nop 1390 | nop 1391 | nop 1392 | call _xt_forwarding_trampoline 1393 | nop 1394 | nop 1395 | nop 1396 | call _xt_forwarding_trampoline 1397 | nop 1398 | nop 1399 | nop 1400 | call _xt_forwarding_trampoline 1401 | nop 1402 | nop 1403 | nop 1404 | call _xt_forwarding_trampoline 1405 | nop 1406 | nop 1407 | nop 1408 | call _xt_forwarding_trampoline 1409 | nop 1410 | nop 1411 | nop 1412 | call _xt_forwarding_trampoline 1413 | nop 1414 | nop 1415 | nop 1416 | call _xt_forwarding_trampoline 1417 | nop 1418 | nop 1419 | nop 1420 | call _xt_forwarding_trampoline 1421 | nop 1422 | nop 1423 | nop 1424 | call _xt_forwarding_trampoline 1425 | nop 1426 | nop 1427 | nop 1428 | call _xt_forwarding_trampoline 1429 | nop 1430 | nop 1431 | nop 1432 | call _xt_forwarding_trampoline 1433 | nop 1434 | nop 1435 | nop 1436 | call _xt_forwarding_trampoline 1437 | nop 1438 | nop 1439 | nop 1440 | call _xt_forwarding_trampoline 1441 | nop 1442 | nop 1443 | nop 1444 | call _xt_forwarding_trampoline 1445 | nop 1446 | nop 1447 | nop 1448 | call _xt_forwarding_trampoline 1449 | nop 1450 | nop 1451 | nop 1452 | call _xt_forwarding_trampoline 1453 | nop 1454 | nop 1455 | nop 1456 | call _xt_forwarding_trampoline 1457 | nop 1458 | nop 1459 | nop 1460 | call _xt_forwarding_trampoline 1461 | nop 1462 | nop 1463 | nop 1464 | call _xt_forwarding_trampoline 1465 | nop 1466 | nop 1467 | nop 1468 | call _xt_forwarding_trampoline 1469 | nop 1470 | nop 1471 | nop 1472 | call _xt_forwarding_trampoline 1473 | nop 1474 | nop 1475 | nop 1476 | call _xt_forwarding_trampoline 1477 | nop 1478 | nop 1479 | nop 1480 | call _xt_forwarding_trampoline 1481 | nop 1482 | nop 1483 | nop 1484 | call _xt_forwarding_trampoline 1485 | nop 1486 | nop 1487 | nop 1488 | call _xt_forwarding_trampoline 1489 | nop 1490 | nop 1491 | nop 1492 | call _xt_forwarding_trampoline 1493 | nop 1494 | nop 1495 | nop 1496 | call _xt_forwarding_trampoline 1497 | nop 1498 | nop 1499 | nop 1500 | call _xt_forwarding_trampoline 1501 | nop 1502 | nop 1503 | nop 1504 | call _xt_forwarding_trampoline 1505 | nop 1506 | nop 1507 | nop 1508 | call _xt_forwarding_trampoline 1509 | nop 1510 | nop 1511 | nop 1512 | call _xt_forwarding_trampoline 1513 | nop 1514 | nop 1515 | nop 1516 | call _xt_forwarding_trampoline 1517 | nop 1518 | nop 1519 | nop 1520 | call _xt_forwarding_trampoline 1521 | nop 1522 | nop 1523 | nop 1524 | call _xt_forwarding_trampoline 1525 | nop 1526 | nop 1527 | nop 1528 | call _xt_forwarding_trampoline 1529 | nop 1530 | nop 1531 | nop 1532 | call _xt_forwarding_trampoline 1533 | nop 1534 | nop 1535 | nop 1536 | call _xt_forwarding_trampoline 1537 | nop 1538 | nop 1539 | nop 1540 | call _xt_forwarding_trampoline 1541 | nop 1542 | nop 1543 | nop 1544 | call _xt_forwarding_trampoline 1545 | nop 1546 | nop 1547 | nop 1548 | call _xt_forwarding_trampoline 1549 | nop 1550 | nop 1551 | nop 1552 | call _xt_forwarding_trampoline 1553 | nop 1554 | nop 1555 | nop 1556 | call _xt_forwarding_trampoline 1557 | nop 1558 | nop 1559 | nop 1560 | call _xt_forwarding_trampoline 1561 | nop 1562 | nop 1563 | nop 1564 | call _xt_forwarding_trampoline 1565 | nop 1566 | nop 1567 | nop 1568 | call _xt_forwarding_trampoline 1569 | nop 1570 | nop 1571 | nop 1572 | call _xt_forwarding_trampoline 1573 | nop 1574 | nop 1575 | nop 1576 | call _xt_forwarding_trampoline 1577 | nop 1578 | nop 1579 | nop 1580 | call _xt_forwarding_trampoline 1581 | nop 1582 | nop 1583 | nop 1584 | call _xt_forwarding_trampoline 1585 | nop 1586 | nop 1587 | nop 1588 | call _xt_forwarding_trampoline 1589 | nop 1590 | nop 1591 | nop 1592 | call _xt_forwarding_trampoline 1593 | nop 1594 | nop 1595 | nop 1596 | call _xt_forwarding_trampoline 1597 | nop 1598 | nop 1599 | nop 1600 | call _xt_forwarding_trampoline 1601 | nop 1602 | nop 1603 | nop 1604 | call _xt_forwarding_trampoline 1605 | nop 1606 | nop 1607 | nop 1608 | call _xt_forwarding_trampoline 1609 | nop 1610 | nop 1611 | nop 1612 | call _xt_forwarding_trampoline 1613 | nop 1614 | nop 1615 | nop 1616 | call _xt_forwarding_trampoline 1617 | nop 1618 | nop 1619 | nop 1620 | call _xt_forwarding_trampoline 1621 | nop 1622 | nop 1623 | nop 1624 | call _xt_forwarding_trampoline 1625 | nop 1626 | nop 1627 | nop 1628 | call _xt_forwarding_trampoline 1629 | nop 1630 | nop 1631 | nop 1632 | call _xt_forwarding_trampoline 1633 | nop 1634 | nop 1635 | nop 1636 | call _xt_forwarding_trampoline 1637 | nop 1638 | nop 1639 | nop 1640 | call _xt_forwarding_trampoline 1641 | nop 1642 | nop 1643 | nop 1644 | call _xt_forwarding_trampoline 1645 | nop 1646 | nop 1647 | nop 1648 | call _xt_forwarding_trampoline 1649 | nop 1650 | nop 1651 | nop 1652 | call _xt_forwarding_trampoline 1653 | nop 1654 | nop 1655 | nop 1656 | call _xt_forwarding_trampoline 1657 | nop 1658 | nop 1659 | nop 1660 | call _xt_forwarding_trampoline 1661 | nop 1662 | nop 1663 | nop 1664 | call _xt_forwarding_trampoline 1665 | nop 1666 | nop 1667 | nop 1668 | call _xt_forwarding_trampoline 1669 | nop 1670 | nop 1671 | nop 1672 | call _xt_forwarding_trampoline 1673 | nop 1674 | nop 1675 | nop 1676 | call _xt_forwarding_trampoline 1677 | nop 1678 | nop 1679 | nop 1680 | call _xt_forwarding_trampoline 1681 | nop 1682 | nop 1683 | nop 1684 | call _xt_forwarding_trampoline 1685 | nop 1686 | nop 1687 | nop 1688 | call _xt_forwarding_trampoline 1689 | nop 1690 | nop 1691 | nop 1692 | call _xt_forwarding_trampoline 1693 | nop 1694 | nop 1695 | nop 1696 | call _xt_forwarding_trampoline 1697 | nop 1698 | nop 1699 | nop 1700 | call _xt_forwarding_trampoline 1701 | nop 1702 | nop 1703 | nop 1704 | call _xt_forwarding_trampoline 1705 | nop 1706 | nop 1707 | nop 1708 | call _xt_forwarding_trampoline 1709 | nop 1710 | nop 1711 | nop 1712 | call _xt_forwarding_trampoline 1713 | nop 1714 | nop 1715 | nop 1716 | call _xt_forwarding_trampoline 1717 | nop 1718 | nop 1719 | nop 1720 | call _xt_forwarding_trampoline 1721 | nop 1722 | nop 1723 | nop 1724 | call _xt_forwarding_trampoline 1725 | nop 1726 | nop 1727 | nop 1728 | call _xt_forwarding_trampoline 1729 | nop 1730 | nop 1731 | nop 1732 | call _xt_forwarding_trampoline 1733 | nop 1734 | nop 1735 | nop 1736 | call _xt_forwarding_trampoline 1737 | nop 1738 | nop 1739 | nop 1740 | call _xt_forwarding_trampoline 1741 | nop 1742 | nop 1743 | nop 1744 | call _xt_forwarding_trampoline 1745 | nop 1746 | nop 1747 | nop 1748 | call _xt_forwarding_trampoline 1749 | nop 1750 | nop 1751 | nop 1752 | call _xt_forwarding_trampoline 1753 | nop 1754 | nop 1755 | nop 1756 | call _xt_forwarding_trampoline 1757 | nop 1758 | nop 1759 | nop 1760 | call _xt_forwarding_trampoline 1761 | nop 1762 | nop 1763 | nop 1764 | call _xt_forwarding_trampoline 1765 | nop 1766 | nop 1767 | nop 1768 | call _xt_forwarding_trampoline 1769 | nop 1770 | nop 1771 | nop 1772 | call _xt_forwarding_trampoline 1773 | nop 1774 | nop 1775 | nop 1776 | call _xt_forwarding_trampoline 1777 | nop 1778 | nop 1779 | nop 1780 | call _xt_forwarding_trampoline 1781 | nop 1782 | nop 1783 | nop 1784 | call _xt_forwarding_trampoline 1785 | nop 1786 | nop 1787 | nop 1788 | call _xt_forwarding_trampoline 1789 | nop 1790 | nop 1791 | nop 1792 | call _xt_forwarding_trampoline 1793 | nop 1794 | nop 1795 | nop 1796 | call _xt_forwarding_trampoline 1797 | nop 1798 | nop 1799 | nop 1800 | call _xt_forwarding_trampoline 1801 | nop 1802 | nop 1803 | nop 1804 | call _xt_forwarding_trampoline 1805 | nop 1806 | nop 1807 | nop 1808 | call _xt_forwarding_trampoline 1809 | nop 1810 | nop 1811 | nop 1812 | call _xt_forwarding_trampoline 1813 | nop 1814 | nop 1815 | nop 1816 | call _xt_forwarding_trampoline 1817 | nop 1818 | nop 1819 | nop 1820 | call _xt_forwarding_trampoline 1821 | nop 1822 | nop 1823 | nop 1824 | call _xt_forwarding_trampoline 1825 | nop 1826 | nop 1827 | nop 1828 | call _xt_forwarding_trampoline 1829 | nop 1830 | nop 1831 | nop 1832 | call _xt_forwarding_trampoline 1833 | nop 1834 | nop 1835 | nop 1836 | call _xt_forwarding_trampoline 1837 | nop 1838 | nop 1839 | nop 1840 | call _xt_forwarding_trampoline 1841 | nop 1842 | nop 1843 | nop 1844 | call _xt_forwarding_trampoline 1845 | nop 1846 | nop 1847 | nop 1848 | call _xt_forwarding_trampoline 1849 | nop 1850 | nop 1851 | nop 1852 | call _xt_forwarding_trampoline 1853 | nop 1854 | nop 1855 | nop 1856 | call _xt_forwarding_trampoline 1857 | nop 1858 | nop 1859 | nop 1860 | call _xt_forwarding_trampoline 1861 | nop 1862 | nop 1863 | nop 1864 | call _xt_forwarding_trampoline 1865 | nop 1866 | nop 1867 | nop 1868 | call _xt_forwarding_trampoline 1869 | nop 1870 | nop 1871 | nop 1872 | call _xt_forwarding_trampoline 1873 | nop 1874 | nop 1875 | nop 1876 | call _xt_forwarding_trampoline 1877 | nop 1878 | nop 1879 | nop 1880 | call _xt_forwarding_trampoline 1881 | nop 1882 | nop 1883 | nop 1884 | call _xt_forwarding_trampoline 1885 | nop 1886 | nop 1887 | nop 1888 | call _xt_forwarding_trampoline 1889 | nop 1890 | nop 1891 | nop 1892 | call _xt_forwarding_trampoline 1893 | nop 1894 | nop 1895 | nop 1896 | call _xt_forwarding_trampoline 1897 | nop 1898 | nop 1899 | nop 1900 | call _xt_forwarding_trampoline 1901 | nop 1902 | nop 1903 | nop 1904 | call _xt_forwarding_trampoline 1905 | nop 1906 | nop 1907 | nop 1908 | call _xt_forwarding_trampoline 1909 | nop 1910 | nop 1911 | nop 1912 | call _xt_forwarding_trampoline 1913 | nop 1914 | nop 1915 | nop 1916 | call _xt_forwarding_trampoline 1917 | nop 1918 | nop 1919 | nop 1920 | call _xt_forwarding_trampoline 1921 | nop 1922 | nop 1923 | nop 1924 | call _xt_forwarding_trampoline 1925 | nop 1926 | nop 1927 | nop 1928 | call _xt_forwarding_trampoline 1929 | nop 1930 | nop 1931 | nop 1932 | call _xt_forwarding_trampoline 1933 | nop 1934 | nop 1935 | nop 1936 | call _xt_forwarding_trampoline 1937 | nop 1938 | nop 1939 | nop 1940 | call _xt_forwarding_trampoline 1941 | nop 1942 | nop 1943 | nop 1944 | call _xt_forwarding_trampoline 1945 | nop 1946 | nop 1947 | nop 1948 | call _xt_forwarding_trampoline 1949 | nop 1950 | nop 1951 | nop 1952 | call _xt_forwarding_trampoline 1953 | nop 1954 | nop 1955 | nop 1956 | call _xt_forwarding_trampoline 1957 | nop 1958 | nop 1959 | nop 1960 | call _xt_forwarding_trampoline 1961 | nop 1962 | nop 1963 | nop 1964 | call _xt_forwarding_trampoline 1965 | nop 1966 | nop 1967 | nop 1968 | call _xt_forwarding_trampoline 1969 | nop 1970 | nop 1971 | nop 1972 | call _xt_forwarding_trampoline 1973 | nop 1974 | nop 1975 | nop 1976 | call _xt_forwarding_trampoline 1977 | nop 1978 | nop 1979 | nop 1980 | call _xt_forwarding_trampoline 1981 | nop 1982 | nop 1983 | nop 1984 | call _xt_forwarding_trampoline 1985 | nop 1986 | nop 1987 | nop 1988 | call _xt_forwarding_trampoline 1989 | nop 1990 | nop 1991 | nop 1992 | call _xt_forwarding_trampoline 1993 | nop 1994 | nop 1995 | nop 1996 | call _xt_forwarding_trampoline 1997 | nop 1998 | nop 1999 | nop 2000 | call _xt_forwarding_trampoline 2001 | nop 2002 | nop 2003 | nop 2004 | call _xt_forwarding_trampoline 2005 | nop 2006 | nop 2007 | nop 2008 | call _xt_forwarding_trampoline 2009 | nop 2010 | nop 2011 | nop 2012 | call _xt_forwarding_trampoline 2013 | nop 2014 | nop 2015 | nop 2016 | call _xt_forwarding_trampoline 2017 | nop 2018 | nop 2019 | nop 2020 | call _xt_forwarding_trampoline 2021 | nop 2022 | nop 2023 | nop 2024 | call _xt_forwarding_trampoline 2025 | nop 2026 | nop 2027 | nop 2028 | call _xt_forwarding_trampoline 2029 | nop 2030 | nop 2031 | nop 2032 | call _xt_forwarding_trampoline 2033 | nop 2034 | nop 2035 | nop 2036 | call _xt_forwarding_trampoline 2037 | nop 2038 | nop 2039 | nop 2040 | call _xt_forwarding_trampoline 2041 | nop 2042 | nop 2043 | nop 2044 | call _xt_forwarding_trampoline 2045 | nop 2046 | nop 2047 | nop 2048 | call _xt_forwarding_trampoline 2049 | nop 2050 | nop 2051 | nop 2052 | call _xt_forwarding_trampoline 2053 | nop 2054 | nop 2055 | nop 2056 | call _xt_forwarding_trampoline 2057 | nop 2058 | nop 2059 | nop 2060 | call _xt_forwarding_trampoline 2061 | nop 2062 | nop 2063 | nop 2064 | call _xt_forwarding_trampoline 2065 | nop 2066 | nop 2067 | nop 2068 | call _xt_forwarding_trampoline 2069 | nop 2070 | nop 2071 | nop 2072 | _xt_forwarding_trampolines_end: 2073 | 2074 | #endif 2075 | -------------------------------------------------------------------------------- /PerformanceMonitor/PerformanceMonitor.h: -------------------------------------------------------------------------------- 1 | // 2 | // PerformanceMonitor.h 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/8/24. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for PerformanceMonitor. 12 | FOUNDATION_EXPORT double PerformanceMonitorVersionNumber; 13 | 14 | //! Project version string for PerformanceMonitor. 15 | FOUNDATION_EXPORT const unsigned char PerformanceMonitorVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | #import "MethodTimeMonitor.h" 20 | -------------------------------------------------------------------------------- /PerformanceMonitor/PerformanceMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PerformanceMonitor.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/8/24. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import RCBacktrace 11 | 12 | public class PerformanceMonitor { 13 | 14 | enum Constants { 15 | static let cpuTimeInterval = 3 16 | static let maxCUPUsage: Double = 80 17 | } 18 | 19 | private var cpuTime = 1 20 | 21 | public static let `default` = PerformanceMonitor() 22 | 23 | private let performanceView = PerformanceView() 24 | 25 | public struct DisplayOptions: OptionSet { 26 | public let rawValue: Int 27 | 28 | public static let cpu = DisplayOptions(rawValue: 1 << 0) 29 | 30 | public static let memory = DisplayOptions(rawValue: 1 << 1) 31 | 32 | public static let fps = DisplayOptions(rawValue: 1 << 2) 33 | 34 | public static let fluecy = DisplayOptions(rawValue: 1 << 3) 35 | 36 | public static let all: DisplayOptions = [.cpu, .memory, .fps, .fluecy] 37 | 38 | public init(rawValue: Int) { 39 | self.rawValue = rawValue 40 | } 41 | } 42 | 43 | private var monitoringTimer: DispatchSourceTimer? 44 | private var displayOptions: DisplayOptions = .all 45 | private var fpsMonitor: FPSMonitor? 46 | private var fluecyMonitor: FluecyMonitor? 47 | 48 | public init(displayOptions: DisplayOptions = .all) { 49 | self.displayOptions = displayOptions 50 | if displayOptions.contains(.fps) { 51 | fpsMonitor = FPSMonitor() 52 | fpsMonitor?.delegate = self 53 | } 54 | 55 | if displayOptions.contains(.fluecy) { 56 | fluecyMonitor = FluecyMonitor() 57 | fluecyMonitor?.start() 58 | } 59 | } 60 | 61 | public func start() { 62 | performanceView.isHidden = false 63 | 64 | monitoringTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global()) 65 | monitoringTimer?.schedule(deadline: .now(), repeating: 1) 66 | monitoringTimer?.setEventHandler(handler: { [weak self] in 67 | DispatchQueue.main.async { 68 | guard let strongSelf = self else { return } 69 | var string = "" 70 | if strongSelf.displayOptions.contains(.cpu) { 71 | let cpu = String.init(format: "%.1f", CPUMonitor.usage()) 72 | string += "CPU: \(cpu)% \n" 73 | 74 | strongSelf.cpuTime += 1 75 | if strongSelf.cpuTime > Constants.cpuTimeInterval { 76 | if CPUMonitor.usage() > Constants.maxCUPUsage { 77 | print("CPU usage is too high -------------------------------------------") 78 | let symbols = RCBacktrace.callstack(.current) 79 | for symbol in symbols { 80 | print(symbol.description) 81 | } 82 | print("CPU usage is too high -------------------------------------------") 83 | strongSelf.cpuTime = 1 84 | } 85 | } 86 | } 87 | 88 | if strongSelf.displayOptions.contains(.memory) { 89 | let memory = String.init(format: "%.1f", MemoryMonitor.usage()) 90 | string += "Memory: \(memory) MB \n" 91 | } 92 | 93 | strongSelf.performanceView.configureTitle(string) 94 | } 95 | }) 96 | monitoringTimer?.resume() 97 | } 98 | 99 | public func stop() { 100 | performanceView.isHidden = true 101 | monitoringTimer?.cancel() 102 | } 103 | 104 | public func pause() { 105 | monitoringTimer?.suspend() 106 | } 107 | 108 | public func resume() { 109 | monitoringTimer?.resume() 110 | } 111 | 112 | deinit { 113 | monitoringTimer?.cancel() 114 | } 115 | } 116 | 117 | extension PerformanceMonitor: FPSMonitorDelegate { 118 | 119 | public func fpsMonitor(with monitor: FPSMonitor, fps: Double) { 120 | DispatchQueue.main.async { 121 | self.performanceView.configureFPS(fps) 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /PerformanceMonitor/UI/PerformanceView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PerformanceView.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/8/26. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class PerformanceView: UIWindow { 12 | 13 | init() { 14 | super.init(frame: UIScreen.main.bounds) 15 | 16 | windowLevel = .normal + 1 17 | autoresizingMask = [.flexibleWidth, .flexibleHeight] 18 | rootViewController = PerformanceViewController() 19 | } 20 | 21 | func configureTitle(_ title: String) { 22 | (rootViewController as! PerformanceViewController).configureTitle(title) 23 | } 24 | 25 | func configureFPS(_ fps: Double) { 26 | (rootViewController as! PerformanceViewController).configureFPS(fps) 27 | } 28 | 29 | required init?(coder aDecoder: NSCoder) { 30 | fatalError("init(coder:) has not been implemented") 31 | } 32 | 33 | override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 34 | if rootViewController?.presentedViewController != nil { 35 | return super.point(inside: point, with: event) 36 | } 37 | 38 | let button = (rootViewController as! PerformanceViewController).infoLabel 39 | let buttonPoint = convert(point, to: button) 40 | 41 | return button.point(inside: buttonPoint, with: event) 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /PerformanceMonitor/UI/PerformanceViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PerformanceViewController.swift 3 | // PerformanceMonitor 4 | // 5 | // Created by roy.cao on 2019/8/26. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PerformanceViewController: UIViewController { 12 | 13 | enum Constants { 14 | static let infoButtonWidthConstraint: CGFloat = 90 15 | static let infoButtonHeightConstraint: CGFloat = 50 16 | static let infoButtonCornerRadius: CGFloat = 12 17 | static let delta: CGFloat = 2.0 18 | } 19 | 20 | private var isShow = false 21 | private weak var transitionContext: UIViewControllerContextTransitioning! 22 | 23 | private var originalCenter = CGPoint.zero 24 | 25 | lazy var infoLabel: UILabel = { 26 | let label = UILabel() 27 | label.translatesAutoresizingMaskIntoConstraints = false 28 | label.font = UIFont.init(name: "Menlo", size: 8.0) 29 | label.backgroundColor = .black 30 | label.layer.cornerRadius = Constants.infoButtonCornerRadius 31 | label.layer.masksToBounds = true 32 | label.textColor = .green 33 | label.isUserInteractionEnabled = true 34 | label.numberOfLines = 3 35 | label.textAlignment = .center 36 | label.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(onPanInfoLabel(_:)))) 37 | return label 38 | }() 39 | 40 | lazy var fpsLabel: UILabel = { 41 | let label = UILabel() 42 | label.translatesAutoresizingMaskIntoConstraints = false 43 | label.font = UIFont.init(name: "Menlo", size: 8.0) 44 | label.backgroundColor = .black 45 | label.textColor = .green 46 | label.textAlignment = .center 47 | label.isUserInteractionEnabled = true 48 | return label 49 | }() 50 | 51 | func configureTitle(_ title: String) { 52 | infoLabel.text = title 53 | } 54 | 55 | func configureFPS(_ fps: Double) { 56 | fpsLabel.text = "FPS: \(String.init(format: "%.1f", fps))" 57 | 58 | if fps > 55.0 { 59 | fpsLabel.textColor = .green 60 | } else if (fps >= 50.0 && fps <= 55.0) { 61 | fpsLabel.textColor = .yellow 62 | } else { 63 | fpsLabel.textColor = .red 64 | } 65 | } 66 | 67 | override var prefersStatusBarHidden: Bool { 68 | return UIApplication.shared.delegate?.window??.rootViewController?.prefersStatusBarHidden ?? false 69 | } 70 | 71 | override var preferredStatusBarStyle: UIStatusBarStyle { 72 | return UIApplication.shared.delegate?.window??.rootViewController?.preferredStatusBarStyle ?? .default 73 | } 74 | 75 | override func viewDidLoad() { 76 | super.viewDidLoad() 77 | 78 | view.addSubview(infoLabel) 79 | infoLabel.addSubview(fpsLabel) 80 | 81 | NSLayoutConstraint.activate([ 82 | infoLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -Constants.delta), 83 | infoLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -52), 84 | infoLabel.widthAnchor.constraint(equalToConstant: Constants.infoButtonWidthConstraint), 85 | infoLabel.heightAnchor.constraint(equalToConstant: Constants.infoButtonHeightConstraint), 86 | 87 | fpsLabel.centerXAnchor.constraint(equalTo: infoLabel.centerXAnchor), 88 | fpsLabel.bottomAnchor.constraint(equalTo: infoLabel.bottomAnchor, constant: -5), 89 | fpsLabel.widthAnchor.constraint(equalTo: infoLabel.widthAnchor, constant: -5), 90 | fpsLabel.heightAnchor.constraint(equalToConstant: Constants.infoButtonHeightConstraint/3) 91 | ]) 92 | } 93 | 94 | override func viewDidLayoutSubviews() { 95 | super.viewDidLayoutSubviews() 96 | 97 | if originalCenter != .zero { 98 | infoLabel.center = originalCenter 99 | } 100 | } 101 | 102 | @objc dynamic private func onPanInfoLabel(_ panGesture: UIPanGestureRecognizer) { 103 | let offset = panGesture.translation(in: view) 104 | panGesture.setTranslation(CGPoint.zero, in: view) 105 | 106 | var center = infoLabel.center 107 | center.x += offset.x 108 | center.y += offset.y 109 | infoLabel.center = center 110 | 111 | guard panGesture.state == .ended || panGesture.state == .cancelled else { return } 112 | 113 | UIView.animate(withDuration: CATransaction.animationDuration()) { 114 | self.snapInfoLabelToSocket() 115 | } 116 | } 117 | 118 | private func snapInfoLabelToSocket() { 119 | enum Direction: Int { 120 | case top, left, bottom, right 121 | } 122 | 123 | let viewSize = view.bounds.size 124 | var center = infoLabel.center 125 | let width = infoLabel.bounds.size.width 126 | let height = infoLabel.bounds.size.height 127 | let distances = [center.y, center.x, viewSize.height - center.y, viewSize.width - center.x] 128 | 129 | for (idx, distance) in distances.enumerated() { 130 | if distance != distances.min() { 131 | continue 132 | } 133 | 134 | let direction = Direction(rawValue: idx)! 135 | 136 | switch direction { 137 | case .top: center = CGPoint(x: center.x, y: height / 2 + Constants.delta) 138 | case .left: center = CGPoint(x: width / 2 + Constants.delta, y: center.y) 139 | case .bottom: center = CGPoint(x: center.x, y: viewSize.height - height / 2 - Constants.delta) 140 | case .right: center = CGPoint(x: viewSize.width - width / 2 - Constants.delta, y: center.y) 141 | } 142 | } 143 | 144 | infoLabel.center = center 145 | originalCenter = center 146 | } 147 | } 148 | 149 | // MARK: - Transition 150 | extension PerformanceViewController: UIViewControllerTransitioningDelegate { 151 | 152 | public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 153 | isShow = true 154 | return self 155 | } 156 | 157 | public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 158 | return self 159 | } 160 | 161 | public func animationEnded(_ transitionCompleted: Bool) { 162 | isShow = false 163 | } 164 | } 165 | 166 | extension PerformanceViewController: UIViewControllerAnimatedTransitioning { 167 | 168 | public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 169 | return 0.3 170 | } 171 | 172 | public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 173 | self.transitionContext = transitionContext 174 | 175 | guard let fromVC = transitionContext.viewController(forKey: .from) else { return } 176 | guard let toVC = transitionContext.viewController(forKey: .to) else { return } 177 | 178 | fromVC.view.frame = transitionContext.initialFrame(for: fromVC) 179 | toVC.view.frame = transitionContext.finalFrame(for: toVC) 180 | 181 | animatePresentingTransition(from: fromVC, to: toVC) 182 | } 183 | 184 | private func animatePresentingTransition(from fromVC: UIViewController, to toVC: UIViewController) { 185 | let containerView = transitionContext.containerView 186 | let fromView = fromVC.view! 187 | let toView = toVC.view! 188 | 189 | let point = containerView.center 190 | let radius = CGFloat(sqrtf(powf(Float(point.x), 2) + powf(Float(point.y), 2))) 191 | let startPath = UIBezierPath(arcCenter: containerView.center, radius: 0.01, startAngle: 0, endAngle: 2*CGFloat.pi, clockwise: true).cgPath 192 | let endPath = UIBezierPath(arcCenter: containerView.center, radius: radius, startAngle: 0, endAngle: 2*CGFloat.pi, clockwise: true).cgPath 193 | let maskLayer = CAShapeLayer(layer: startPath) 194 | 195 | let animationDuration = transitionDuration(using: transitionContext) 196 | let circleAnimation = CABasicAnimation(keyPath: "path") 197 | circleAnimation.duration = animationDuration 198 | // Avoid screen flash 199 | circleAnimation.isRemovedOnCompletion = false 200 | circleAnimation.fillMode = CAMediaTimingFillMode.both 201 | 202 | if isShow { 203 | containerView.addSubview(toView) 204 | toView.layer.mask = maskLayer 205 | circleAnimation.fromValue = startPath 206 | circleAnimation.toValue = endPath 207 | } else { 208 | containerView.insertSubview(toView, belowSubview: fromView) 209 | fromView.layer.mask = maskLayer 210 | circleAnimation.fromValue = endPath 211 | circleAnimation.toValue = startPath 212 | } 213 | maskLayer.add(circleAnimation, forKey: "cirleAnimation") 214 | 215 | DispatchQueue.main.asyncAfter(deadline: .now() + animationDuration) { 216 | fromView.layer.mask = nil 217 | toView.layer.mask = nil 218 | self.transitionContext.completeTransition(!self.transitionContext.transitionWasCancelled) 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /PerformanceMonitorDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // PerformanceMonitorDemo 4 | // 5 | // Created by ming on 2019/8/24. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PerformanceMonitor 11 | import RCBacktrace 12 | 13 | extension AppDelegate: MethodTimeMonitorDelegate { 14 | 15 | func methodTimeMonitor(_ record: MethodTimeMonitorRecord) { 16 | print(record.description) 17 | } 18 | } 19 | 20 | @UIApplicationMain 21 | class AppDelegate: UIResponder, UIApplicationDelegate { 22 | 23 | var window: UIWindow? 24 | 25 | var performanceMonitor: PerformanceMonitor? 26 | 27 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 28 | 29 | RCBacktrace.setup() 30 | performanceMonitor = PerformanceMonitor(displayOptions: [.cpu, .memory, .fps, .fluecy]) 31 | performanceMonitor?.start() 32 | 33 | MethodTimeMonitor.traceBundle(containing: type(of: self)) 34 | MethodTimeMonitor.delegate = self 35 | 36 | return true 37 | } 38 | 39 | func applicationWillResignActive(_ application: UIApplication) { 40 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 41 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 42 | } 43 | 44 | func applicationDidEnterBackground(_ application: UIApplication) { 45 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 46 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 47 | } 48 | 49 | func applicationWillEnterForeground(_ application: UIApplication) { 50 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 51 | } 52 | 53 | func applicationDidBecomeActive(_ application: UIApplication) { 54 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | } 56 | 57 | func applicationWillTerminate(_ application: UIApplication) { 58 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 59 | } 60 | 61 | 62 | } 63 | 64 | -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Assets.xcassets/cat.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "cat.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Assets.xcassets/cat.imageset/cat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woshiccm/PerformanceMonitor/b40745906068295ecee0b47215a94fe3c550ce76/PerformanceMonitorDemo/Assets.xcassets/cat.imageset/cat.png -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Assets.xcassets/city.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "city.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Assets.xcassets/city.imageset/city.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/woshiccm/PerformanceMonitor/b40745906068295ecee0b47215a94fe3c550ce76/PerformanceMonitorDemo/Assets.xcassets/city.imageset/city.png -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /PerformanceMonitorDemo/FPSTestViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FPSTestViewController.swift 3 | // PerformanceMonitorDemo 4 | // 5 | // Created by roy.cao on 2019/8/26. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FPSTestViewController: UIViewController { 12 | 13 | lazy var tableView: UITableView = { 14 | let tableView = UITableView(frame: CGRect.zero, style: .plain) 15 | tableView.translatesAutoresizingMaskIntoConstraints = false 16 | tableView.backgroundColor = UIColor.clear 17 | tableView.separatorStyle = .none 18 | tableView.separatorColor = UIColor.clear 19 | tableView.indicatorStyle = .default 20 | tableView.dataSource = self 21 | tableView.delegate = self 22 | return tableView 23 | }() 24 | 25 | override func viewDidLoad() { 26 | super.viewDidLoad() 27 | view.backgroundColor = .white 28 | 29 | tableView.register(UITableViewCell.self, forCellReuseIdentifier: UITableViewCell.description()) 30 | view.addSubview(tableView) 31 | 32 | NSLayoutConstraint.activate([ 33 | tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), 34 | tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), 35 | tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), 36 | tableView.topAnchor.constraint(equalTo: view.topAnchor) 37 | ]) 38 | } 39 | } 40 | 41 | extension FPSTestViewController: UITableViewDataSource, UITableViewDelegate { 42 | 43 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 44 | return 200 45 | } 46 | 47 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 48 | let cell = tableView.dequeueReusableCell(withIdentifier: UITableViewCell.description(), for: indexPath) 49 | cell.imageView?.image = UIImage(named: "city") 50 | if (indexPath.row > 0 && indexPath.row % 10 == 0) { 51 | usleep(100000); 52 | } 53 | return cell 54 | } 55 | 56 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 57 | return 100.0 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /PerformanceMonitorDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /PerformanceMonitorDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // PerformanceMonitorDemo 4 | // 5 | // Created by roy.cao on 2019/8/24. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PerformanceMonitor 11 | 12 | class ViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | // let imgPrefix = self.imagePrefix() 18 | // var imageCount:UInt32 = 0 19 | // let images = objc_copyImageNames(&imageCount) 20 | // for i in 0 ..< imageCount { 21 | // let imagePath = String(cString: images[Int(i)]) 22 | // } 23 | } 24 | 25 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 26 | foo() 27 | let fpsVC = FPSTestViewController() 28 | self.navigationController?.pushViewController(fpsVC, animated: true) 29 | } 30 | 31 | func foo() { 32 | bar() 33 | } 34 | 35 | func bar() { 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /PerformanceMonitorTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /PerformanceMonitorTests/PerformanceMonitorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PerformanceMonitorTests.swift 3 | // PerformanceMonitorTests 4 | // 5 | // Created by roy.cao on 2019/8/24. 6 | // Copyright © 2019 roy. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import PerformanceMonitor 11 | 12 | class PerformanceMonitorTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform :ios, '10.0' 3 | use_frameworks! 4 | 5 | target 'PerformanceMonitor' do 6 | pod 'RCBacktrace', '~> 0.1.7' 7 | end 8 | 9 | target 'PerformanceMonitorDemo' do 10 | pod 'RCBacktrace', '~> 0.1.7' 11 | end 12 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - RCBacktrace (0.1.7) 3 | 4 | DEPENDENCIES: 5 | - RCBacktrace (~> 0.1.7) 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - RCBacktrace 10 | 11 | SPEC CHECKSUMS: 12 | RCBacktrace: cee4e073bfff3573f72eb433542705cdf7ffd98c 13 | 14 | PODFILE CHECKSUM: 6492b41268e5a841762ebc0e608cfbf40d34e44e 15 | 16 | COCOAPODS: 1.7.3 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PerformanceMonitor 2 | 3 | ![badge-pms](https://img.shields.io/badge/languages-Swift|ObjC-orange.svg) 4 | ![badge-platforms](https://img.shields.io/cocoapods/p/RCBacktrace.svg?style=flat) 5 | ![badge-languages](https://img.shields.io/badge/supports-Carthage|CocoaPods|SwiftPM-green.svg) 6 | [![Swift Version](https://img.shields.io/badge/Swift-4.0--5.0.x-F16D39.svg?style=flat)](https://developer.apple.com/swift) 7 | 8 | PerformanceMonitor is a non-invasive APM system, Including monitoring CPU,Memory,FPS,Recording all OC and Swift methods time consuming,etc. 9 | 10 | ## Plugin 11 | * CPUMonitor 12 | * MemoryMonitor 13 | * FPSMonitor 14 | * FluecyMonitor 15 | * SwiftTrace 16 | 17 | ## Features 18 | 19 | - [x] Monitor cup usage, record current thread call stack if the usage rate exceeds 80% 20 | - [x] Monitor memory usage 21 | - [x] Monitor fps 22 | - [x] Record main thread call stack if app is not fluecy 23 | - [x] Record all OC and Swift methods time consuming 24 | 25 | >Note: none of these features will work on a class or method that is final or internal in a module compiled with whole module optimisation as the dispatch of the method will be "direct" i.e. linked to a symbol at the call site rather than going through the class' vtable. 26 | 27 | ![Screen Shot 2019-09-08 at 4.09.41 PM.png](https://upload-images.jianshu.io/upload_images/2086987-4fec99a35eac32c5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 28 | 29 | 30 | ![Screen Shot 2019-09-10 at 6.10.47 PM.png](https://upload-images.jianshu.io/upload_images/2086987-a22d493c640dfc82.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 31 | 32 | ![Screen Shot 2019-09-10 at 6.11.04 PM.png](https://upload-images.jianshu.io/upload_images/2086987-c4db6903675d43b9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 33 | 34 | ## Usage 35 | 36 | ### setup 37 | 38 | ``` 39 | RCBacktrace.setup() 40 | performanceMonitor = PerformanceMonitor(displayOptions: [.cpu, .memory, .fps, .fluecy]) 41 | performanceMonitor?.start() 42 | SwiftTrace.traceBundle(containing: type(of: self)) 43 | 44 | ``` 45 | 46 | 47 | 48 | ≈ Requirements 49 | 50 | - iOS 8.0+ 51 | - Swift 4.0-5.x 52 | 53 | ## Next Steps 54 | 55 | * Use TableView to show records 56 | * Improve SwiftTrace, support more Swift methods 57 | 58 | ## Installation 59 | 60 | #### Carthage 61 | Add the following line to your [Cartfile](https://github.com/carthage/carthage) 62 | 63 | ``` 64 | git "https://github.com/woshiccm/PerformanceMonitor.git" "0.0.1" 65 | ``` 66 | 67 | ### CocoaPods 68 | [CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. To integrate Aspect into your Xcode project using CocoaPods, specify it in your `Podfile`: 69 | 70 | ``` 71 | source 'https://github.com/CocoaPods/Specs.git' 72 | platform :ios, '10.0' 73 | use_frameworks! 74 | 75 | target 'xxxx' do 76 | pod 'PerformanceMonitor', '~> 0.0.5' 77 | end 78 | 79 | ``` 80 | 81 | ##Thanks 82 | 83 | [SwiftTrace](https://github.com/johnno1962/SwiftTrace) 84 | [GDPerformanceView-Swift](https://github.com/dani-gavrilov/GDPerformanceView-Swift) 85 | [SystemEye](https://github.com/zixun/SystemEye) 86 | [AppPerformance](https://github.com/SilongLi/AppPerformance) 87 | 88 | ## License 89 | 90 | Aspect is released under the MIT license. See LICENSE for details. 91 | --------------------------------------------------------------------------------