| 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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 var entryEndAddress = entry.address + entry.size; | 300 var entryEndAddress = entry.address + entry.size; |
| 301 if (entryEndAddress <= newEntry.address) | 301 if (entryEndAddress <= newEntry.address) |
| 302 break; | 302 break; |
| 303 } | 303 } |
| 304 ++index; | 304 ++index; |
| 305 this._entries.splice(index, lastIndex - index, newEntry); | 305 this._entries.splice(index, lastIndex - index, newEntry); |
| 306 } | 306 } |
| 307 } | 307 } |
| 308 | 308 |
| 309 /** | 309 /** |
| 310 * @param {string} functionName |
| 311 * @param {string=} url |
| 312 * @param {string=} scriptId |
| 313 * @param {number=} line |
| 314 * @param {number=} column |
| 315 * @return {!ConsoleAgent.CallFrame} |
| 316 */ |
| 317 WebInspector.TimelineJSProfileProcessor._createFrame = function(functionName, ur
l, scriptId, line, column) |
| 318 { |
| 319 return /** @type {!ConsoleAgent.CallFrame} */ ({ |
| 320 "functionName": functionName, |
| 321 "url": url || "", |
| 322 "scriptId": scriptId || "0", |
| 323 "lineNumber": line || 0, |
| 324 "columnNumber": column || 0 |
| 325 }); |
| 326 } |
| 327 |
| 328 /** |
| 329 * @param {string} name |
| 330 * @param {number} scriptId |
| 331 * @return {!ConsoleAgent.CallFrame} |
| 332 */ |
| 333 WebInspector.TimelineJSProfileProcessor._buildCallFrame = function(name, scriptI
d) |
| 334 { |
| 335 // Code states: |
| 336 // (empty) -> compiled |
| 337 // ~ -> optimizable |
| 338 // * -> optimized |
| 339 var rePrefix = /^(\w*:)?[*~]?(.*)$/m; |
| 340 |
| 341 var tokens = rePrefix.exec(name); |
| 342 var prefix = tokens[1]; |
| 343 var body = tokens[2]; |
| 344 var rawName; |
| 345 var rawUrl; |
| 346 if (prefix === "Script:") { |
| 347 rawName = ""; |
| 348 rawUrl = body; |
| 349 } else { |
| 350 var spacePos = body.lastIndexOf(" "); |
| 351 rawName = spacePos !== -1 ? body.substr(0, spacePos) : body; |
| 352 rawUrl = spacePos !== -1 ? body.substr(spacePos + 1) : ""; |
| 353 } |
| 354 var functionName = rawName; |
| 355 var urlData = WebInspector.ParsedURL.splitLineAndColumn(rawUrl); |
| 356 var url = urlData.url || ""; |
| 357 var line = urlData.lineNumber || 0; |
| 358 var column = urlData.columnNumber || 0; |
| 359 return WebInspector.TimelineJSProfileProcessor._createFrame(functionName, ur
l, String(scriptId), line, column); |
| 360 } |
| 361 |
| 362 /** |
| 310 * @param {!Array<!WebInspector.TracingModel.Event>} events | 363 * @param {!Array<!WebInspector.TracingModel.Event>} events |
| 311 * @return {!Array<!WebInspector.TracingModel.Event>} | 364 * @return {!Array<!WebInspector.TracingModel.Event>} |
| 312 */ | 365 */ |
| 313 WebInspector.TimelineJSProfileProcessor.processRawV8Samples = function(events) | 366 WebInspector.TimelineJSProfileProcessor.processRawV8Samples = function(events) |
| 314 { | 367 { |
| 315 var unknownFrame = { | 368 var missingAddesses = new Set(); |
| 316 functionName: "(unknown)", | 369 |
| 317 url: "", | |
| 318 scriptId: "0", | |
| 319 lineNumber: 0, | |
| 320 columnNumber: 0 | |
| 321 }; | |
| 322 /** | 370 /** |
| 323 * @param {string} address | 371 * @param {string} address |
| 324 * @return {!ConsoleAgent.CallFrame} | 372 * @return {!ConsoleAgent.CallFrame} |
| 325 */ | 373 */ |
| 326 function convertRawFrame(address) | 374 function convertRawFrame(address) |
| 327 { | 375 { |
| 328 return codeMap.lookupEntry(address) || unknownFrame; | 376 var entry = codeMap.lookupEntry(address); |
| 329 } | 377 if (entry) |
| 330 | 378 return entry; |
| 331 // Code states: | 379 if (!missingAddesses.has(address)) { |
| 332 // (empty) -> compiled | 380 missingAddesses.add(address); |
| 333 // ~ -> optimizable | 381 console.error("Address " + address + " has missing code entry"); |
| 334 // * -> optimized | 382 } |
| 335 var reName = /^(\S*:)?[*~]?(\S*)(?: (\S*))?$/; | 383 return WebInspector.TimelineJSProfileProcessor._createFrame(address); |
| 336 | |
| 337 /** | |
| 338 * @param {string} name | |
| 339 * @param {number} scriptId | |
| 340 * @return {!ConsoleAgent.CallFrame} | |
| 341 */ | |
| 342 function buildCallFrame(name, scriptId) | |
| 343 { | |
| 344 var parsed = reName.exec(name); | |
| 345 if (!parsed) | |
| 346 return unknownFrame; | |
| 347 var functionName = parsed[2] || ""; | |
| 348 var urlData = WebInspector.ParsedURL.splitLineAndColumn(parsed[3] || "")
; | |
| 349 var url = urlData && urlData.url || ""; | |
| 350 var line = urlData && urlData.lineNumber || 0; | |
| 351 var column = urlData && urlData.columnNumber || 0; | |
| 352 var frame = { | |
| 353 "functionName": functionName, | |
| 354 "url": url, | |
| 355 "scriptId": String(scriptId), | |
| 356 "lineNumber": line, | |
| 357 "columnNumber": column | |
| 358 }; | |
| 359 return frame; | |
| 360 } | 384 } |
| 361 | 385 |
| 362 var recordTypes = WebInspector.TimelineModel.RecordType; | 386 var recordTypes = WebInspector.TimelineModel.RecordType; |
| 363 var samples = []; | 387 var samples = []; |
| 364 var codeMap = new WebInspector.TimelineJSProfileProcessor.CodeMap(); | 388 var codeMap = new WebInspector.TimelineJSProfileProcessor.CodeMap(); |
| 365 for (var i = 0; i < events.length; ++i) { | 389 for (var i = 0; i < events.length; ++i) { |
| 366 var e = events[i]; | 390 var e = events[i]; |
| 367 var data = e.args["data"]; | 391 var data = e.args["data"]; |
| 368 switch (e.name) { | 392 switch (e.name) { |
| 369 case recordTypes.JitCodeAdded: | 393 case recordTypes.JitCodeAdded: |
| 370 codeMap.addEntry(data["code_start"], data["code_len"], buildCallFram
e(data["name"], data["script_id"])); | 394 var frame = WebInspector.TimelineJSProfileProcessor._buildCallFrame(
data["name"], data["script_id"]); |
| 395 codeMap.addEntry(data["code_start"], data["code_len"], frame); |
| 371 break; | 396 break; |
| 372 case recordTypes.JitCodeMoved: | 397 case recordTypes.JitCodeMoved: |
| 373 codeMap.moveEntry(data["code_start"], data["new_code_start"], data["
code_len"]); | 398 codeMap.moveEntry(data["code_start"], data["new_code_start"], data["
code_len"]); |
| 374 break; | 399 break; |
| 375 case recordTypes.V8Sample: | 400 case recordTypes.V8Sample: |
| 376 var rawStack = data["stack"]; | 401 var rawStack = data["stack"]; |
| 377 // Sometimes backend fails to collect a stack and returns an empty s
tack. | 402 // Sometimes backend fails to collect a stack and returns an empty s
tack. |
| 378 // Skip these bogus samples. | 403 // Skip these bogus samples. |
| 379 if (data["vm_state"] === "js" && !rawStack.length) | 404 if (data["vm_state"] === "js" && !rawStack.length) |
| 380 break; | 405 break; |
| 381 var stack = rawStack.map(convertRawFrame); | 406 var stack = rawStack.map(convertRawFrame); |
| 382 var sampleEvent = new WebInspector.TracingModel.Event( | 407 var sampleEvent = new WebInspector.TracingModel.Event( |
| 383 WebInspector.TracingModel.DevToolsTimelineEventCategory, | 408 WebInspector.TracingModel.DevToolsTimelineEventCategory, |
| 384 WebInspector.TimelineModel.RecordType.JSSample, | 409 WebInspector.TimelineModel.RecordType.JSSample, |
| 385 WebInspector.TracingModel.Phase.Instant, e.startTime, e.thread); | 410 WebInspector.TracingModel.Phase.Instant, e.startTime, e.thread); |
| 386 sampleEvent.ordinal = e.ordinal; | 411 sampleEvent.ordinal = e.ordinal; |
| 387 sampleEvent.args = {"data": {"stackTrace": stack }}; | 412 sampleEvent.args = {"data": {"stackTrace": stack }}; |
| 388 samples.push(sampleEvent); | 413 samples.push(sampleEvent); |
| 389 break; | 414 break; |
| 390 } | 415 } |
| 391 } | 416 } |
| 392 | 417 |
| 393 return samples; | 418 return samples; |
| 394 } | 419 } |
| OLD | NEW |