Chromium Code Reviews| 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) | |
|
caseq
2014/03/03 09:08:32
This can be now implemented recursively given that
pfeldman
2014/03/03 10:03:45
Yup. Will do in a follow up!
| |
| 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 /** | |
| 254 * @param {!TimelineAgent.TimelineEvent} payload | |
| 255 * @param {?WebInspector.TimelineModel.Record} parentRecord | |
| 256 * @return {!WebInspector.TimelineModel.Record} | |
| 257 * @this {!WebInspector.TimelineModel} | |
| 258 */ | |
| 259 function innerAddRecord(payload, parentRecord) | |
|
caseq
2014/03/03 09:08:32
nit: extract to a member
pfeldman
2014/03/03 10:03:45
Done.
| |
| 260 { | |
| 261 var record = new WebInspector.TimelineModel.Record(this, payload, pa rentRecord); | |
| 262 for (var i = 0; payload.children && i < payload.children.length; ++i ) | |
| 263 innerAddRecord.call(this, payload.children[i], record); | |
| 264 | |
| 265 record.calculateAggregatedStats(); | |
| 266 if (parentRecord) | |
| 267 parentRecord._selfTime -= record.endTime - record.startTime; | |
| 268 return record; | |
| 269 } | |
| 270 var record = innerAddRecord.call(this, payload, null); | |
| 206 this._records.push(record); | 271 this._records.push(record); |
| 207 this._updateBoundaries(record); | 272 |
| 208 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd ded, record); | 273 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd ded, record); |
| 209 }, | 274 }, |
| 210 | 275 |
| 211 /** | 276 /** |
| 212 * @param {!Blob} file | 277 * @param {!Blob} file |
| 213 * @param {!WebInspector.Progress} progress | 278 * @param {!WebInspector.Progress} progress |
| 214 */ | 279 */ |
| 215 loadFromFile: function(file, progress) | 280 loadFromFile: function(file, progress) |
| 216 { | 281 { |
| 217 var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this, progress); | 282 var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this, progress); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 | 314 |
| 250 /** | 315 /** |
| 251 * @param {boolean} accepted | 316 * @param {boolean} accepted |
| 252 * @this {WebInspector.TimelineModel} | 317 * @this {WebInspector.TimelineModel} |
| 253 */ | 318 */ |
| 254 function callback(accepted) | 319 function callback(accepted) |
| 255 { | 320 { |
| 256 if (!accepted) | 321 if (!accepted) |
| 257 return; | 322 return; |
| 258 var saver = new WebInspector.TimelineSaver(stream); | 323 var saver = new WebInspector.TimelineSaver(stream); |
| 259 saver.save(this._records, window.navigator.appVersion); | 324 saver.save(this._payloads, window.navigator.appVersion); |
| 260 } | 325 } |
| 261 stream.open(fileName, callback.bind(this)); | 326 stream.open(fileName, callback.bind(this)); |
| 262 }, | 327 }, |
| 263 | 328 |
| 264 reset: function() | 329 reset: function() |
| 265 { | 330 { |
| 266 this._records = []; | 331 this._records = []; |
| 332 this._payloads = []; | |
| 267 this._stringPool = {}; | 333 this._stringPool = {}; |
| 268 this._minimumRecordTime = -1; | 334 this._minimumRecordTime = -1; |
| 269 this._maximumRecordTime = -1; | 335 this._maximumRecordTime = -1; |
| 336 this._bindings._reset(); | |
| 270 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC leared); | 337 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC leared); |
| 271 }, | 338 }, |
| 272 | 339 |
| 273 /** | 340 /** |
| 274 * @return {number} | 341 * @return {number} |
| 275 */ | 342 */ |
| 276 minimumRecordTime: function() | 343 minimumRecordTime: function() |
| 277 { | 344 { |
| 278 return this._minimumRecordTime; | 345 return this._minimumRecordTime; |
| 279 }, | 346 }, |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 305 * @return {number} | 372 * @return {number} |
| 306 */ | 373 */ |
| 307 recordOffsetInMillis: function(rawRecord) | 374 recordOffsetInMillis: function(rawRecord) |
| 308 { | 375 { |
| 309 return rawRecord.startTime - this._minimumRecordTime; | 376 return rawRecord.startTime - this._minimumRecordTime; |
| 310 }, | 377 }, |
| 311 | 378 |
| 312 /** | 379 /** |
| 313 * @param {!TimelineAgent.TimelineEvent} record | 380 * @param {!TimelineAgent.TimelineEvent} record |
| 314 */ | 381 */ |
| 315 _internStringsAndAssignEndTime: function(record) | 382 _internStrings: function(record) |
| 316 { | 383 { |
| 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) { | 384 for (var name in record) { |
| 324 var value = record[name]; | 385 var value = record[name]; |
| 325 if (typeof value !== "string") | 386 if (typeof value !== "string") |
| 326 continue; | 387 continue; |
| 327 | 388 |
| 328 var interned = this._stringPool[value]; | 389 var interned = this._stringPool[value]; |
| 329 if (typeof interned === "string") | 390 if (typeof interned === "string") |
| 330 record[name] = interned; | 391 record[name] = interned; |
| 331 else | 392 else |
| 332 this._stringPool[value] = value; | 393 this._stringPool[value] = value; |
| 333 } | 394 } |
| 334 | 395 |
| 335 var children = record.children; | 396 var children = record.children; |
| 336 for (var i = 0; children && i < children.length; ++i) | 397 for (var i = 0; children && i < children.length; ++i) |
| 337 this._internStringsAndAssignEndTime(children[i]); | 398 this._internStrings(children[i]); |
| 338 }, | 399 }, |
| 339 | 400 |
| 340 __proto__: WebInspector.Object.prototype | 401 __proto__: WebInspector.Object.prototype |
| 341 } | 402 } |
| 342 | 403 |
| 404 | |
| 405 /** | |
| 406 * @constructor | |
| 407 */ | |
| 408 WebInspector.TimelineModel.InterRecordBindings = function() { | |
|
caseq
2014/03/03 09:08:32
{ => next line
pfeldman
2014/03/03 10:03:45
Done.
| |
| 409 this._reset(); | |
| 410 } | |
| 411 | |
| 412 WebInspector.TimelineModel.InterRecordBindings.prototype = { | |
| 413 _reset: function() | |
| 414 { | |
| 415 this._sendRequestRecords = {}; | |
| 416 this._timerRecords = {}; | |
| 417 this._requestAnimationFrameRecords = {}; | |
| 418 this._layoutInvalidateStack = {}; | |
| 419 this._lastScheduleStyleRecalculation = {}; | |
| 420 this._webSocketCreateRecords = {}; | |
| 421 } | |
| 422 } | |
| 423 | |
| 424 /** | |
| 425 * @constructor | |
| 426 * @param {!WebInspector.TimelineModel} model | |
| 427 * @param {!TimelineAgent.TimelineEvent} record | |
| 428 * @param {?WebInspector.TimelineModel.Record} parentRecord | |
| 429 */ | |
| 430 WebInspector.TimelineModel.Record = function(model, record, parentRecord) | |
| 431 { | |
| 432 this._model = model; | |
| 433 var bindings = this._model._bindings; | |
| 434 this._aggregatedStats = {}; | |
| 435 this._record = record; | |
|
caseq
2014/03/03 09:08:32
record => payload
pfeldman
2014/03/03 10:03:45
Will do in a follow up - otherwise too much change
| |
| 436 this._children = []; | |
| 437 if (parentRecord) { | |
| 438 this.parent = parentRecord; | |
| 439 parentRecord.children.push(this); | |
| 440 } | |
| 441 | |
| 442 this._selfTime = this.endTime - this.startTime; | |
| 443 this._lastChildEndTime = this.endTime; | |
| 444 this._startTimeOffset = this.startTime - model.minimumRecordTime(); | |
| 445 | |
| 446 if (record.data) { | |
| 447 if (record.data["url"]) | |
| 448 this.url = record.data["url"]; | |
| 449 if (record.data["rootNode"]) | |
| 450 this._relatedBackendNodeId = record.data["rootNode"]; | |
| 451 else if (record.data["elementId"]) | |
| 452 this._relatedBackendNodeId = record.data["elementId"]; | |
| 453 if (record.data["scriptName"]) { | |
| 454 this.scriptName = record.data["scriptName"]; | |
| 455 this.scriptLine = record.data["scriptLine"]; | |
| 456 } | |
| 457 } | |
| 458 | |
| 459 if (parentRecord && parentRecord.callSiteStackTrace) | |
| 460 this.callSiteStackTrace = parentRecord.callSiteStackTrace; | |
| 461 | |
| 462 var recordTypes = WebInspector.TimelineModel.RecordType; | |
| 463 switch (record.type) { | |
| 464 case recordTypes.ResourceSendRequest: | |
| 465 // Make resource receive record last since request was sent; make finish record last since response received. | |
| 466 bindings._sendRequestRecords[record.data["requestId"]] = this; | |
| 467 break; | |
| 468 | |
| 469 case recordTypes.ResourceReceiveResponse: | |
| 470 var sendRequestRecord = bindings._sendRequestRecords[record.data["reques tId"]]; | |
| 471 if (sendRequestRecord) // False if we started instrumentation in the mid dle of request. | |
| 472 this.url = sendRequestRecord.url; | |
| 473 break; | |
| 474 | |
| 475 case recordTypes.ResourceReceivedData: | |
| 476 case recordTypes.ResourceFinish: | |
| 477 var sendRequestRecord = bindings._sendRequestRecords[record.data["reques tId"]]; | |
| 478 if (sendRequestRecord) // False for main resource. | |
| 479 this.url = sendRequestRecord.url; | |
| 480 break; | |
| 481 | |
| 482 case recordTypes.TimerInstall: | |
| 483 this.timeout = record.data["timeout"]; | |
| 484 this.singleShot = record.data["singleShot"]; | |
| 485 bindings._timerRecords[record.data["timerId"]] = this; | |
| 486 break; | |
| 487 | |
| 488 case recordTypes.TimerFire: | |
| 489 var timerInstalledRecord = bindings._timerRecords[record.data["timerId"] ]; | |
| 490 if (timerInstalledRecord) { | |
| 491 this.callSiteStackTrace = timerInstalledRecord.stackTrace; | |
| 492 this.timeout = timerInstalledRecord.timeout; | |
| 493 this.singleShot = timerInstalledRecord.singleShot; | |
| 494 } | |
| 495 break; | |
| 496 | |
| 497 case recordTypes.RequestAnimationFrame: | |
| 498 bindings._requestAnimationFrameRecords[record.data["id"]] = this; | |
| 499 break; | |
| 500 | |
| 501 case recordTypes.FireAnimationFrame: | |
| 502 var requestAnimationRecord = bindings._requestAnimationFrameRecords[reco rd.data["id"]]; | |
| 503 if (requestAnimationRecord) | |
| 504 this.callSiteStackTrace = requestAnimationRecord.stackTrace; | |
| 505 break; | |
| 506 | |
| 507 case recordTypes.ConsoleTime: | |
| 508 var message = record.data["message"]; | |
| 509 break; | |
| 510 | |
| 511 case recordTypes.ScheduleStyleRecalculation: | |
| 512 bindings._lastScheduleStyleRecalculation[this.frameId] = this; | |
| 513 break; | |
| 514 | |
| 515 case recordTypes.RecalculateStyles: | |
| 516 var scheduleStyleRecalculationRecord = bindings._lastScheduleStyleRecalc ulation[this.frameId]; | |
| 517 if (!scheduleStyleRecalculationRecord) | |
| 518 break; | |
| 519 this.callSiteStackTrace = scheduleStyleRecalculationRecord.stackTrace; | |
| 520 break; | |
| 521 | |
| 522 case recordTypes.InvalidateLayout: | |
| 523 // Consider style recalculation as a reason for layout invalidation, | |
| 524 // but only if we had no earlier layout invalidation records. | |
| 525 var styleRecalcStack; | |
| 526 if (!bindings._layoutInvalidateStack[this.frameId]) { | |
| 527 if (parentRecord.type === recordTypes.RecalculateStyles) | |
| 528 styleRecalcStack = parentRecord.callSiteStackTrace; | |
| 529 } | |
| 530 bindings._layoutInvalidateStack[this.frameId] = styleRecalcStack || this .stackTrace; | |
| 531 break; | |
| 532 | |
| 533 case recordTypes.Layout: | |
| 534 var layoutInvalidateStack = bindings._layoutInvalidateStack[this.frameId ]; | |
| 535 if (layoutInvalidateStack) | |
| 536 this.callSiteStackTrace = layoutInvalidateStack; | |
| 537 if (this.stackTrace) | |
| 538 this.addWarning(WebInspector.UIString("Forced synchronous layout is a possible performance bottleneck.")); | |
| 539 | |
| 540 bindings._layoutInvalidateStack[this.frameId] = null; | |
| 541 this.highlightQuad = record.data.root || WebInspector.TimelineModel._qua dFromRectData(record.data); | |
| 542 this._relatedBackendNodeId = record.data["rootNode"]; | |
| 543 break; | |
| 544 | |
| 545 case recordTypes.AutosizeText: | |
| 546 if (record.data.needsRelayout && parentRecord.type === recordTypes.Layou t) | |
| 547 parentRecord.addWarning(WebInspector.UIString("Layout required two p asses due to text autosizing, consider setting viewport.")); | |
| 548 break; | |
| 549 | |
| 550 case recordTypes.Paint: | |
| 551 this.highlightQuad = record.data.clip || WebInspector.TimelineModel._qua dFromRectData(record.data); | |
| 552 break; | |
| 553 | |
| 554 case recordTypes.WebSocketCreate: | |
| 555 this.webSocketURL = record.data["url"]; | |
| 556 if (typeof record.data["webSocketProtocol"] !== "undefined") | |
| 557 this.webSocketProtocol = record.data["webSocketProtocol"]; | |
| 558 bindings._webSocketCreateRecords[record.data["identifier"]] = this; | |
| 559 break; | |
| 560 | |
| 561 case recordTypes.WebSocketSendHandshakeRequest: | |
| 562 case recordTypes.WebSocketReceiveHandshakeResponse: | |
| 563 case recordTypes.WebSocketDestroy: | |
| 564 var webSocketCreateRecord = bindings._webSocketCreateRecords[record.data ["identifier"]]; | |
| 565 if (webSocketCreateRecord) { // False if we started instrumentation in t he middle of request. | |
| 566 this.webSocketURL = webSocketCreateRecord.webSocketURL; | |
| 567 if (typeof webSocketCreateRecord.webSocketProtocol !== "undefined") | |
| 568 this.webSocketProtocol = webSocketCreateRecord.webSocketProtocol ; | |
| 569 } | |
| 570 break; | |
| 571 | |
| 572 case recordTypes.EmbedderCallback: | |
| 573 this.embedderCallbackName = record.data["callbackName"]; | |
| 574 break; | |
| 575 } | |
| 576 } | |
| 577 | |
| 578 WebInspector.TimelineModel.Record.prototype = { | |
| 579 get lastChildEndTime() | |
| 580 { | |
| 581 return this._lastChildEndTime; | |
| 582 }, | |
| 583 | |
| 584 set lastChildEndTime(time) | |
| 585 { | |
| 586 this._lastChildEndTime = time; | |
| 587 }, | |
| 588 | |
| 589 get selfTime() | |
| 590 { | |
| 591 return this._selfTime; | |
| 592 }, | |
| 593 | |
| 594 get cpuTime() | |
| 595 { | |
| 596 return this._cpuTime; | |
| 597 }, | |
| 598 | |
| 599 /** | |
| 600 * @return {boolean} | |
| 601 */ | |
| 602 isRoot: function() | |
| 603 { | |
| 604 return this.type === WebInspector.TimelineModel.RecordType.Root; | |
| 605 }, | |
| 606 | |
| 607 /** | |
| 608 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
| 609 */ | |
| 610 get children() | |
| 611 { | |
| 612 return this._children; | |
| 613 }, | |
| 614 | |
| 615 /** | |
| 616 * @return {!WebInspector.TimelineCategory} | |
| 617 */ | |
| 618 get category() | |
| 619 { | |
| 620 return WebInspector.TimelineUIUtils.categoryForRecord(this); | |
| 621 }, | |
| 622 | |
| 623 /** | |
| 624 * @return {string} | |
| 625 */ | |
| 626 title: function() | |
| 627 { | |
| 628 return WebInspector.TimelineUIUtils.recordTitle(this); | |
| 629 }, | |
| 630 | |
| 631 /** | |
| 632 * @return {number} | |
| 633 */ | |
| 634 get startTime() | |
| 635 { | |
| 636 return this._startTime || this._record.startTime; | |
| 637 }, | |
| 638 | |
| 639 set startTime(startTime) | |
| 640 { | |
| 641 this._startTime = startTime; | |
| 642 }, | |
| 643 | |
| 644 /** | |
| 645 * @return {string|undefined} | |
| 646 */ | |
| 647 get thread() | |
| 648 { | |
| 649 return this._record.thread; | |
| 650 }, | |
| 651 | |
| 652 /** | |
| 653 * @return {number} | |
| 654 */ | |
| 655 get startTimeOffset() | |
| 656 { | |
| 657 return this._startTimeOffset; | |
| 658 }, | |
| 659 | |
| 660 /** | |
| 661 * @return {number} | |
| 662 */ | |
| 663 get endTime() | |
| 664 { | |
| 665 return this._endTime || this._record.endTime || this._record.startTime; | |
| 666 }, | |
| 667 | |
| 668 set endTime(endTime) | |
| 669 { | |
| 670 this._endTime = endTime; | |
| 671 }, | |
| 672 | |
| 673 /** | |
| 674 * @return {!Object} | |
| 675 */ | |
| 676 get data() | |
| 677 { | |
| 678 return this._record.data; | |
| 679 }, | |
| 680 | |
| 681 /** | |
| 682 * @return {string} | |
| 683 */ | |
| 684 get type() | |
| 685 { | |
| 686 return this._record.type; | |
| 687 }, | |
| 688 | |
| 689 /** | |
| 690 * @return {string} | |
| 691 */ | |
| 692 get frameId() | |
| 693 { | |
| 694 return this._record.frameId || ""; | |
| 695 }, | |
| 696 | |
| 697 /** | |
| 698 * @return {number} | |
| 699 */ | |
| 700 get usedHeapSizeDelta() | |
| 701 { | |
| 702 return this._record.usedHeapSizeDelta || 0; | |
| 703 }, | |
| 704 | |
| 705 /** | |
| 706 * @return {number} | |
| 707 */ | |
| 708 get jsHeapSizeUsed() | |
| 709 { | |
| 710 return this._record.counters ? this._record.counters.jsHeapSizeUsed || 0 : 0; | |
| 711 }, | |
| 712 | |
| 713 /** | |
| 714 * @return {!Object|undefined} | |
| 715 */ | |
| 716 get counters() | |
| 717 { | |
| 718 return this._record.counters; | |
| 719 }, | |
| 720 | |
| 721 /** | |
| 722 * @return {?Array.<!ConsoleAgent.CallFrame>} | |
| 723 */ | |
| 724 get stackTrace() | |
| 725 { | |
| 726 if (this._record.stackTrace && this._record.stackTrace.length) | |
| 727 return this._record.stackTrace; | |
| 728 return null; | |
| 729 }, | |
| 730 | |
| 731 /** | |
| 732 * @param {string} key | |
| 733 * @return {?Object} | |
| 734 */ | |
| 735 getUserObject: function(key) | |
| 736 { | |
| 737 if (!this._userObjects) | |
| 738 return null; | |
| 739 return this._userObjects.get(key); | |
| 740 }, | |
| 741 | |
| 742 /** | |
| 743 * @param {string} key | |
| 744 * @param {?Object|undefined} value | |
| 745 */ | |
| 746 setUserObject: function(key, value) | |
| 747 { | |
| 748 if (!this._userObjects) | |
| 749 this._userObjects = new StringMap(); | |
| 750 this._userObjects.put(key, value); | |
| 751 }, | |
| 752 | |
| 753 /** | |
| 754 * @return {number} nodeId | |
| 755 */ | |
| 756 relatedBackendNodeId: function() | |
| 757 { | |
| 758 return this._relatedBackendNodeId; | |
| 759 }, | |
| 760 | |
| 761 calculateAggregatedStats: function() | |
| 762 { | |
| 763 this._aggregatedStats = {}; | |
| 764 this._cpuTime = this._selfTime; | |
| 765 | |
| 766 for (var index = this._children.length; index; --index) { | |
| 767 var child = this._children[index - 1]; | |
| 768 for (var category in child._aggregatedStats) | |
| 769 this._aggregatedStats[category] = (this._aggregatedStats[categor y] || 0) + child._aggregatedStats[category]; | |
| 770 } | |
| 771 for (var category in this._aggregatedStats) | |
| 772 this._cpuTime += this._aggregatedStats[category]; | |
| 773 this._aggregatedStats[this.category.name] = (this._aggregatedStats[this. category.name] || 0) + this._selfTime; | |
| 774 }, | |
| 775 | |
| 776 get aggregatedStats() | |
| 777 { | |
| 778 return this._aggregatedStats; | |
| 779 }, | |
| 780 | |
| 781 /** | |
| 782 * @param {string} message | |
| 783 */ | |
| 784 addWarning: function(message) | |
| 785 { | |
| 786 if (this._warnings) | |
| 787 this._warnings.push(message); | |
| 788 else | |
| 789 this._warnings = [message]; | |
| 790 }, | |
| 791 | |
| 792 /** | |
| 793 * @return {!Object} | |
| 794 */ | |
| 795 warnings: function() | |
| 796 { | |
| 797 return this._warnings; | |
| 798 }, | |
| 799 | |
| 800 /** | |
| 801 * @return {boolean} | |
| 802 */ | |
| 803 childHasWarnings: function() | |
|
caseq
2014/03/03 09:08:32
drop this
pfeldman
2014/03/03 10:03:45
Done.
| |
| 804 { | |
| 805 return this._childHasWarnings; | |
| 806 }, | |
| 807 | |
| 808 /** | |
| 809 * @param {!RegExp} regExp | |
| 810 * @return {boolean} | |
| 811 */ | |
| 812 testContentMatching: function(regExp) | |
| 813 { | |
| 814 var tokens = [this.title()]; | |
| 815 for (var key in this._record.data) | |
| 816 tokens.push(this._record.data[key]) | |
| 817 return regExp.test(tokens.join("|")); | |
| 818 } | |
| 819 } | |
| 820 | |
| 343 /** | 821 /** |
| 344 * @constructor | 822 * @constructor |
| 345 * @implements {WebInspector.OutputStream} | 823 * @implements {WebInspector.OutputStream} |
| 346 * @param {!WebInspector.TimelineModel} model | 824 * @param {!WebInspector.TimelineModel} model |
| 347 * @param {!{cancel: function()}} reader | 825 * @param {!{cancel: function()}} reader |
| 348 * @param {!WebInspector.Progress} progress | 826 * @param {!WebInspector.Progress} progress |
| 349 */ | 827 */ |
| 350 WebInspector.TimelineModelLoader = function(model, reader, progress) | 828 WebInspector.TimelineModelLoader = function(model, reader, progress) |
| 351 { | 829 { |
| 352 this._model = model; | 830 this._model = model; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 /** | 950 /** |
| 473 * @constructor | 951 * @constructor |
| 474 */ | 952 */ |
| 475 WebInspector.TimelineSaver = function(stream) | 953 WebInspector.TimelineSaver = function(stream) |
| 476 { | 954 { |
| 477 this._stream = stream; | 955 this._stream = stream; |
| 478 } | 956 } |
| 479 | 957 |
| 480 WebInspector.TimelineSaver.prototype = { | 958 WebInspector.TimelineSaver.prototype = { |
| 481 /** | 959 /** |
| 482 * @param {!Array.<*>} records | 960 * @param {!Array.<*>} payloads |
| 483 * @param {string} version | 961 * @param {string} version |
| 484 */ | 962 */ |
| 485 save: function(records, version) | 963 save: function(payloads, version) |
| 486 { | 964 { |
| 487 this._records = records; | 965 this._payloads = payloads; |
| 488 this._recordIndex = 0; | 966 this._recordIndex = 0; |
| 489 this._prologue = "[" + JSON.stringify(version); | 967 this._prologue = "[" + JSON.stringify(version); |
| 490 | 968 |
| 491 this._writeNextChunk(this._stream); | 969 this._writeNextChunk(this._stream); |
| 492 }, | 970 }, |
| 493 | 971 |
| 494 _writeNextChunk: function(stream) | 972 _writeNextChunk: function(stream) |
| 495 { | 973 { |
| 496 const separator = ",\n"; | 974 const separator = ",\n"; |
| 497 var data = []; | 975 var data = []; |
| 498 var length = 0; | 976 var length = 0; |
| 499 | 977 |
| 500 if (this._prologue) { | 978 if (this._prologue) { |
| 501 data.push(this._prologue); | 979 data.push(this._prologue); |
| 502 length += this._prologue.length; | 980 length += this._prologue.length; |
| 503 delete this._prologue; | 981 delete this._prologue; |
| 504 } else { | 982 } else { |
| 505 if (this._recordIndex === this._records.length) { | 983 if (this._recordIndex === this._payloads.length) { |
| 506 stream.close(); | 984 stream.close(); |
| 507 return; | 985 return; |
| 508 } | 986 } |
| 509 data.push(""); | 987 data.push(""); |
| 510 } | 988 } |
| 511 while (this._recordIndex < this._records.length) { | 989 while (this._recordIndex < this._payloads.length) { |
| 512 var item = JSON.stringify(this._records[this._recordIndex]); | 990 var item = JSON.stringify(this._payloads[this._recordIndex]); |
| 513 var itemLength = item.length + separator.length; | 991 var itemLength = item.length + separator.length; |
| 514 if (length + itemLength > WebInspector.TimelineModel.TransferChunkLe ngthBytes) | 992 if (length + itemLength > WebInspector.TimelineModel.TransferChunkLe ngthBytes) |
| 515 break; | 993 break; |
| 516 length += itemLength; | 994 length += itemLength; |
| 517 data.push(item); | 995 data.push(item); |
| 518 ++this._recordIndex; | 996 ++this._recordIndex; |
| 519 } | 997 } |
| 520 if (this._recordIndex === this._records.length) | 998 if (this._recordIndex === this._payloads.length) |
| 521 data.push(data.pop() + "]"); | 999 data.push(data.pop() + "]"); |
| 522 stream.write(data.join(separator), this._writeNextChunk.bind(this)); | 1000 stream.write(data.join(separator), this._writeNextChunk.bind(this)); |
| 523 } | 1001 } |
| 524 } | 1002 } |
| 525 | 1003 |
| 526 /** | 1004 /** |
| 527 * @constructor | 1005 * @constructor |
| 528 */ | 1006 */ |
| 529 WebInspector.TimelineMergingRecordBuffer = function() | 1007 WebInspector.TimelineMergingRecordBuffer = function() |
| 530 { | 1008 { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 552 */ | 1030 */ |
| 553 function recordTimestampComparator(a, b) | 1031 function recordTimestampComparator(a, b) |
| 554 { | 1032 { |
| 555 // Never return 0, as the merge function will squash identical entri es. | 1033 // Never return 0, as the merge function will squash identical entri es. |
| 556 return a.startTime < b.startTime ? -1 : 1; | 1034 return a.startTime < b.startTime ? -1 : 1; |
| 557 } | 1035 } |
| 558 var result = this._backgroundRecordsBuffer.mergeOrdered(records, recordT imestampComparator); | 1036 var result = this._backgroundRecordsBuffer.mergeOrdered(records, recordT imestampComparator); |
| 559 this._backgroundRecordsBuffer = []; | 1037 this._backgroundRecordsBuffer = []; |
| 560 return result; | 1038 return result; |
| 561 } | 1039 } |
| 562 }; | 1040 } |
| 1041 | |
| 1042 /** | |
| 1043 * @param {!Object} data | |
| 1044 * @return {?Array.<number>} | |
| 1045 */ | |
| 1046 WebInspector.TimelineModel._quadFromRectData = function(data) | |
| 1047 { | |
| 1048 if (typeof data["x"] === "undefined" || typeof data["y"] === "undefined") | |
| 1049 return null; | |
| 1050 var x0 = data["x"]; | |
| 1051 var x1 = data["x"] + data["width"]; | |
| 1052 var y0 = data["y"]; | |
| 1053 var y1 = data["y"] + data["height"]; | |
| 1054 return [x0, y0, x1, y0, x1, y1, x0, y1]; | |
| 1055 } | |
| OLD | NEW |