| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 /** | 31 /** |
| 32 * @constructor | 32 * @constructor |
| 33 * @extends {WebInspector.Object} | 33 * @extends {WebInspector.Object} |
| 34 */ | 34 */ |
| 35 WebInspector.TimelineModel = function() | 35 WebInspector.TimelineModel = function() |
| 36 { | 36 { |
| 37 this._payloads = []; |
| 37 this._records = []; | 38 this._records = []; |
| 38 this._minimumRecordTime = -1; | 39 this._minimumRecordTime = -1; |
| 39 this._maximumRecordTime = -1; | 40 this._maximumRecordTime = -1; |
| 40 this._stringPool = {}; | 41 this._stringPool = {}; |
| 42 this._bindings = new WebInspector.TimelineModel.InterRecordBindings(); |
| 41 | 43 |
| 42 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineEventRecorded, this._onRecordAdded, this); | 44 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineEventRecorded, this._onRecordAdded, this); |
| 43 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineStarted, this._onStarted, this); | 45 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineStarted, this._onStarted, this); |
| 44 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineStopped, this._onStopped, this); | 46 WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.E
ventTypes.TimelineStopped, this._onStopped, this); |
| 45 } | 47 } |
| 46 | 48 |
| 47 WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000; | 49 WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000; |
| 48 | 50 |
| 49 WebInspector.TimelineModel.RecordType = { | 51 WebInspector.TimelineModel.RecordType = { |
| 50 Root: "Root", | 52 Root: "Root", |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 EmbedderCallback : "EmbedderCallback", | 110 EmbedderCallback : "EmbedderCallback", |
| 109 } | 111 } |
| 110 | 112 |
| 111 WebInspector.TimelineModel.Events = { | 113 WebInspector.TimelineModel.Events = { |
| 112 RecordAdded: "RecordAdded", | 114 RecordAdded: "RecordAdded", |
| 113 RecordsCleared: "RecordsCleared", | 115 RecordsCleared: "RecordsCleared", |
| 114 RecordingStarted: "RecordingStarted", | 116 RecordingStarted: "RecordingStarted", |
| 115 RecordingStopped: "RecordingStopped" | 117 RecordingStopped: "RecordingStopped" |
| 116 } | 118 } |
| 117 | 119 |
| 120 /** |
| 121 * @param {!Array.<!WebInspector.TimelineModel.Record>} recordsArray |
| 122 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector
.TimelineModel.Record,number)} preOrderCallback |
| 123 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.T
imelineModel.Record,number)=} postOrderCallback |
| 124 */ |
| 125 WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallba
ck, postOrderCallback) |
| 126 { |
| 127 if (!recordsArray) |
| 128 return; |
| 129 var stack = [{array: recordsArray, index: 0}]; |
| 130 while (stack.length) { |
| 131 var entry = stack[stack.length - 1]; |
| 132 var records = entry.array; |
| 133 if (entry.index < records.length) { |
| 134 var record = records[entry.index]; |
| 135 if (preOrderCallback && preOrderCallback(record, stack.length)) |
| 136 return; |
| 137 if (record.children) |
| 138 stack.push({array: record.children, index: 0, record: record}); |
| 139 else if (postOrderCallback && postOrderCallback(record, stack.lengt
h)) |
| 140 return; |
| 141 ++entry.index; |
| 142 } else { |
| 143 if (entry.record && postOrderCallback && postOrderCallback(entry.rec
ord, stack.length)) |
| 144 return; |
| 145 stack.pop(); |
| 146 } |
| 147 } |
| 148 } |
| 149 |
| 118 WebInspector.TimelineModel.prototype = { | 150 WebInspector.TimelineModel.prototype = { |
| 119 /** | 151 /** |
| 152 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspe
ctor.TimelineModel.Record,number)} preOrderCallback |
| 153 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect
or.TimelineModel.Record,number)=} postOrderCallback |
| 154 */ |
| 155 forAllRecords: function(preOrderCallback, postOrderCallback) |
| 156 { |
| 157 WebInspector.TimelineModel.forAllRecords(this._records, preOrderCallback
, postOrderCallback); |
| 158 }, |
| 159 |
| 160 /** |
| 120 * @param {boolean=} includeCounters | 161 * @param {boolean=} includeCounters |
| 121 */ | 162 */ |
| 122 startRecording: function(includeCounters) | 163 startRecording: function(includeCounters) |
| 123 { | 164 { |
| 124 this._clientInitiatedRecording = true; | 165 this._clientInitiatedRecording = true; |
| 125 this.reset(); | 166 this.reset(); |
| 126 var maxStackFrames = WebInspector.settings.timelineCaptureStacks.get() ?
30 : 0; | 167 var maxStackFrames = WebInspector.settings.timelineCaptureStacks.get() ?
30 : 0; |
| 127 var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEn
abled(); | 168 var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEn
abled(); |
| 128 WebInspector.timelineManager.start(maxStackFrames, includeCounters, incl
udeGPUEvents, this._fireRecordingStarted.bind(this)); | 169 WebInspector.timelineManager.start(maxStackFrames, includeCounters, incl
udeGPUEvents, this._fireRecordingStarted.bind(this)); |
| 129 }, | 170 }, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 142 */ | 183 */ |
| 143 function stopTimeline() | 184 function stopTimeline() |
| 144 { | 185 { |
| 145 WebInspector.timelineManager.stop(this._fireRecordingStopped.bind(th
is)); | 186 WebInspector.timelineManager.stop(this._fireRecordingStopped.bind(th
is)); |
| 146 } | 187 } |
| 147 | 188 |
| 148 this._clientInitiatedRecording = false; | 189 this._clientInitiatedRecording = false; |
| 149 WebInspector.timelineManager.stop(this._fireRecordingStopped.bind(this))
; | 190 WebInspector.timelineManager.stop(this._fireRecordingStopped.bind(this))
; |
| 150 }, | 191 }, |
| 151 | 192 |
| 152 get records() | 193 /** |
| 194 * @return {!Array.<!WebInspector.TimelineModel.Record>} |
| 195 */ |
| 196 records: function() |
| 153 { | 197 { |
| 154 return this._records; | 198 return this._records; |
| 155 }, | 199 }, |
| 156 | 200 |
| 157 /** | 201 /** |
| 158 * @param {!WebInspector.Event} event | 202 * @param {!WebInspector.Event} event |
| 159 */ | 203 */ |
| 160 _onRecordAdded: function(event) | 204 _onRecordAdded: function(event) |
| 161 { | 205 { |
| 162 if (this._collectionEnabled) | 206 if (this._collectionEnabled) |
| (...skipping 28 matching lines...) Expand all Loading... |
| 191 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.Recordin
gStarted); | 235 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.Recordin
gStarted); |
| 192 }, | 236 }, |
| 193 | 237 |
| 194 _fireRecordingStopped: function() | 238 _fireRecordingStopped: function() |
| 195 { | 239 { |
| 196 this._collectionEnabled = false; | 240 this._collectionEnabled = false; |
| 197 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.Recordin
gStopped); | 241 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.Recordin
gStopped); |
| 198 }, | 242 }, |
| 199 | 243 |
| 200 /** | 244 /** |
| 201 * @param {!TimelineAgent.TimelineEvent} record | 245 * @param {!TimelineAgent.TimelineEvent} payload |
| 202 */ | 246 */ |
| 203 _addRecord: function(record) | 247 _addRecord: function(payload) |
| 204 { | 248 { |
| 205 this._internStringsAndAssignEndTime(record); | 249 this._internStrings(payload); |
| 250 this._payloads.push(payload); |
| 251 this._updateBoundaries(payload); |
| 252 |
| 253 var record = this._innerAddRecord(payload, null); |
| 206 this._records.push(record); | 254 this._records.push(record); |
| 207 this._updateBoundaries(record); | 255 |
| 208 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd
ded, record); | 256 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd
ded, record); |
| 209 }, | 257 }, |
| 210 | 258 |
| 211 /** | 259 /** |
| 260 * @param {!TimelineAgent.TimelineEvent} payload |
| 261 * @param {?WebInspector.TimelineModel.Record} parentRecord |
| 262 * @return {!WebInspector.TimelineModel.Record} |
| 263 * @this {!WebInspector.TimelineModel} |
| 264 */ |
| 265 _innerAddRecord: function(payload, parentRecord) |
| 266 { |
| 267 var record = new WebInspector.TimelineModel.Record(this, payload, parent
Record); |
| 268 for (var i = 0; payload.children && i < payload.children.length; ++i) |
| 269 this._innerAddRecord.call(this, payload.children[i], record); |
| 270 |
| 271 record.calculateAggregatedStats(); |
| 272 if (parentRecord) |
| 273 parentRecord._selfTime -= record.endTime - record.startTime; |
| 274 return record; |
| 275 }, |
| 276 |
| 277 /** |
| 212 * @param {!Blob} file | 278 * @param {!Blob} file |
| 213 * @param {!WebInspector.Progress} progress | 279 * @param {!WebInspector.Progress} progress |
| 214 */ | 280 */ |
| 215 loadFromFile: function(file, progress) | 281 loadFromFile: function(file, progress) |
| 216 { | 282 { |
| 217 var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this,
progress); | 283 var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this,
progress); |
| 218 var fileReader = this._createFileReader(file, delegate); | 284 var fileReader = this._createFileReader(file, delegate); |
| 219 var loader = new WebInspector.TimelineModelLoader(this, fileReader, prog
ress); | 285 var loader = new WebInspector.TimelineModelLoader(this, fileReader, prog
ress); |
| 220 fileReader.start(loader); | 286 fileReader.start(loader); |
| 221 }, | 287 }, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 249 | 315 |
| 250 /** | 316 /** |
| 251 * @param {boolean} accepted | 317 * @param {boolean} accepted |
| 252 * @this {WebInspector.TimelineModel} | 318 * @this {WebInspector.TimelineModel} |
| 253 */ | 319 */ |
| 254 function callback(accepted) | 320 function callback(accepted) |
| 255 { | 321 { |
| 256 if (!accepted) | 322 if (!accepted) |
| 257 return; | 323 return; |
| 258 var saver = new WebInspector.TimelineSaver(stream); | 324 var saver = new WebInspector.TimelineSaver(stream); |
| 259 saver.save(this._records, window.navigator.appVersion); | 325 saver.save(this._payloads, window.navigator.appVersion); |
| 260 } | 326 } |
| 261 stream.open(fileName, callback.bind(this)); | 327 stream.open(fileName, callback.bind(this)); |
| 262 }, | 328 }, |
| 263 | 329 |
| 264 reset: function() | 330 reset: function() |
| 265 { | 331 { |
| 266 this._records = []; | 332 this._records = []; |
| 333 this._payloads = []; |
| 267 this._stringPool = {}; | 334 this._stringPool = {}; |
| 268 this._minimumRecordTime = -1; | 335 this._minimumRecordTime = -1; |
| 269 this._maximumRecordTime = -1; | 336 this._maximumRecordTime = -1; |
| 337 this._bindings._reset(); |
| 270 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC
leared); | 338 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC
leared); |
| 271 }, | 339 }, |
| 272 | 340 |
| 273 /** | 341 /** |
| 274 * @return {number} | 342 * @return {number} |
| 275 */ | 343 */ |
| 276 minimumRecordTime: function() | 344 minimumRecordTime: function() |
| 277 { | 345 { |
| 278 return this._minimumRecordTime; | 346 return this._minimumRecordTime; |
| 279 }, | 347 }, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 305 * @return {number} | 373 * @return {number} |
| 306 */ | 374 */ |
| 307 recordOffsetInMillis: function(rawRecord) | 375 recordOffsetInMillis: function(rawRecord) |
| 308 { | 376 { |
| 309 return rawRecord.startTime - this._minimumRecordTime; | 377 return rawRecord.startTime - this._minimumRecordTime; |
| 310 }, | 378 }, |
| 311 | 379 |
| 312 /** | 380 /** |
| 313 * @param {!TimelineAgent.TimelineEvent} record | 381 * @param {!TimelineAgent.TimelineEvent} record |
| 314 */ | 382 */ |
| 315 _internStringsAndAssignEndTime: function(record) | 383 _internStrings: function(record) |
| 316 { | 384 { |
| 317 // We'd like to dump raw protocol in tests, so add an option to not assi
gn implicit end time. | |
| 318 if (!WebInspector.TimelineModel["_doNotAssignEndTime"]) { | |
| 319 if (typeof record.startTime === "number" && typeof record.endTime !=
= "number") | |
| 320 record.endTime = record.startTime; | |
| 321 } | |
| 322 | |
| 323 for (var name in record) { | 385 for (var name in record) { |
| 324 var value = record[name]; | 386 var value = record[name]; |
| 325 if (typeof value !== "string") | 387 if (typeof value !== "string") |
| 326 continue; | 388 continue; |
| 327 | 389 |
| 328 var interned = this._stringPool[value]; | 390 var interned = this._stringPool[value]; |
| 329 if (typeof interned === "string") | 391 if (typeof interned === "string") |
| 330 record[name] = interned; | 392 record[name] = interned; |
| 331 else | 393 else |
| 332 this._stringPool[value] = value; | 394 this._stringPool[value] = value; |
| 333 } | 395 } |
| 334 | 396 |
| 335 var children = record.children; | 397 var children = record.children; |
| 336 for (var i = 0; children && i < children.length; ++i) | 398 for (var i = 0; children && i < children.length; ++i) |
| 337 this._internStringsAndAssignEndTime(children[i]); | 399 this._internStrings(children[i]); |
| 338 }, | 400 }, |
| 339 | 401 |
| 340 __proto__: WebInspector.Object.prototype | 402 __proto__: WebInspector.Object.prototype |
| 341 } | 403 } |
| 342 | 404 |
| 405 |
| 406 /** |
| 407 * @constructor |
| 408 */ |
| 409 WebInspector.TimelineModel.InterRecordBindings = function() { |
| 410 this._reset(); |
| 411 } |
| 412 |
| 413 WebInspector.TimelineModel.InterRecordBindings.prototype = { |
| 414 _reset: function() |
| 415 { |
| 416 this._sendRequestRecords = {}; |
| 417 this._timerRecords = {}; |
| 418 this._requestAnimationFrameRecords = {}; |
| 419 this._layoutInvalidateStack = {}; |
| 420 this._lastScheduleStyleRecalculation = {}; |
| 421 this._webSocketCreateRecords = {}; |
| 422 } |
| 423 } |
| 424 |
| 425 /** |
| 426 * @constructor |
| 427 * @param {!WebInspector.TimelineModel} model |
| 428 * @param {!TimelineAgent.TimelineEvent} record |
| 429 * @param {?WebInspector.TimelineModel.Record} parentRecord |
| 430 */ |
| 431 WebInspector.TimelineModel.Record = function(model, record, parentRecord) |
| 432 { |
| 433 this._model = model; |
| 434 var bindings = this._model._bindings; |
| 435 this._aggregatedStats = {}; |
| 436 this._record = record; |
| 437 this._children = []; |
| 438 if (parentRecord) { |
| 439 this.parent = parentRecord; |
| 440 parentRecord.children.push(this); |
| 441 } |
| 442 |
| 443 this._selfTime = this.endTime - this.startTime; |
| 444 this._lastChildEndTime = this.endTime; |
| 445 this._startTimeOffset = this.startTime - model.minimumRecordTime(); |
| 446 |
| 447 if (record.data) { |
| 448 if (record.data["url"]) |
| 449 this.url = record.data["url"]; |
| 450 if (record.data["rootNode"]) |
| 451 this._relatedBackendNodeId = record.data["rootNode"]; |
| 452 else if (record.data["elementId"]) |
| 453 this._relatedBackendNodeId = record.data["elementId"]; |
| 454 if (record.data["scriptName"]) { |
| 455 this.scriptName = record.data["scriptName"]; |
| 456 this.scriptLine = record.data["scriptLine"]; |
| 457 } |
| 458 } |
| 459 |
| 460 if (parentRecord && parentRecord.callSiteStackTrace) |
| 461 this.callSiteStackTrace = parentRecord.callSiteStackTrace; |
| 462 |
| 463 var recordTypes = WebInspector.TimelineModel.RecordType; |
| 464 switch (record.type) { |
| 465 case recordTypes.ResourceSendRequest: |
| 466 // Make resource receive record last since request was sent; make finish
record last since response received. |
| 467 bindings._sendRequestRecords[record.data["requestId"]] = this; |
| 468 break; |
| 469 |
| 470 case recordTypes.ResourceReceiveResponse: |
| 471 var sendRequestRecord = bindings._sendRequestRecords[record.data["reques
tId"]]; |
| 472 if (sendRequestRecord) // False if we started instrumentation in the mid
dle of request. |
| 473 this.url = sendRequestRecord.url; |
| 474 break; |
| 475 |
| 476 case recordTypes.ResourceReceivedData: |
| 477 case recordTypes.ResourceFinish: |
| 478 var sendRequestRecord = bindings._sendRequestRecords[record.data["reques
tId"]]; |
| 479 if (sendRequestRecord) // False for main resource. |
| 480 this.url = sendRequestRecord.url; |
| 481 break; |
| 482 |
| 483 case recordTypes.TimerInstall: |
| 484 this.timeout = record.data["timeout"]; |
| 485 this.singleShot = record.data["singleShot"]; |
| 486 bindings._timerRecords[record.data["timerId"]] = this; |
| 487 break; |
| 488 |
| 489 case recordTypes.TimerFire: |
| 490 var timerInstalledRecord = bindings._timerRecords[record.data["timerId"]
]; |
| 491 if (timerInstalledRecord) { |
| 492 this.callSiteStackTrace = timerInstalledRecord.stackTrace; |
| 493 this.timeout = timerInstalledRecord.timeout; |
| 494 this.singleShot = timerInstalledRecord.singleShot; |
| 495 } |
| 496 break; |
| 497 |
| 498 case recordTypes.RequestAnimationFrame: |
| 499 bindings._requestAnimationFrameRecords[record.data["id"]] = this; |
| 500 break; |
| 501 |
| 502 case recordTypes.FireAnimationFrame: |
| 503 var requestAnimationRecord = bindings._requestAnimationFrameRecords[reco
rd.data["id"]]; |
| 504 if (requestAnimationRecord) |
| 505 this.callSiteStackTrace = requestAnimationRecord.stackTrace; |
| 506 break; |
| 507 |
| 508 case recordTypes.ConsoleTime: |
| 509 var message = record.data["message"]; |
| 510 break; |
| 511 |
| 512 case recordTypes.ScheduleStyleRecalculation: |
| 513 bindings._lastScheduleStyleRecalculation[this.frameId] = this; |
| 514 break; |
| 515 |
| 516 case recordTypes.RecalculateStyles: |
| 517 var scheduleStyleRecalculationRecord = bindings._lastScheduleStyleRecalc
ulation[this.frameId]; |
| 518 if (!scheduleStyleRecalculationRecord) |
| 519 break; |
| 520 this.callSiteStackTrace = scheduleStyleRecalculationRecord.stackTrace; |
| 521 break; |
| 522 |
| 523 case recordTypes.InvalidateLayout: |
| 524 // Consider style recalculation as a reason for layout invalidation, |
| 525 // but only if we had no earlier layout invalidation records. |
| 526 var styleRecalcStack; |
| 527 if (!bindings._layoutInvalidateStack[this.frameId]) { |
| 528 if (parentRecord.type === recordTypes.RecalculateStyles) |
| 529 styleRecalcStack = parentRecord.callSiteStackTrace; |
| 530 } |
| 531 bindings._layoutInvalidateStack[this.frameId] = styleRecalcStack || this
.stackTrace; |
| 532 break; |
| 533 |
| 534 case recordTypes.Layout: |
| 535 var layoutInvalidateStack = bindings._layoutInvalidateStack[this.frameId
]; |
| 536 if (layoutInvalidateStack) |
| 537 this.callSiteStackTrace = layoutInvalidateStack; |
| 538 if (this.stackTrace) |
| 539 this.addWarning(WebInspector.UIString("Forced synchronous layout is
a possible performance bottleneck.")); |
| 540 |
| 541 bindings._layoutInvalidateStack[this.frameId] = null; |
| 542 this.highlightQuad = record.data.root || WebInspector.TimelineModel._qua
dFromRectData(record.data); |
| 543 this._relatedBackendNodeId = record.data["rootNode"]; |
| 544 break; |
| 545 |
| 546 case recordTypes.AutosizeText: |
| 547 if (record.data.needsRelayout && parentRecord.type === recordTypes.Layou
t) |
| 548 parentRecord.addWarning(WebInspector.UIString("Layout required two p
asses due to text autosizing, consider setting viewport.")); |
| 549 break; |
| 550 |
| 551 case recordTypes.Paint: |
| 552 this.highlightQuad = record.data.clip || WebInspector.TimelineModel._qua
dFromRectData(record.data); |
| 553 break; |
| 554 |
| 555 case recordTypes.WebSocketCreate: |
| 556 this.webSocketURL = record.data["url"]; |
| 557 if (typeof record.data["webSocketProtocol"] !== "undefined") |
| 558 this.webSocketProtocol = record.data["webSocketProtocol"]; |
| 559 bindings._webSocketCreateRecords[record.data["identifier"]] = this; |
| 560 break; |
| 561 |
| 562 case recordTypes.WebSocketSendHandshakeRequest: |
| 563 case recordTypes.WebSocketReceiveHandshakeResponse: |
| 564 case recordTypes.WebSocketDestroy: |
| 565 var webSocketCreateRecord = bindings._webSocketCreateRecords[record.data
["identifier"]]; |
| 566 if (webSocketCreateRecord) { // False if we started instrumentation in t
he middle of request. |
| 567 this.webSocketURL = webSocketCreateRecord.webSocketURL; |
| 568 if (typeof webSocketCreateRecord.webSocketProtocol !== "undefined") |
| 569 this.webSocketProtocol = webSocketCreateRecord.webSocketProtocol
; |
| 570 } |
| 571 break; |
| 572 |
| 573 case recordTypes.EmbedderCallback: |
| 574 this.embedderCallbackName = record.data["callbackName"]; |
| 575 break; |
| 576 } |
| 577 } |
| 578 |
| 579 WebInspector.TimelineModel.Record.prototype = { |
| 580 get lastChildEndTime() |
| 581 { |
| 582 return this._lastChildEndTime; |
| 583 }, |
| 584 |
| 585 set lastChildEndTime(time) |
| 586 { |
| 587 this._lastChildEndTime = time; |
| 588 }, |
| 589 |
| 590 get selfTime() |
| 591 { |
| 592 return this._selfTime; |
| 593 }, |
| 594 |
| 595 get cpuTime() |
| 596 { |
| 597 return this._cpuTime; |
| 598 }, |
| 599 |
| 600 /** |
| 601 * @return {boolean} |
| 602 */ |
| 603 isRoot: function() |
| 604 { |
| 605 return this.type === WebInspector.TimelineModel.RecordType.Root; |
| 606 }, |
| 607 |
| 608 /** |
| 609 * @return {!Array.<!WebInspector.TimelineModel.Record>} |
| 610 */ |
| 611 get children() |
| 612 { |
| 613 return this._children; |
| 614 }, |
| 615 |
| 616 /** |
| 617 * @return {!WebInspector.TimelineCategory} |
| 618 */ |
| 619 get category() |
| 620 { |
| 621 return WebInspector.TimelineUIUtils.categoryForRecord(this); |
| 622 }, |
| 623 |
| 624 /** |
| 625 * @return {string} |
| 626 */ |
| 627 title: function() |
| 628 { |
| 629 return WebInspector.TimelineUIUtils.recordTitle(this); |
| 630 }, |
| 631 |
| 632 /** |
| 633 * @return {number} |
| 634 */ |
| 635 get startTime() |
| 636 { |
| 637 return this._startTime || this._record.startTime; |
| 638 }, |
| 639 |
| 640 set startTime(startTime) |
| 641 { |
| 642 this._startTime = startTime; |
| 643 }, |
| 644 |
| 645 /** |
| 646 * @return {string|undefined} |
| 647 */ |
| 648 get thread() |
| 649 { |
| 650 return this._record.thread; |
| 651 }, |
| 652 |
| 653 /** |
| 654 * @return {number} |
| 655 */ |
| 656 get startTimeOffset() |
| 657 { |
| 658 return this._startTimeOffset; |
| 659 }, |
| 660 |
| 661 /** |
| 662 * @return {number} |
| 663 */ |
| 664 get endTime() |
| 665 { |
| 666 return this._endTime || this._record.endTime || this._record.startTime; |
| 667 }, |
| 668 |
| 669 set endTime(endTime) |
| 670 { |
| 671 this._endTime = endTime; |
| 672 }, |
| 673 |
| 674 /** |
| 675 * @return {!Object} |
| 676 */ |
| 677 get data() |
| 678 { |
| 679 return this._record.data; |
| 680 }, |
| 681 |
| 682 /** |
| 683 * @return {string} |
| 684 */ |
| 685 get type() |
| 686 { |
| 687 return this._record.type; |
| 688 }, |
| 689 |
| 690 /** |
| 691 * @return {string} |
| 692 */ |
| 693 get frameId() |
| 694 { |
| 695 return this._record.frameId || ""; |
| 696 }, |
| 697 |
| 698 /** |
| 699 * @return {number} |
| 700 */ |
| 701 get usedHeapSizeDelta() |
| 702 { |
| 703 return this._record.usedHeapSizeDelta || 0; |
| 704 }, |
| 705 |
| 706 /** |
| 707 * @return {number} |
| 708 */ |
| 709 get jsHeapSizeUsed() |
| 710 { |
| 711 return this._record.counters ? this._record.counters.jsHeapSizeUsed || 0
: 0; |
| 712 }, |
| 713 |
| 714 /** |
| 715 * @return {!Object|undefined} |
| 716 */ |
| 717 get counters() |
| 718 { |
| 719 return this._record.counters; |
| 720 }, |
| 721 |
| 722 /** |
| 723 * @return {?Array.<!ConsoleAgent.CallFrame>} |
| 724 */ |
| 725 get stackTrace() |
| 726 { |
| 727 if (this._record.stackTrace && this._record.stackTrace.length) |
| 728 return this._record.stackTrace; |
| 729 return null; |
| 730 }, |
| 731 |
| 732 /** |
| 733 * @param {string} key |
| 734 * @return {?Object} |
| 735 */ |
| 736 getUserObject: function(key) |
| 737 { |
| 738 if (!this._userObjects) |
| 739 return null; |
| 740 return this._userObjects.get(key); |
| 741 }, |
| 742 |
| 743 /** |
| 744 * @param {string} key |
| 745 * @param {?Object|undefined} value |
| 746 */ |
| 747 setUserObject: function(key, value) |
| 748 { |
| 749 if (!this._userObjects) |
| 750 this._userObjects = new StringMap(); |
| 751 this._userObjects.put(key, value); |
| 752 }, |
| 753 |
| 754 /** |
| 755 * @return {number} nodeId |
| 756 */ |
| 757 relatedBackendNodeId: function() |
| 758 { |
| 759 return this._relatedBackendNodeId; |
| 760 }, |
| 761 |
| 762 calculateAggregatedStats: function() |
| 763 { |
| 764 this._aggregatedStats = {}; |
| 765 this._cpuTime = this._selfTime; |
| 766 |
| 767 for (var index = this._children.length; index; --index) { |
| 768 var child = this._children[index - 1]; |
| 769 for (var category in child._aggregatedStats) |
| 770 this._aggregatedStats[category] = (this._aggregatedStats[categor
y] || 0) + child._aggregatedStats[category]; |
| 771 } |
| 772 for (var category in this._aggregatedStats) |
| 773 this._cpuTime += this._aggregatedStats[category]; |
| 774 this._aggregatedStats[this.category.name] = (this._aggregatedStats[this.
category.name] || 0) + this._selfTime; |
| 775 }, |
| 776 |
| 777 get aggregatedStats() |
| 778 { |
| 779 return this._aggregatedStats; |
| 780 }, |
| 781 |
| 782 /** |
| 783 * @param {string} message |
| 784 */ |
| 785 addWarning: function(message) |
| 786 { |
| 787 if (this._warnings) |
| 788 this._warnings.push(message); |
| 789 else |
| 790 this._warnings = [message]; |
| 791 }, |
| 792 |
| 793 /** |
| 794 * @return {!Object} |
| 795 */ |
| 796 warnings: function() |
| 797 { |
| 798 return this._warnings; |
| 799 }, |
| 800 |
| 801 /** |
| 802 * @param {!RegExp} regExp |
| 803 * @return {boolean} |
| 804 */ |
| 805 testContentMatching: function(regExp) |
| 806 { |
| 807 var tokens = [this.title()]; |
| 808 for (var key in this._record.data) |
| 809 tokens.push(this._record.data[key]) |
| 810 return regExp.test(tokens.join("|")); |
| 811 } |
| 812 } |
| 813 |
| 343 /** | 814 /** |
| 344 * @constructor | 815 * @constructor |
| 345 * @implements {WebInspector.OutputStream} | 816 * @implements {WebInspector.OutputStream} |
| 346 * @param {!WebInspector.TimelineModel} model | 817 * @param {!WebInspector.TimelineModel} model |
| 347 * @param {!{cancel: function()}} reader | 818 * @param {!{cancel: function()}} reader |
| 348 * @param {!WebInspector.Progress} progress | 819 * @param {!WebInspector.Progress} progress |
| 349 */ | 820 */ |
| 350 WebInspector.TimelineModelLoader = function(model, reader, progress) | 821 WebInspector.TimelineModelLoader = function(model, reader, progress) |
| 351 { | 822 { |
| 352 this._model = model; | 823 this._model = model; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 /** | 943 /** |
| 473 * @constructor | 944 * @constructor |
| 474 */ | 945 */ |
| 475 WebInspector.TimelineSaver = function(stream) | 946 WebInspector.TimelineSaver = function(stream) |
| 476 { | 947 { |
| 477 this._stream = stream; | 948 this._stream = stream; |
| 478 } | 949 } |
| 479 | 950 |
| 480 WebInspector.TimelineSaver.prototype = { | 951 WebInspector.TimelineSaver.prototype = { |
| 481 /** | 952 /** |
| 482 * @param {!Array.<*>} records | 953 * @param {!Array.<*>} payloads |
| 483 * @param {string} version | 954 * @param {string} version |
| 484 */ | 955 */ |
| 485 save: function(records, version) | 956 save: function(payloads, version) |
| 486 { | 957 { |
| 487 this._records = records; | 958 this._payloads = payloads; |
| 488 this._recordIndex = 0; | 959 this._recordIndex = 0; |
| 489 this._prologue = "[" + JSON.stringify(version); | 960 this._prologue = "[" + JSON.stringify(version); |
| 490 | 961 |
| 491 this._writeNextChunk(this._stream); | 962 this._writeNextChunk(this._stream); |
| 492 }, | 963 }, |
| 493 | 964 |
| 494 _writeNextChunk: function(stream) | 965 _writeNextChunk: function(stream) |
| 495 { | 966 { |
| 496 const separator = ",\n"; | 967 const separator = ",\n"; |
| 497 var data = []; | 968 var data = []; |
| 498 var length = 0; | 969 var length = 0; |
| 499 | 970 |
| 500 if (this._prologue) { | 971 if (this._prologue) { |
| 501 data.push(this._prologue); | 972 data.push(this._prologue); |
| 502 length += this._prologue.length; | 973 length += this._prologue.length; |
| 503 delete this._prologue; | 974 delete this._prologue; |
| 504 } else { | 975 } else { |
| 505 if (this._recordIndex === this._records.length) { | 976 if (this._recordIndex === this._payloads.length) { |
| 506 stream.close(); | 977 stream.close(); |
| 507 return; | 978 return; |
| 508 } | 979 } |
| 509 data.push(""); | 980 data.push(""); |
| 510 } | 981 } |
| 511 while (this._recordIndex < this._records.length) { | 982 while (this._recordIndex < this._payloads.length) { |
| 512 var item = JSON.stringify(this._records[this._recordIndex]); | 983 var item = JSON.stringify(this._payloads[this._recordIndex]); |
| 513 var itemLength = item.length + separator.length; | 984 var itemLength = item.length + separator.length; |
| 514 if (length + itemLength > WebInspector.TimelineModel.TransferChunkLe
ngthBytes) | 985 if (length + itemLength > WebInspector.TimelineModel.TransferChunkLe
ngthBytes) |
| 515 break; | 986 break; |
| 516 length += itemLength; | 987 length += itemLength; |
| 517 data.push(item); | 988 data.push(item); |
| 518 ++this._recordIndex; | 989 ++this._recordIndex; |
| 519 } | 990 } |
| 520 if (this._recordIndex === this._records.length) | 991 if (this._recordIndex === this._payloads.length) |
| 521 data.push(data.pop() + "]"); | 992 data.push(data.pop() + "]"); |
| 522 stream.write(data.join(separator), this._writeNextChunk.bind(this)); | 993 stream.write(data.join(separator), this._writeNextChunk.bind(this)); |
| 523 } | 994 } |
| 524 } | 995 } |
| 525 | 996 |
| 526 /** | 997 /** |
| 527 * @constructor | 998 * @constructor |
| 528 */ | 999 */ |
| 529 WebInspector.TimelineMergingRecordBuffer = function() | 1000 WebInspector.TimelineMergingRecordBuffer = function() |
| 530 { | 1001 { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 552 */ | 1023 */ |
| 553 function recordTimestampComparator(a, b) | 1024 function recordTimestampComparator(a, b) |
| 554 { | 1025 { |
| 555 // Never return 0, as the merge function will squash identical entri
es. | 1026 // Never return 0, as the merge function will squash identical entri
es. |
| 556 return a.startTime < b.startTime ? -1 : 1; | 1027 return a.startTime < b.startTime ? -1 : 1; |
| 557 } | 1028 } |
| 558 var result = this._backgroundRecordsBuffer.mergeOrdered(records, recordT
imestampComparator); | 1029 var result = this._backgroundRecordsBuffer.mergeOrdered(records, recordT
imestampComparator); |
| 559 this._backgroundRecordsBuffer = []; | 1030 this._backgroundRecordsBuffer = []; |
| 560 return result; | 1031 return result; |
| 561 } | 1032 } |
| 562 }; | 1033 } |
| 1034 |
| 1035 /** |
| 1036 * @param {!Object} data |
| 1037 * @return {?Array.<number>} |
| 1038 */ |
| 1039 WebInspector.TimelineModel._quadFromRectData = function(data) |
| 1040 { |
| 1041 if (typeof data["x"] === "undefined" || typeof data["y"] === "undefined") |
| 1042 return null; |
| 1043 var x0 = data["x"]; |
| 1044 var x1 = data["x"] + data["width"]; |
| 1045 var y0 = data["y"]; |
| 1046 var y1 = data["y"] + data["height"]; |
| 1047 return [x0, y0, x1, y0, x1, y1, x0, y1]; |
| 1048 } |
| OLD | NEW |