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 |