Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 WebInspector.TimelineJSProfileProcessor = { }; | 6 WebInspector.TimelineJSProfileProcessor = { }; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * @param {!ProfilerAgent.CPUProfile} jsProfile | 9 * @param {!ProfilerAgent.CPUProfile} jsProfile |
| 10 * @param {!WebInspector.TracingModel.Thread} thread | 10 * @param {!WebInspector.TracingModel.Thread} thread |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 }, | 244 }, |
| 245 | 245 |
| 246 /** | 246 /** |
| 247 * @param {string} oldAddressHex | 247 * @param {string} oldAddressHex |
| 248 * @param {string} newAddressHex | 248 * @param {string} newAddressHex |
| 249 * @param {number} size | 249 * @param {number} size |
| 250 */ | 250 */ |
| 251 moveEntry: function(oldAddressHex, newAddressHex, size) | 251 moveEntry: function(oldAddressHex, newAddressHex, size) |
| 252 { | 252 { |
| 253 var entry = this._getBank(oldAddressHex).removeEntry(this._getAddress(ol dAddressHex)); | 253 var entry = this._getBank(oldAddressHex).removeEntry(this._getAddress(ol dAddressHex)); |
| 254 if (!entry) { | 254 if (!entry) |
| 255 console.error("Entry at address " + oldAddressHex + " not found"); | |
|
yurys
2015/06/24 13:57:44
Why was this removed? Is there a valid case when w
alph
2015/06/24 14:03:38
Reverted.
| |
| 256 return; | 255 return; |
| 257 } | |
| 258 entry.address = this._getAddress(newAddressHex); | 256 entry.address = this._getAddress(newAddressHex); |
| 259 entry.size = size; | 257 entry.size = size; |
| 260 this._addEntry(newAddressHex, entry); | 258 this._addEntry(newAddressHex, entry); |
| 261 }, | 259 }, |
| 262 | 260 |
| 263 /** | 261 /** |
| 264 * @param {string} addressHex | 262 * @param {string} addressHex |
| 265 * @return {?ConsoleAgent.CallFrame} | 263 * @return {?ConsoleAgent.CallFrame} |
| 266 */ | 264 */ |
| 267 lookupEntry: function(addressHex) | 265 lookupEntry: function(addressHex) |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 var entryEndAddress = entry.address + entry.size; | 357 var entryEndAddress = entry.address + entry.size; |
| 360 if (entryEndAddress <= newEntry.address) | 358 if (entryEndAddress <= newEntry.address) |
| 361 break; | 359 break; |
| 362 } | 360 } |
| 363 ++index; | 361 ++index; |
| 364 this._entries.splice(index, lastIndex - index, newEntry); | 362 this._entries.splice(index, lastIndex - index, newEntry); |
| 365 } | 363 } |
| 366 } | 364 } |
| 367 | 365 |
| 368 /** | 366 /** |
| 369 * @param {string} functionName | |
| 370 * @param {string=} url | |
| 371 * @param {string=} scriptId | |
| 372 * @param {number=} line | |
| 373 * @param {number=} column | |
| 374 * @return {!ConsoleAgent.CallFrame} | |
| 375 */ | |
| 376 WebInspector.TimelineJSProfileProcessor._createFrame = function(functionName, ur l, scriptId, line, column) | |
| 377 { | |
| 378 return /** @type {!ConsoleAgent.CallFrame} */ ({ | |
| 379 "functionName": functionName, | |
| 380 "url": url || "", | |
| 381 "scriptId": scriptId || "0", | |
| 382 "lineNumber": line || 0, | |
| 383 "columnNumber": column || 0 | |
| 384 }); | |
| 385 } | |
| 386 | |
| 387 /** | |
| 388 * @param {string} name | 367 * @param {string} name |
| 389 * @param {number} scriptId | 368 * @param {number} scriptId |
| 390 * @return {!ConsoleAgent.CallFrame} | 369 * @return {!ConsoleAgent.CallFrame} |
| 391 */ | 370 */ |
| 392 WebInspector.TimelineJSProfileProcessor._buildCallFrame = function(name, scriptI d) | 371 WebInspector.TimelineJSProfileProcessor._buildCallFrame = function(name, scriptI d) |
| 393 { | 372 { |
| 373 /** | |
| 374 * @param {string} functionName | |
| 375 * @param {string=} url | |
| 376 * @param {string=} scriptId | |
| 377 * @param {number=} line | |
| 378 * @param {number=} column | |
| 379 * @param {boolean=} isNative | |
| 380 * @return {!ConsoleAgent.CallFrame} | |
| 381 */ | |
| 382 function createFrame(functionName, url, scriptId, line, column, isNative) | |
| 383 { | |
| 384 return /** @type {!ConsoleAgent.CallFrame} */ ({ | |
| 385 "functionName": functionName, | |
| 386 "url": url || "", | |
| 387 "scriptId": scriptId || "0", | |
| 388 "lineNumber": line || 0, | |
| 389 "columnNumber": column || 0, | |
| 390 "isNative": isNative || false | |
| 391 }); | |
| 392 } | |
| 393 | |
| 394 // Code states: | 394 // Code states: |
| 395 // (empty) -> compiled | 395 // (empty) -> compiled |
| 396 // ~ -> optimizable | 396 // ~ -> optimizable |
| 397 // * -> optimized | 397 // * -> optimized |
| 398 var rePrefix = /^(\w*:)?[*~]?(.*)$/m; | 398 var rePrefix = /^(\w*:)?[*~]?(.*)$/m; |
| 399 | |
| 400 var tokens = rePrefix.exec(name); | 399 var tokens = rePrefix.exec(name); |
| 401 var prefix = tokens[1]; | 400 var prefix = tokens[1]; |
| 402 var body = tokens[2]; | 401 var body = tokens[2]; |
| 403 var rawName; | 402 var rawName; |
| 404 var rawUrl; | 403 var rawUrl; |
| 405 if (prefix === "Script:") { | 404 if (prefix === "Script:") { |
| 406 rawName = ""; | 405 rawName = ""; |
| 407 rawUrl = body; | 406 rawUrl = body; |
| 408 } else { | 407 } else { |
| 409 var spacePos = body.lastIndexOf(" "); | 408 var spacePos = body.lastIndexOf(" "); |
| 410 rawName = spacePos !== -1 ? body.substr(0, spacePos) : body; | 409 rawName = spacePos !== -1 ? body.substr(0, spacePos) : body; |
| 411 rawUrl = spacePos !== -1 ? body.substr(spacePos + 1) : ""; | 410 rawUrl = spacePos !== -1 ? body.substr(spacePos + 1) : ""; |
| 412 } | 411 } |
| 413 var functionName = rawName; | 412 var nativeSuffix = " native"; |
| 413 var isNative = rawName.endsWith(nativeSuffix); | |
| 414 var functionName = isNative ? rawName.slice(0, -nativeSuffix.length) : rawNa me; | |
| 414 var urlData = WebInspector.ParsedURL.splitLineAndColumn(rawUrl); | 415 var urlData = WebInspector.ParsedURL.splitLineAndColumn(rawUrl); |
| 415 var url = urlData.url || ""; | 416 var url = urlData.url || ""; |
| 416 var line = urlData.lineNumber || 0; | 417 var line = urlData.lineNumber || 0; |
| 417 var column = urlData.columnNumber || 0; | 418 var column = urlData.columnNumber || 0; |
| 418 return WebInspector.TimelineJSProfileProcessor._createFrame(functionName, ur l, String(scriptId), line, column); | 419 return createFrame(functionName, url, String(scriptId), line, column, isNati ve); |
| 419 } | 420 } |
| 420 | 421 |
| 421 /** | 422 /** |
| 422 * @param {!Array<!WebInspector.TracingModel.Event>} events | 423 * @param {!Array<!WebInspector.TracingModel.Event>} events |
| 423 * @return {!Array<!WebInspector.TracingModel.Event>} | 424 * @return {!Array<!WebInspector.TracingModel.Event>} |
| 424 */ | 425 */ |
| 425 WebInspector.TimelineJSProfileProcessor.processRawV8Samples = function(events) | 426 WebInspector.TimelineJSProfileProcessor.processRawV8Samples = function(events) |
| 426 { | 427 { |
| 427 var missingAddesses = new Set(); | 428 var missingAddesses = new Set(); |
| 428 | 429 |
| 429 /** | 430 /** |
| 430 * @param {string} address | 431 * @param {string} address |
| 431 * @return {!ConsoleAgent.CallFrame} | 432 * @return {?ConsoleAgent.CallFrame} |
| 432 */ | 433 */ |
| 433 function convertRawFrame(address) | 434 function convertRawFrame(address) |
| 434 { | 435 { |
| 435 var entry = codeMap.lookupEntry(address); | 436 var entry = codeMap.lookupEntry(address); |
| 436 if (entry) | 437 if (entry) |
| 437 return entry; | 438 return !entry.isNative ? entry : null; |
|
yurys
2015/06/24 13:57:44
entry.isNative ? null : entry;
alph
2015/06/24 14:03:38
Done.
| |
| 438 if (!missingAddesses.has(address)) { | 439 if (!missingAddesses.has(address)) { |
| 439 missingAddesses.add(address); | 440 missingAddesses.add(address); |
| 440 console.error("Address " + address + " has missing code entry"); | 441 console.error("Address " + address + " has missing code entry"); |
| 441 } | 442 } |
| 442 return WebInspector.TimelineJSProfileProcessor._createFrame(address); | 443 return null; |
| 443 } | 444 } |
| 444 | 445 |
| 445 var recordTypes = WebInspector.TimelineModel.RecordType; | 446 var recordTypes = WebInspector.TimelineModel.RecordType; |
| 446 var samples = []; | 447 var samples = []; |
| 447 var codeMap = new WebInspector.TimelineJSProfileProcessor.CodeMap(); | 448 var codeMap = new WebInspector.TimelineJSProfileProcessor.CodeMap(); |
| 448 for (var i = 0; i < events.length; ++i) { | 449 for (var i = 0; i < events.length; ++i) { |
| 449 var e = events[i]; | 450 var e = events[i]; |
| 450 var data = e.args["data"]; | 451 var data = e.args["data"]; |
| 451 switch (e.name) { | 452 switch (e.name) { |
| 452 case recordTypes.JitCodeAdded: | 453 case recordTypes.JitCodeAdded: |
| 453 var frame = WebInspector.TimelineJSProfileProcessor._buildCallFrame( data["name"], data["script_id"]); | 454 var frame = WebInspector.TimelineJSProfileProcessor._buildCallFrame( data["name"], data["script_id"]); |
| 454 codeMap.addEntry(data["code_start"], data["code_len"], frame); | 455 codeMap.addEntry(data["code_start"], data["code_len"], frame); |
| 455 break; | 456 break; |
| 456 case recordTypes.JitCodeMoved: | 457 case recordTypes.JitCodeMoved: |
| 457 codeMap.moveEntry(data["code_start"], data["new_code_start"], data[" code_len"]); | 458 codeMap.moveEntry(data["code_start"], data["new_code_start"], data[" code_len"]); |
| 458 break; | 459 break; |
| 459 case recordTypes.V8Sample: | 460 case recordTypes.V8Sample: |
| 460 var rawStack = data["stack"]; | 461 var rawStack = data["stack"]; |
| 461 // Sometimes backend fails to collect a stack and returns an empty s tack. | 462 // Sometimes backend fails to collect a stack and returns an empty s tack. |
| 462 // Skip these bogus samples. | 463 // Skip these bogus samples. |
| 463 if (data["vm_state"] === "js" && !rawStack.length) | 464 if (data["vm_state"] === "js" && !rawStack.length) |
| 464 break; | 465 break; |
| 465 var stack = rawStack.map(convertRawFrame); | 466 var stack = rawStack.map(convertRawFrame); |
| 467 stack.remove(null); | |
| 466 var sampleEvent = new WebInspector.TracingModel.Event( | 468 var sampleEvent = new WebInspector.TracingModel.Event( |
| 467 WebInspector.TracingModel.DevToolsTimelineEventCategory, | 469 WebInspector.TracingModel.DevToolsTimelineEventCategory, |
| 468 WebInspector.TimelineModel.RecordType.JSSample, | 470 WebInspector.TimelineModel.RecordType.JSSample, |
| 469 WebInspector.TracingModel.Phase.Instant, e.startTime, e.thread); | 471 WebInspector.TracingModel.Phase.Instant, e.startTime, e.thread); |
| 470 sampleEvent.ordinal = e.ordinal; | 472 sampleEvent.ordinal = e.ordinal; |
| 471 sampleEvent.args = {"data": {"stackTrace": stack }}; | 473 sampleEvent.args = {"data": {"stackTrace": stack }}; |
| 472 samples.push(sampleEvent); | 474 samples.push(sampleEvent); |
| 473 break; | 475 break; |
| 474 } | 476 } |
| 475 } | 477 } |
| 476 | 478 |
| 477 return samples; | 479 return samples; |
| 478 } | 480 } |
| OLD | NEW |