| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 TickProcessor.VmStates = { | 92 TickProcessor.VmStates = { |
| 93 JS: 0, | 93 JS: 0, |
| 94 GC: 1, | 94 GC: 1, |
| 95 COMPILER: 2, | 95 COMPILER: 2, |
| 96 OTHER: 3, | 96 OTHER: 3, |
| 97 EXTERNAL: 4 | 97 EXTERNAL: 4 |
| 98 }; | 98 }; |
| 99 | 99 |
| 100 | 100 |
| 101 TickProcessor.CodeTypes = { | 101 TickProcessor.CodeTypes = { |
| 102 JS: 0, | 102 CPP: 0, |
| 103 CPP: 1, | 103 SHARED_LIB: 1 |
| 104 SHARED_LIB: 2 | |
| 105 }; | 104 }; |
| 105 // Otherwise, this is JS-related code. We are not adding it to |
| 106 // codeTypes_ map because there can be zillions of them. |
| 106 | 107 |
| 107 | 108 |
| 108 TickProcessor.RecordsDispatch = { | 109 TickProcessor.RecordsDispatch = { |
| 109 'shared-library': { parsers: [null, parseInt, parseInt], | 110 'shared-library': { parsers: [null, parseInt, parseInt], |
| 110 processor: 'processSharedLibrary' }, | 111 processor: 'processSharedLibrary' }, |
| 111 'code-creation': { parsers: [null, parseInt, parseInt, null], | 112 'code-creation': { parsers: [null, parseInt, parseInt, null], |
| 112 processor: 'processCodeCreation' }, | 113 processor: 'processCodeCreation' }, |
| 113 'code-move': { parsers: [parseInt, parseInt], | 114 'code-move': { parsers: [parseInt, parseInt], |
| 114 processor: 'processCodeMove' }, | 115 processor: 'processCodeMove' }, |
| 115 'code-delete': { parsers: [parseInt], processor: 'processCodeDelete' }, | 116 'code-delete': { parsers: [parseInt], processor: 'processCodeDelete' }, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 135 return this.codeTypes_[name] == TickProcessor.CodeTypes.SHARED_LIB; | 136 return this.codeTypes_[name] == TickProcessor.CodeTypes.SHARED_LIB; |
| 136 }; | 137 }; |
| 137 | 138 |
| 138 | 139 |
| 139 TickProcessor.prototype.isCppCode = function(name) { | 140 TickProcessor.prototype.isCppCode = function(name) { |
| 140 return this.codeTypes_[name] == TickProcessor.CodeTypes.CPP; | 141 return this.codeTypes_[name] == TickProcessor.CodeTypes.CPP; |
| 141 }; | 142 }; |
| 142 | 143 |
| 143 | 144 |
| 144 TickProcessor.prototype.isJsCode = function(name) { | 145 TickProcessor.prototype.isJsCode = function(name) { |
| 145 return this.codeTypes_[name] == TickProcessor.CodeTypes.JS; | 146 return !(name in this.codeTypes_); |
| 146 }; | 147 }; |
| 147 | 148 |
| 148 | 149 |
| 149 TickProcessor.prototype.processLogFile = function(fileName) { | 150 TickProcessor.prototype.processLogFile = function(fileName) { |
| 150 this.lastLogFileName_ = fileName; | 151 this.lastLogFileName_ = fileName; |
| 151 var contents = readFile(fileName); | 152 var contents = readFile(fileName); |
| 152 this.processLog(contents.split('\n')); | 153 this.processLog(contents.split('\n')); |
| 153 }; | 154 }; |
| 154 | 155 |
| 155 | 156 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 name, startAddr, endAddr, function(fName, fStart, fEnd) { | 214 name, startAddr, endAddr, function(fName, fStart, fEnd) { |
| 214 self.profile_.addStaticCode(fName, fStart, fEnd); | 215 self.profile_.addStaticCode(fName, fStart, fEnd); |
| 215 self.setCodeType(fName, 'CPP'); | 216 self.setCodeType(fName, 'CPP'); |
| 216 }); | 217 }); |
| 217 }; | 218 }; |
| 218 | 219 |
| 219 | 220 |
| 220 TickProcessor.prototype.processCodeCreation = function( | 221 TickProcessor.prototype.processCodeCreation = function( |
| 221 type, start, size, name) { | 222 type, start, size, name) { |
| 222 var entry = this.profile_.addCode(type, name, start, size); | 223 var entry = this.profile_.addCode(type, name, start, size); |
| 223 this.setCodeType(entry.getName(), 'JS'); | |
| 224 }; | 224 }; |
| 225 | 225 |
| 226 | 226 |
| 227 TickProcessor.prototype.processCodeMove = function(from, to) { | 227 TickProcessor.prototype.processCodeMove = function(from, to) { |
| 228 this.profile_.moveCode(from, to); | 228 this.profile_.moveCode(from, to); |
| 229 }; | 229 }; |
| 230 | 230 |
| 231 | 231 |
| 232 TickProcessor.prototype.processCodeDelete = function(start) { | 232 TickProcessor.prototype.processCodeDelete = function(start) { |
| 233 this.profile_.deleteCode(start); | 233 this.profile_.deleteCode(start); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 }); | 408 }); |
| 409 }; | 409 }; |
| 410 | 410 |
| 411 | 411 |
| 412 function CppEntriesProvider() { | 412 function CppEntriesProvider() { |
| 413 }; | 413 }; |
| 414 | 414 |
| 415 | 415 |
| 416 CppEntriesProvider.prototype.parseVmSymbols = function( | 416 CppEntriesProvider.prototype.parseVmSymbols = function( |
| 417 libName, libStart, libEnd, processorFunc) { | 417 libName, libStart, libEnd, processorFunc) { |
| 418 var syms = this.loadSymbols(libName); | 418 this.loadSymbols(libName); |
| 419 if (syms.length == 0) return; | |
| 420 | 419 |
| 421 var prevEntry; | 420 var prevEntry; |
| 422 | 421 |
| 423 function addPrevEntry(end) { | 422 function addPrevEntry(end) { |
| 424 // Several functions can be mapped onto the same address. To avoid | 423 // Several functions can be mapped onto the same address. To avoid |
| 425 // creating zero-sized entries, skip such duplicates. | 424 // creating zero-sized entries, skip such duplicates. |
| 426 if (prevEntry && prevEntry.start != end) { | 425 if (prevEntry && prevEntry.start != end) { |
| 427 processorFunc(prevEntry.name, prevEntry.start, end); | 426 processorFunc(prevEntry.name, prevEntry.start, end); |
| 428 } | 427 } |
| 429 } | 428 } |
| 430 | 429 |
| 431 for (var i = 0, n = syms.length; i < n; ++i) { | 430 while (true) { |
| 432 var line = syms[i]; | 431 var funcInfo = this.parseNextLine(); |
| 433 var funcInfo = this.parseLine(line); | 432 if (funcInfo === null) { |
| 434 if (!funcInfo) { | |
| 435 continue; | 433 continue; |
| 434 } else if (funcInfo === false) { |
| 435 break; |
| 436 } | 436 } |
| 437 if (funcInfo.start < libStart && funcInfo.start < libEnd - libStart) { | 437 if (funcInfo.start < libStart && funcInfo.start < libEnd - libStart) { |
| 438 funcInfo.start += libStart; | 438 funcInfo.start += libStart; |
| 439 } | 439 } |
| 440 addPrevEntry(funcInfo.start); | 440 addPrevEntry(funcInfo.start); |
| 441 prevEntry = funcInfo; | 441 prevEntry = funcInfo; |
| 442 } | 442 } |
| 443 addPrevEntry(libEnd); | 443 addPrevEntry(libEnd); |
| 444 }; | 444 }; |
| 445 | 445 |
| 446 | 446 |
| 447 CppEntriesProvider.prototype.loadSymbols = function(libName) { | 447 CppEntriesProvider.prototype.loadSymbols = function(libName) { |
| 448 return []; | |
| 449 }; | 448 }; |
| 450 | 449 |
| 451 | 450 |
| 452 CppEntriesProvider.prototype.parseLine = function(line) { | 451 CppEntriesProvider.prototype.parseNextLine = function() { |
| 453 return { name: '', start: 0 }; | 452 return false; |
| 454 }; | 453 }; |
| 455 | 454 |
| 456 | 455 |
| 457 function inherits(childCtor, parentCtor) { | 456 function inherits(childCtor, parentCtor) { |
| 458 function tempCtor() {}; | 457 function tempCtor() {}; |
| 459 tempCtor.prototype = parentCtor.prototype; | 458 tempCtor.prototype = parentCtor.prototype; |
| 460 childCtor.prototype = new tempCtor(); | 459 childCtor.prototype = new tempCtor(); |
| 461 }; | 460 }; |
| 462 | 461 |
| 463 | 462 |
| 464 function UnixCppEntriesProvider() { | 463 function UnixCppEntriesProvider() { |
| 464 this.symbols = []; |
| 465 this.parsePos = 0; |
| 465 }; | 466 }; |
| 466 inherits(UnixCppEntriesProvider, CppEntriesProvider); | 467 inherits(UnixCppEntriesProvider, CppEntriesProvider); |
| 467 | 468 |
| 468 | 469 |
| 469 UnixCppEntriesProvider.FUNC_RE = /^([0-9a-fA-F]{8}) . (.*)$/; | 470 UnixCppEntriesProvider.FUNC_RE = /^([0-9a-fA-F]{8}) . (.*)$/; |
| 470 | 471 |
| 471 | 472 |
| 472 UnixCppEntriesProvider.prototype.loadSymbols = function(libName) { | 473 UnixCppEntriesProvider.prototype.loadSymbols = function(libName) { |
| 473 var normalSyms = os.system('nm', ['-C', '-n', libName], -1, -1); | 474 this.symbols = [ |
| 474 var dynaSyms = os.system('nm', ['-C', '-n', '-D', libName], -1, -1); | 475 os.system('nm', ['-C', '-n', libName], -1, -1), |
| 475 var syms = (normalSyms + dynaSyms).split('\n'); | 476 os.system('nm', ['-C', '-n', '-D', libName], -1, -1) |
| 476 return syms; | 477 ]; |
| 478 this.parsePos = 0; |
| 477 }; | 479 }; |
| 478 | 480 |
| 479 | 481 |
| 480 UnixCppEntriesProvider.prototype.parseLine = function(line) { | 482 UnixCppEntriesProvider.prototype.parseNextLine = function() { |
| 483 if (this.symbols.length == 0) { |
| 484 return false; |
| 485 } |
| 486 var lineEndPos = this.symbols[0].indexOf('\n', this.parsePos); |
| 487 if (lineEndPos == -1) { |
| 488 this.symbols.shift(); |
| 489 this.parsePos = 0; |
| 490 return this.parseNextLine(); |
| 491 } |
| 492 |
| 493 var line = this.symbols[0].substring(this.parsePos, lineEndPos); |
| 494 this.parsePos = lineEndPos + 1; |
| 481 var fields = line.match(UnixCppEntriesProvider.FUNC_RE); | 495 var fields = line.match(UnixCppEntriesProvider.FUNC_RE); |
| 482 return fields ? { name: fields[2], start: parseInt(fields[1], 16) } : null; | 496 return fields ? { name: fields[2], start: parseInt(fields[1], 16) } : null; |
| 483 }; | 497 }; |
| 484 | 498 |
| 485 | 499 |
| 486 function WindowsCppEntriesProvider() { | 500 function WindowsCppEntriesProvider() { |
| 501 this.symbols = ''; |
| 502 this.parsePos = 0; |
| 487 }; | 503 }; |
| 488 inherits(WindowsCppEntriesProvider, CppEntriesProvider); | 504 inherits(WindowsCppEntriesProvider, CppEntriesProvider); |
| 489 | 505 |
| 490 | 506 |
| 491 WindowsCppEntriesProvider.FILENAME_RE = /^(.*)\.exe$/; | 507 WindowsCppEntriesProvider.FILENAME_RE = /^(.*)\.exe$/; |
| 492 | 508 |
| 493 | 509 |
| 494 WindowsCppEntriesProvider.FUNC_RE = | 510 WindowsCppEntriesProvider.FUNC_RE = |
| 495 /^ 0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/; | 511 /^ 0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/; |
| 496 | 512 |
| 497 | 513 |
| 498 WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) { | 514 WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) { |
| 499 var fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE); | 515 var fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE); |
| 500 // Only try to load symbols for the .exe file. | 516 // Only try to load symbols for the .exe file. |
| 501 if (!fileNameFields) return []; | 517 if (!fileNameFields) return; |
| 502 var mapFileName = fileNameFields[1] + '.map'; | 518 var mapFileName = fileNameFields[1] + '.map'; |
| 503 return readFile(mapFileName).split('\r\n'); | 519 this.symbols = readFile(mapFileName); |
| 504 }; | 520 }; |
| 505 | 521 |
| 506 | 522 |
| 507 WindowsCppEntriesProvider.prototype.parseLine = function(line) { | 523 WindowsCppEntriesProvider.prototype.parseNextLine = function() { |
| 524 var lineEndPos = this.symbols.indexOf('\r\n', this.parsePos); |
| 525 if (lineEndPos == -1) { |
| 526 return false; |
| 527 } |
| 528 |
| 529 var line = this.symbols.substring(this.parsePos, lineEndPos); |
| 530 this.parsePos = lineEndPos + 2; |
| 508 var fields = line.match(WindowsCppEntriesProvider.FUNC_RE); | 531 var fields = line.match(WindowsCppEntriesProvider.FUNC_RE); |
| 509 return fields ? | 532 return fields ? |
| 510 { name: this.unmangleName(fields[1]), start: parseInt(fields[2], 16) } : | 533 { name: this.unmangleName(fields[1]), start: parseInt(fields[2], 16) } : |
| 511 null; | 534 null; |
| 512 }; | 535 }; |
| 513 | 536 |
| 514 | 537 |
| 515 /** | 538 /** |
| 516 * Performs very simple unmangling of C++ names. | 539 * Performs very simple unmangling of C++ names. |
| 517 * | 540 * |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 637 |
| 615 var params = processArguments(arguments); | 638 var params = processArguments(arguments); |
| 616 var tickProcessor = new TickProcessor( | 639 var tickProcessor = new TickProcessor( |
| 617 params.platform == 'unix' ? new UnixCppEntriesProvider() : | 640 params.platform == 'unix' ? new UnixCppEntriesProvider() : |
| 618 new WindowsCppEntriesProvider(), | 641 new WindowsCppEntriesProvider(), |
| 619 params.separateIc, | 642 params.separateIc, |
| 620 params.ignoreUnknown, | 643 params.ignoreUnknown, |
| 621 params.stateFilter); | 644 params.stateFilter); |
| 622 tickProcessor.processLogFile(params.logFileName); | 645 tickProcessor.processLogFile(params.logFileName); |
| 623 tickProcessor.printStatistics(); | 646 tickProcessor.printStatistics(); |
| OLD | NEW |