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 |