| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 /^(LoadGlobalIC: )|(Handler: )|(Stub: )|(Builtin: )|(BytecodeHandler: )|(?:C
allIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Load|Store)IC_)/; | 43 /^(LoadGlobalIC: )|(Handler: )|(Stub: )|(Builtin: )|(BytecodeHandler: )|(?:C
allIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Load|Store)IC_)/; |
| 44 | 44 |
| 45 | 45 |
| 46 /** | 46 /** |
| 47 * A thin wrapper around shell's 'read' function showing a file name on error. | 47 * A thin wrapper around shell's 'read' function showing a file name on error. |
| 48 */ | 48 */ |
| 49 function readFile(fileName) { | 49 function readFile(fileName) { |
| 50 try { | 50 try { |
| 51 return read(fileName); | 51 return read(fileName); |
| 52 } catch (e) { | 52 } catch (e) { |
| 53 print(fileName + ': ' + (e.message || e)); | 53 printErr(fileName + ': ' + (e.message || e)); |
| 54 throw e; | 54 throw e; |
| 55 } | 55 } |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 /** | 59 /** |
| 60 * Parser for dynamic code optimization state. | 60 * Parser for dynamic code optimization state. |
| 61 */ | 61 */ |
| 62 function parseState(s) { | 62 function parseState(s) { |
| 63 switch (s) { | 63 switch (s) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 74 separateIc, | 74 separateIc, |
| 75 callGraphSize, | 75 callGraphSize, |
| 76 ignoreUnknown, | 76 ignoreUnknown, |
| 77 stateFilter, | 77 stateFilter, |
| 78 distortion, | 78 distortion, |
| 79 range, | 79 range, |
| 80 sourceMap, | 80 sourceMap, |
| 81 timedRange, | 81 timedRange, |
| 82 pairwiseTimedRange, | 82 pairwiseTimedRange, |
| 83 onlySummary, | 83 onlySummary, |
| 84 runtimeTimerFilter) { | 84 runtimeTimerFilter, |
| 85 preprocessJson) { |
| 86 this.preprocessJson = preprocessJson; |
| 85 LogReader.call(this, { | 87 LogReader.call(this, { |
| 86 'shared-library': { parsers: [null, parseInt, parseInt, parseInt], | 88 'shared-library': { parsers: [null, parseInt, parseInt, parseInt], |
| 87 processor: this.processSharedLibrary }, | 89 processor: this.processSharedLibrary }, |
| 88 'code-creation': { | 90 'code-creation': { |
| 89 parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'], | 91 parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'], |
| 90 processor: this.processCodeCreation }, | 92 processor: this.processCodeCreation }, |
| 91 'code-move': { parsers: [parseInt, parseInt], | 93 'code-move': { parsers: [parseInt, parseInt], |
| 92 processor: this.processCodeMove }, | 94 processor: this.processCodeMove }, |
| 93 'code-delete': { parsers: [parseInt], | 95 'code-delete': { parsers: [parseInt], |
| 94 processor: this.processCodeDelete }, | 96 processor: this.processCodeDelete }, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 var range_end = parseInt(rangelimits[1]); | 144 var range_end = parseInt(rangelimits[1]); |
| 143 // Convert milliseconds to nanoseconds. | 145 // Convert milliseconds to nanoseconds. |
| 144 this.range_start = isNaN(range_start) ? -Infinity : (range_start * 1000); | 146 this.range_start = isNaN(range_start) ? -Infinity : (range_start * 1000); |
| 145 this.range_end = isNaN(range_end) ? Infinity : (range_end * 1000) | 147 this.range_end = isNaN(range_end) ? Infinity : (range_end * 1000) |
| 146 | 148 |
| 147 V8Profile.prototype.handleUnknownCode = function( | 149 V8Profile.prototype.handleUnknownCode = function( |
| 148 operation, addr, opt_stackPos) { | 150 operation, addr, opt_stackPos) { |
| 149 var op = Profile.Operation; | 151 var op = Profile.Operation; |
| 150 switch (operation) { | 152 switch (operation) { |
| 151 case op.MOVE: | 153 case op.MOVE: |
| 152 print('Code move event for unknown code: 0x' + addr.toString(16)); | 154 printErr('Code move event for unknown code: 0x' + addr.toString(16)); |
| 153 break; | 155 break; |
| 154 case op.DELETE: | 156 case op.DELETE: |
| 155 print('Code delete event for unknown code: 0x' + addr.toString(16)); | 157 printErr('Code delete event for unknown code: 0x' + addr.toString(16)); |
| 156 break; | 158 break; |
| 157 case op.TICK: | 159 case op.TICK: |
| 158 // Only unknown PCs (the first frame) are reported as unaccounted, | 160 // Only unknown PCs (the first frame) are reported as unaccounted, |
| 159 // otherwise tick balance will be corrupted (this behavior is compatible | 161 // otherwise tick balance will be corrupted (this behavior is compatible |
| 160 // with the original tickprocessor.py script.) | 162 // with the original tickprocessor.py script.) |
| 161 if (opt_stackPos == 0) { | 163 if (opt_stackPos == 0) { |
| 162 ticks.unaccounted++; | 164 ticks.unaccounted++; |
| 163 } | 165 } |
| 164 break; | 166 break; |
| 165 } | 167 } |
| 166 }; | 168 }; |
| 167 | 169 |
| 168 this.profile_ = new V8Profile(separateIc); | 170 if (preprocessJson) { |
| 171 this.profile_ = new JsonProfile(); |
| 172 } else { |
| 173 this.profile_ = new V8Profile(separateIc); |
| 174 } |
| 169 this.codeTypes_ = {}; | 175 this.codeTypes_ = {}; |
| 170 // Count each tick as a time unit. | 176 // Count each tick as a time unit. |
| 171 this.viewBuilder_ = new ViewBuilder(1); | 177 this.viewBuilder_ = new ViewBuilder(1); |
| 172 this.lastLogFileName_ = null; | 178 this.lastLogFileName_ = null; |
| 173 | 179 |
| 174 this.generation_ = 1; | 180 this.generation_ = 1; |
| 175 this.currentProducerProfile_ = null; | 181 this.currentProducerProfile_ = null; |
| 176 this.onlySummary_ = onlySummary; | 182 this.onlySummary_ = onlySummary; |
| 177 }; | 183 }; |
| 178 inherits(TickProcessor, LogReader); | 184 inherits(TickProcessor, LogReader); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 197 | 203 |
| 198 | 204 |
| 199 TickProcessor.CALL_PROFILE_CUTOFF_PCT = 2.0; | 205 TickProcessor.CALL_PROFILE_CUTOFF_PCT = 2.0; |
| 200 | 206 |
| 201 TickProcessor.CALL_GRAPH_SIZE = 5; | 207 TickProcessor.CALL_GRAPH_SIZE = 5; |
| 202 | 208 |
| 203 /** | 209 /** |
| 204 * @override | 210 * @override |
| 205 */ | 211 */ |
| 206 TickProcessor.prototype.printError = function(str) { | 212 TickProcessor.prototype.printError = function(str) { |
| 207 print(str); | 213 printErr(str); |
| 208 }; | 214 }; |
| 209 | 215 |
| 210 | 216 |
| 211 TickProcessor.prototype.setCodeType = function(name, type) { | 217 TickProcessor.prototype.setCodeType = function(name, type) { |
| 212 this.codeTypes_[name] = TickProcessor.CodeTypes[type]; | 218 this.codeTypes_[name] = TickProcessor.CodeTypes[type]; |
| 213 }; | 219 }; |
| 214 | 220 |
| 215 | 221 |
| 216 TickProcessor.prototype.isSharedLibrary = function(name) { | 222 TickProcessor.prototype.isSharedLibrary = function(name) { |
| 217 return this.codeTypes_[name] == TickProcessor.CodeTypes.SHARED_LIB; | 223 return this.codeTypes_[name] == TickProcessor.CodeTypes.SHARED_LIB; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 tos_or_external_callback = 0; | 332 tos_or_external_callback = 0; |
| 327 } else if (tos_or_external_callback) { | 333 } else if (tos_or_external_callback) { |
| 328 // Find out, if top of stack was pointing inside a JS function | 334 // Find out, if top of stack was pointing inside a JS function |
| 329 // meaning that we have encountered a frameless invocation. | 335 // meaning that we have encountered a frameless invocation. |
| 330 var funcEntry = this.profile_.findEntry(tos_or_external_callback); | 336 var funcEntry = this.profile_.findEntry(tos_or_external_callback); |
| 331 if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction()) { | 337 if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction()) { |
| 332 tos_or_external_callback = 0; | 338 tos_or_external_callback = 0; |
| 333 } | 339 } |
| 334 } | 340 } |
| 335 | 341 |
| 336 this.profile_.recordTick(this.processStack(pc, tos_or_external_callback, stack
)); | 342 this.profile_.recordTick( |
| 343 ns_since_start, vmState, |
| 344 this.processStack(pc, tos_or_external_callback, stack)); |
| 337 }; | 345 }; |
| 338 | 346 |
| 339 | 347 |
| 340 TickProcessor.prototype.advanceDistortion = function() { | 348 TickProcessor.prototype.advanceDistortion = function() { |
| 341 this.distortion += this.distortion_per_entry; | 349 this.distortion += this.distortion_per_entry; |
| 342 } | 350 } |
| 343 | 351 |
| 344 | 352 |
| 345 TickProcessor.prototype.processHeapSampleBegin = function(space, state, ticks) { | 353 TickProcessor.prototype.processHeapSampleBegin = function(space, state, ticks) { |
| 346 if (space != 'Heap') return; | 354 if (space != 'Heap') return; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 360 return rec2.totalTime - rec1.totalTime || | 368 return rec2.totalTime - rec1.totalTime || |
| 361 (rec2.internalFuncName < rec1.internalFuncName ? -1 : 1); }); | 369 (rec2.internalFuncName < rec1.internalFuncName ? -1 : 1); }); |
| 362 this.printHeavyProfile(producersView.head.children); | 370 this.printHeavyProfile(producersView.head.children); |
| 363 | 371 |
| 364 this.currentProducerProfile_ = null; | 372 this.currentProducerProfile_ = null; |
| 365 this.generation_++; | 373 this.generation_++; |
| 366 }; | 374 }; |
| 367 | 375 |
| 368 | 376 |
| 369 TickProcessor.prototype.printStatistics = function() { | 377 TickProcessor.prototype.printStatistics = function() { |
| 378 if (this.preprocessJson) { |
| 379 this.profile_.writeJson(); |
| 380 return; |
| 381 } |
| 382 |
| 370 print('Statistical profiling result from ' + this.lastLogFileName_ + | 383 print('Statistical profiling result from ' + this.lastLogFileName_ + |
| 371 ', (' + this.ticks_.total + | 384 ', (' + this.ticks_.total + |
| 372 ' ticks, ' + this.ticks_.unaccounted + ' unaccounted, ' + | 385 ' ticks, ' + this.ticks_.unaccounted + ' unaccounted, ' + |
| 373 this.ticks_.excluded + ' excluded).'); | 386 this.ticks_.excluded + ' excluded).'); |
| 374 | 387 |
| 375 if (this.ticks_.total == 0) return; | 388 if (this.ticks_.total == 0) return; |
| 376 | 389 |
| 377 var flatProfile = this.profile_.getFlatProfile(); | 390 var flatProfile = this.profile_.getFlatProfile(); |
| 378 var flatView = this.viewBuilder_.buildView(flatProfile); | 391 var flatView = this.viewBuilder_.buildView(flatProfile); |
| 379 // Sort by self time, desc, then by name, desc. | 392 // Sort by self time, desc, then by name, desc. |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 funcInfo.size = parseInt(fields[2], 16); | 682 funcInfo.size = parseInt(fields[2], 16); |
| 670 } | 683 } |
| 671 } | 684 } |
| 672 return funcInfo; | 685 return funcInfo; |
| 673 }; | 686 }; |
| 674 | 687 |
| 675 | 688 |
| 676 function MacCppEntriesProvider(nmExec, targetRootFS) { | 689 function MacCppEntriesProvider(nmExec, targetRootFS) { |
| 677 UnixCppEntriesProvider.call(this, nmExec, targetRootFS); | 690 UnixCppEntriesProvider.call(this, nmExec, targetRootFS); |
| 678 // Note an empty group. It is required, as UnixCppEntriesProvider expects 3 gr
oups. | 691 // Note an empty group. It is required, as UnixCppEntriesProvider expects 3 gr
oups. |
| 679 this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ()[iItT] (.*)$/; | 692 this.FUNC_RE = /^([0-9a-fA-F]{8,16})() (.*)$/; |
| 680 }; | 693 }; |
| 681 inherits(MacCppEntriesProvider, UnixCppEntriesProvider); | 694 inherits(MacCppEntriesProvider, UnixCppEntriesProvider); |
| 682 | 695 |
| 683 | 696 |
| 684 MacCppEntriesProvider.prototype.loadSymbols = function(libName) { | 697 MacCppEntriesProvider.prototype.loadSymbols = function(libName) { |
| 685 this.parsePos = 0; | 698 this.parsePos = 0; |
| 686 libName = this.targetRootFS + libName; | 699 libName = this.targetRootFS + libName; |
| 687 | 700 |
| 688 // It seems that in OS X `nm` thinks that `-f` is a format option, not a | 701 // It seems that in OS X `nm` thinks that `-f` is a format option, not a |
| 689 // "flat" display option flag. | 702 // "flat" display option flag. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 'Specify the range limit as [start],[end]'], | 829 'Specify the range limit as [start],[end]'], |
| 817 '--distortion': ['distortion', 0, | 830 '--distortion': ['distortion', 0, |
| 818 'Specify the logging overhead in picoseconds'], | 831 'Specify the logging overhead in picoseconds'], |
| 819 '--source-map': ['sourceMap', null, | 832 '--source-map': ['sourceMap', null, |
| 820 'Specify the source map that should be used for output'], | 833 'Specify the source map that should be used for output'], |
| 821 '--timed-range': ['timedRange', true, | 834 '--timed-range': ['timedRange', true, |
| 822 'Ignore ticks before first and after last Date.now() call'], | 835 'Ignore ticks before first and after last Date.now() call'], |
| 823 '--pairwise-timed-range': ['pairwiseTimedRange', true, | 836 '--pairwise-timed-range': ['pairwiseTimedRange', true, |
| 824 'Ignore ticks outside pairs of Date.now() calls'], | 837 'Ignore ticks outside pairs of Date.now() calls'], |
| 825 '--only-summary': ['onlySummary', true, | 838 '--only-summary': ['onlySummary', true, |
| 826 'Print only tick summary, exclude other information'] | 839 'Print only tick summary, exclude other information'], |
| 840 '--preprocess': ['preprocessJson', true, |
| 841 'Preprocess for consumption with web interface'] |
| 827 }; | 842 }; |
| 828 this.argsDispatch_['--js'] = this.argsDispatch_['-j']; | 843 this.argsDispatch_['--js'] = this.argsDispatch_['-j']; |
| 829 this.argsDispatch_['--gc'] = this.argsDispatch_['-g']; | 844 this.argsDispatch_['--gc'] = this.argsDispatch_['-g']; |
| 830 this.argsDispatch_['--compiler'] = this.argsDispatch_['-c']; | 845 this.argsDispatch_['--compiler'] = this.argsDispatch_['-c']; |
| 831 this.argsDispatch_['--other'] = this.argsDispatch_['-o']; | 846 this.argsDispatch_['--other'] = this.argsDispatch_['-o']; |
| 832 this.argsDispatch_['--external'] = this.argsDispatch_['-e']; | 847 this.argsDispatch_['--external'] = this.argsDispatch_['-e']; |
| 833 this.argsDispatch_['--ptr'] = this.argsDispatch_['--pairwise-timed-range']; | 848 this.argsDispatch_['--ptr'] = this.argsDispatch_['--pairwise-timed-range']; |
| 834 }; | 849 }; |
| 835 | 850 |
| 836 | 851 |
| 837 ArgumentsProcessor.DEFAULTS = { | 852 ArgumentsProcessor.DEFAULTS = { |
| 838 logFileName: 'v8.log', | 853 logFileName: 'v8.log', |
| 839 platform: 'unix', | 854 platform: 'unix', |
| 840 stateFilter: null, | 855 stateFilter: null, |
| 841 callGraphSize: 5, | 856 callGraphSize: 5, |
| 842 ignoreUnknown: false, | 857 ignoreUnknown: false, |
| 843 separateIc: false, | 858 separateIc: false, |
| 859 preprocessJson: null, |
| 844 targetRootFS: '', | 860 targetRootFS: '', |
| 845 nm: 'nm', | 861 nm: 'nm', |
| 846 range: 'auto,auto', | 862 range: 'auto,auto', |
| 847 distortion: 0, | 863 distortion: 0, |
| 848 timedRange: false, | 864 timedRange: false, |
| 849 pairwiseTimedRange: false, | 865 pairwiseTimedRange: false, |
| 850 onlySummary: false, | 866 onlySummary: false, |
| 851 runtimeTimerFilter: null, | 867 runtimeTimerFilter: null, |
| 852 }; | 868 }; |
| 853 | 869 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 901 for (var synArg in this.argsDispatch_) { | 917 for (var synArg in this.argsDispatch_) { |
| 902 if (arg !== synArg && dispatch === this.argsDispatch_[synArg]) { | 918 if (arg !== synArg && dispatch === this.argsDispatch_[synArg]) { |
| 903 synonyms.push(synArg); | 919 synonyms.push(synArg); |
| 904 delete this.argsDispatch_[synArg]; | 920 delete this.argsDispatch_[synArg]; |
| 905 } | 921 } |
| 906 } | 922 } |
| 907 print(' ' + padRight(synonyms.join(', '), 20) + " " + dispatch[2]); | 923 print(' ' + padRight(synonyms.join(', '), 20) + " " + dispatch[2]); |
| 908 } | 924 } |
| 909 quit(2); | 925 quit(2); |
| 910 }; | 926 }; |
| OLD | NEW |