| 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 18 matching lines...) Expand all Loading... |
| 29 /** | 29 /** |
| 30 * Creates a profile object for processing profiling-related events | 30 * Creates a profile object for processing profiling-related events |
| 31 * and calculating function execution times. | 31 * and calculating function execution times. |
| 32 * | 32 * |
| 33 * @constructor | 33 * @constructor |
| 34 */ | 34 */ |
| 35 function Profile() { | 35 function Profile() { |
| 36 this.codeMap_ = new CodeMap(); | 36 this.codeMap_ = new CodeMap(); |
| 37 this.topDownTree_ = new CallTree(); | 37 this.topDownTree_ = new CallTree(); |
| 38 this.bottomUpTree_ = new CallTree(); | 38 this.bottomUpTree_ = new CallTree(); |
| 39 this.c_entries_ = {}; |
| 39 }; | 40 }; |
| 40 | 41 |
| 41 | 42 |
| 42 /** | 43 /** |
| 43 * Returns whether a function with the specified name must be skipped. | 44 * Returns whether a function with the specified name must be skipped. |
| 44 * Should be overriden by subclasses. | 45 * Should be overriden by subclasses. |
| 45 * | 46 * |
| 46 * @param {string} name Function name. | 47 * @param {string} name Function name. |
| 47 */ | 48 */ |
| 48 Profile.prototype.skipThisFunction = function(name) { | 49 Profile.prototype.skipThisFunction = function(name) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 /** | 96 /** |
| 96 * Registers a library. | 97 * Registers a library. |
| 97 * | 98 * |
| 98 * @param {string} name Code entry name. | 99 * @param {string} name Code entry name. |
| 99 * @param {number} startAddr Starting address. | 100 * @param {number} startAddr Starting address. |
| 100 * @param {number} endAddr Ending address. | 101 * @param {number} endAddr Ending address. |
| 101 */ | 102 */ |
| 102 Profile.prototype.addLibrary = function( | 103 Profile.prototype.addLibrary = function( |
| 103 name, startAddr, endAddr) { | 104 name, startAddr, endAddr) { |
| 104 var entry = new CodeMap.CodeEntry( | 105 var entry = new CodeMap.CodeEntry( |
| 105 endAddr - startAddr, name); | 106 endAddr - startAddr, name, 'SHARED_LIB'); |
| 106 this.codeMap_.addLibrary(startAddr, entry); | 107 this.codeMap_.addLibrary(startAddr, entry); |
| 107 return entry; | 108 return entry; |
| 108 }; | 109 }; |
| 109 | 110 |
| 110 | 111 |
| 111 /** | 112 /** |
| 112 * Registers statically compiled code entry. | 113 * Registers statically compiled code entry. |
| 113 * | 114 * |
| 114 * @param {string} name Code entry name. | 115 * @param {string} name Code entry name. |
| 115 * @param {number} startAddr Starting address. | 116 * @param {number} startAddr Starting address. |
| 116 * @param {number} endAddr Ending address. | 117 * @param {number} endAddr Ending address. |
| 117 */ | 118 */ |
| 118 Profile.prototype.addStaticCode = function( | 119 Profile.prototype.addStaticCode = function( |
| 119 name, startAddr, endAddr) { | 120 name, startAddr, endAddr) { |
| 120 var entry = new CodeMap.CodeEntry( | 121 var entry = new CodeMap.CodeEntry( |
| 121 endAddr - startAddr, name); | 122 endAddr - startAddr, name, 'CPP'); |
| 122 this.codeMap_.addStaticCode(startAddr, entry); | 123 this.codeMap_.addStaticCode(startAddr, entry); |
| 123 return entry; | 124 return entry; |
| 124 }; | 125 }; |
| 125 | 126 |
| 126 | 127 |
| 127 /** | 128 /** |
| 128 * Registers dynamic (JIT-compiled) code entry. | 129 * Registers dynamic (JIT-compiled) code entry. |
| 129 * | 130 * |
| 130 * @param {string} type Code entry type. | 131 * @param {string} type Code entry type. |
| 131 * @param {string} name Code entry name. | 132 * @param {string} name Code entry name. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 | 244 |
| 244 | 245 |
| 245 /** | 246 /** |
| 246 * Translates addresses into function names and filters unneeded | 247 * Translates addresses into function names and filters unneeded |
| 247 * functions. | 248 * functions. |
| 248 * | 249 * |
| 249 * @param {Array<number>} stack Stack sample. | 250 * @param {Array<number>} stack Stack sample. |
| 250 */ | 251 */ |
| 251 Profile.prototype.resolveAndFilterFuncs_ = function(stack) { | 252 Profile.prototype.resolveAndFilterFuncs_ = function(stack) { |
| 252 var result = []; | 253 var result = []; |
| 254 var last_seen_c_function = ''; |
| 255 var look_for_first_c_function = false; |
| 253 for (var i = 0; i < stack.length; ++i) { | 256 for (var i = 0; i < stack.length; ++i) { |
| 254 var entry = this.codeMap_.findEntry(stack[i]); | 257 var entry = this.codeMap_.findEntry(stack[i]); |
| 255 if (entry) { | 258 if (entry) { |
| 256 var name = entry.getName(); | 259 var name = entry.getName(); |
| 260 if (i == 0 && (entry.type == 'CPP' || entry.type == 'SHARED_LIB')) { |
| 261 look_for_first_c_function = true; |
| 262 } |
| 263 if (look_for_first_c_function) { |
| 264 if (entry.type == 'CPP') { |
| 265 last_seen_c_function = name; |
| 266 } else if (i > 0 && last_seen_c_function != '') { |
| 267 if (this.c_entries_[last_seen_c_function] === undefined) { |
| 268 this.c_entries_[last_seen_c_function] = 0; |
| 269 } |
| 270 this.c_entries_[last_seen_c_function]++; |
| 271 look_for_first_c_function = false; // Found it, we're done. |
| 272 } |
| 273 } |
| 257 if (!this.skipThisFunction(name)) { | 274 if (!this.skipThisFunction(name)) { |
| 258 result.push(name); | 275 result.push(name); |
| 259 } | 276 } |
| 260 } else { | 277 } else { |
| 261 this.handleUnknownCode( | 278 this.handleUnknownCode( |
| 262 Profile.Operation.TICK, stack[i], i); | 279 Profile.Operation.TICK, stack[i], i); |
| 263 } | 280 } |
| 264 } | 281 } |
| 265 return result; | 282 return result; |
| 266 }; | 283 }; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 counters.root_ = root; | 391 counters.root_ = root; |
| 375 } else { | 392 } else { |
| 376 // Propagate weights so percents can be calculated correctly. | 393 // Propagate weights so percents can be calculated correctly. |
| 377 counters.getRoot().selfWeight = root.selfWeight; | 394 counters.getRoot().selfWeight = root.selfWeight; |
| 378 counters.getRoot().totalWeight = root.totalWeight; | 395 counters.getRoot().totalWeight = root.totalWeight; |
| 379 } | 396 } |
| 380 return counters; | 397 return counters; |
| 381 }; | 398 }; |
| 382 | 399 |
| 383 | 400 |
| 401 Profile.CEntryNode = function(name, ticks) { |
| 402 this.name = name; |
| 403 this.ticks = ticks; |
| 404 } |
| 405 |
| 406 |
| 407 Profile.prototype.getCEntryProfile = function() { |
| 408 var result = [new Profile.CEntryNode("TOTAL", 0)]; |
| 409 var total_ticks = 0; |
| 410 for (var f in this.c_entries_) { |
| 411 var ticks = this.c_entries_[f]; |
| 412 total_ticks += ticks; |
| 413 result.push(new Profile.CEntryNode(f, ticks)); |
| 414 } |
| 415 result[0].ticks = total_ticks; // Sorting will keep this at index 0. |
| 416 result.sort(function(n1, n2) { |
| 417 return n2.ticks - n1.ticks || (n2.name < n1.name ? -1 : 1) |
| 418 }); |
| 419 return result; |
| 420 } |
| 421 |
| 422 |
| 384 /** | 423 /** |
| 385 * Cleans up function entries that are not referenced by code entries. | 424 * Cleans up function entries that are not referenced by code entries. |
| 386 */ | 425 */ |
| 387 Profile.prototype.cleanUpFuncEntries = function() { | 426 Profile.prototype.cleanUpFuncEntries = function() { |
| 388 var referencedFuncEntries = []; | 427 var referencedFuncEntries = []; |
| 389 var entries = this.codeMap_.getAllDynamicEntriesWithAddresses(); | 428 var entries = this.codeMap_.getAllDynamicEntriesWithAddresses(); |
| 390 for (var i = 0, l = entries.length; i < l; ++i) { | 429 for (var i = 0, l = entries.length; i < l; ++i) { |
| 391 if (entries[i][1].constructor === Profile.FunctionEntry) { | 430 if (entries[i][1].constructor === Profile.FunctionEntry) { |
| 392 entries[i][1].used = false; | 431 entries[i][1].used = false; |
| 393 } | 432 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 408 | 447 |
| 409 /** | 448 /** |
| 410 * Creates a dynamic code entry. | 449 * Creates a dynamic code entry. |
| 411 * | 450 * |
| 412 * @param {number} size Code size. | 451 * @param {number} size Code size. |
| 413 * @param {string} type Code type. | 452 * @param {string} type Code type. |
| 414 * @param {string} name Function name. | 453 * @param {string} name Function name. |
| 415 * @constructor | 454 * @constructor |
| 416 */ | 455 */ |
| 417 Profile.DynamicCodeEntry = function(size, type, name) { | 456 Profile.DynamicCodeEntry = function(size, type, name) { |
| 418 CodeMap.CodeEntry.call(this, size, name); | 457 CodeMap.CodeEntry.call(this, size, name, type); |
| 419 this.type = type; | |
| 420 }; | 458 }; |
| 421 | 459 |
| 422 | 460 |
| 423 /** | 461 /** |
| 424 * Returns node name. | 462 * Returns node name. |
| 425 */ | 463 */ |
| 426 Profile.DynamicCodeEntry.prototype.getName = function() { | 464 Profile.DynamicCodeEntry.prototype.getName = function() { |
| 427 return this.type + ': ' + this.name; | 465 return this.type + ': ' + this.name; |
| 428 }; | 466 }; |
| 429 | 467 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 449 /** | 487 /** |
| 450 * Creates a dynamic code entry. | 488 * Creates a dynamic code entry. |
| 451 * | 489 * |
| 452 * @param {number} size Code size. | 490 * @param {number} size Code size. |
| 453 * @param {string} type Code type. | 491 * @param {string} type Code type. |
| 454 * @param {Profile.FunctionEntry} func Shared function entry. | 492 * @param {Profile.FunctionEntry} func Shared function entry. |
| 455 * @param {Profile.CodeState} state Code optimization state. | 493 * @param {Profile.CodeState} state Code optimization state. |
| 456 * @constructor | 494 * @constructor |
| 457 */ | 495 */ |
| 458 Profile.DynamicFuncCodeEntry = function(size, type, func, state) { | 496 Profile.DynamicFuncCodeEntry = function(size, type, func, state) { |
| 459 CodeMap.CodeEntry.call(this, size); | 497 CodeMap.CodeEntry.call(this, size, '', type); |
| 460 this.type = type; | |
| 461 this.func = func; | 498 this.func = func; |
| 462 this.state = state; | 499 this.state = state; |
| 463 }; | 500 }; |
| 464 | 501 |
| 465 Profile.DynamicFuncCodeEntry.STATE_PREFIX = ["", "~", "*"]; | 502 Profile.DynamicFuncCodeEntry.STATE_PREFIX = ["", "~", "*"]; |
| 466 | 503 |
| 467 /** | 504 /** |
| 468 * Returns node name. | 505 * Returns node name. |
| 469 */ | 506 */ |
| 470 Profile.DynamicFuncCodeEntry.prototype.getName = function() { | 507 Profile.DynamicFuncCodeEntry.prototype.getName = function() { |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 labels, opt_f) { | 823 labels, opt_f) { |
| 787 for (var pos = 0, curr = this; pos < labels.length && curr != null; pos++) { | 824 for (var pos = 0, curr = this; pos < labels.length && curr != null; pos++) { |
| 788 var child = curr.findChild(labels[pos]); | 825 var child = curr.findChild(labels[pos]); |
| 789 if (opt_f) { | 826 if (opt_f) { |
| 790 opt_f(child, pos); | 827 opt_f(child, pos); |
| 791 } | 828 } |
| 792 curr = child; | 829 curr = child; |
| 793 } | 830 } |
| 794 return curr; | 831 return curr; |
| 795 }; | 832 }; |
| OLD | NEW |