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 12 matching lines...) Expand all Loading... |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
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.TargetAwareObject} |
34 * @param {!WebInspector.Target} target | 34 * @param {!WebInspector.Target} target |
35 */ | 35 */ |
36 WebInspector.TimelineModel = function(target) | 36 WebInspector.TimelineModel = function(target) |
37 { | 37 { |
| 38 WebInspector.TargetAwareObject.call(this, target); |
38 this._filters = []; | 39 this._filters = []; |
39 this._target = target; | |
40 } | 40 } |
41 | 41 |
42 WebInspector.TimelineModel.RecordType = { | 42 WebInspector.TimelineModel.RecordType = { |
43 Root: "Root", | 43 Root: "Root", |
44 Program: "Program", | 44 Program: "Program", |
45 EventDispatch: "EventDispatch", | 45 EventDispatch: "EventDispatch", |
46 | 46 |
47 GPUTask: "GPUTask", | 47 GPUTask: "GPUTask", |
48 | 48 |
49 RequestMainThreadFrame: "RequestMainThreadFrame", | 49 RequestMainThreadFrame: "RequestMainThreadFrame", |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 if (postOrderCallback && postOrderCallback(record, depth)) | 136 if (postOrderCallback && postOrderCallback(record, depth)) |
137 return true; | 137 return true; |
138 } | 138 } |
139 return false; | 139 return false; |
140 } | 140 } |
141 return processRecords(recordsArray, 0); | 141 return processRecords(recordsArray, 0); |
142 } | 142 } |
143 | 143 |
144 WebInspector.TimelineModel.prototype = { | 144 WebInspector.TimelineModel.prototype = { |
145 /** | 145 /** |
146 * @return {!WebInspector.Target} | |
147 */ | |
148 target: function() | |
149 { | |
150 return this._target; | |
151 }, | |
152 | |
153 /** | |
154 * @return {boolean} | 146 * @return {boolean} |
155 */ | 147 */ |
156 loadedFromFile: function() | 148 loadedFromFile: function() |
157 { | 149 { |
158 return false; | 150 return false; |
159 }, | 151 }, |
160 | 152 |
161 /** | 153 /** |
162 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspe
ctor.TimelineModel.Record,number)} preOrderCallback | 154 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspe
ctor.TimelineModel.Record,number)} preOrderCallback |
163 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect
or.TimelineModel.Record,number)=} postOrderCallback | 155 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect
or.TimelineModel.Record,number)=} postOrderCallback |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 return false; | 209 return false; |
218 } | 210 } |
219 return true; | 211 return true; |
220 }, | 212 }, |
221 | 213 |
222 _filterChanged: function() | 214 _filterChanged: function() |
223 { | 215 { |
224 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordFi
lterChanged); | 216 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordFi
lterChanged); |
225 }, | 217 }, |
226 | 218 |
227 willStartRecordingTraceEvents: function() | |
228 { | |
229 this.reset(); | |
230 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.Recordin
gStarted); | |
231 }, | |
232 | |
233 /** | |
234 * @param {!Array.<!WebInspector.TracingModel.Event>} mainThreadEvents | |
235 */ | |
236 didStopRecordingTraceEvents: function(mainThreadEvents) | |
237 { | |
238 var recordStack = []; | |
239 for (var i = 0, size = mainThreadEvents.length; i < size; ++i) { | |
240 var event = mainThreadEvents[i]; | |
241 while (recordStack.length) { | |
242 var top = recordStack.peekLast(); | |
243 if (top._event.endTime >= event.startTime) | |
244 break; | |
245 recordStack.pop(); | |
246 } | |
247 var parentRecord = recordStack.peekLast() || null; | |
248 var record = new WebInspector.TimelineModel.TraceEventRecord(this, e
vent, parentRecord); | |
249 if (WebInspector.TimelineUIUtils.isEventDivider(record)) | |
250 this._eventDividerRecords.push(record); | |
251 if (!recordStack.length) | |
252 this._addTopLevelRecord(record); | |
253 if (event.endTime) | |
254 recordStack.push(record); | |
255 } | |
256 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.Recordin
gStopped); | |
257 }, | |
258 | |
259 /** | |
260 * @param {!WebInspector.TimelineModel.TraceEventRecord} record | |
261 */ | |
262 _addTopLevelRecord: function(record) | |
263 { | |
264 this._updateBoundaries(record); | |
265 this._records.push(record); | |
266 if (record.type() === WebInspector.TimelineModel.RecordType.Program) | |
267 this._mainThreadTasks.push(record); | |
268 if (record.type() === WebInspector.TimelineModel.RecordType.GPUTask) | |
269 this._gpuThreadTasks.push(record); | |
270 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd
ded, record); | |
271 }, | |
272 | |
273 /** | 219 /** |
274 * @return {!Array.<!WebInspector.TimelineModel.Record>} | 220 * @return {!Array.<!WebInspector.TimelineModel.Record>} |
275 */ | 221 */ |
276 records: function() | 222 records: function() |
277 { | 223 { |
278 return this._records; | 224 return this._records; |
279 }, | 225 }, |
280 | 226 |
281 /** | 227 /** |
282 * @param {!Blob} file | 228 * @param {!Blob} file |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 }, | 309 }, |
364 | 310 |
365 /** | 311 /** |
366 * @return {!Array.<!WebInspector.TimelineModel.Record>} | 312 * @return {!Array.<!WebInspector.TimelineModel.Record>} |
367 */ | 313 */ |
368 eventDividerRecords: function() | 314 eventDividerRecords: function() |
369 { | 315 { |
370 return this._eventDividerRecords; | 316 return this._eventDividerRecords; |
371 }, | 317 }, |
372 | 318 |
373 __proto__: WebInspector.Object.prototype | 319 __proto__: WebInspector.TargetAwareObject.prototype |
374 } | 320 } |
375 | 321 |
376 /** | 322 /** |
377 * @interface | 323 * @interface |
378 */ | 324 */ |
379 WebInspector.TimelineModel.Record = function() | 325 WebInspector.TimelineModel.Record = function() |
380 { | 326 { |
381 } | 327 } |
382 | 328 |
383 WebInspector.TimelineModel.Record.prototype = { | 329 WebInspector.TimelineModel.Record.prototype = { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 */ | 424 */ |
479 warnings: function() { }, | 425 warnings: function() { }, |
480 | 426 |
481 /** | 427 /** |
482 * @param {!RegExp} regExp | 428 * @param {!RegExp} regExp |
483 * @return {boolean} | 429 * @return {boolean} |
484 */ | 430 */ |
485 testContentMatching: function(regExp) { } | 431 testContentMatching: function(regExp) { } |
486 } | 432 } |
487 | 433 |
488 | |
489 /** | |
490 * @constructor | |
491 * @implements {WebInspector.TimelineModel.Record} | |
492 * @param {!WebInspector.TimelineModel} model | |
493 * @param {!WebInspector.TracingModel.Event} traceEvent | |
494 * @param {?WebInspector.TimelineModel.TraceEventRecord} parentRecord | |
495 */ | |
496 WebInspector.TimelineModel.TraceEventRecord = function(model, traceEvent, parent
Record) | |
497 { | |
498 this._model = model; | |
499 this._event = traceEvent; | |
500 traceEvent._timelineRecord = this; | |
501 if (parentRecord) { | |
502 this.parent = parentRecord; | |
503 parentRecord._children.push(this); | |
504 } | |
505 this._children = []; | |
506 } | |
507 | |
508 WebInspector.TimelineModel.TraceEventRecord.prototype = { | |
509 /** | |
510 * @return {?Array.<!ConsoleAgent.CallFrame>} | |
511 */ | |
512 callSiteStackTrace: function() | |
513 { | |
514 var initiator = this._event.initiator; | |
515 return initiator ? initiator.stackTrace : null; | |
516 }, | |
517 | |
518 /** | |
519 * @return {?WebInspector.TimelineModel.Record} | |
520 */ | |
521 initiator: function() | |
522 { | |
523 var initiator = this._event.initiator; | |
524 return initiator ? initiator._timelineRecord : null; | |
525 }, | |
526 | |
527 /** | |
528 * @return {!WebInspector.Target} | |
529 */ | |
530 target: function() | |
531 { | |
532 return this._model.target(); | |
533 }, | |
534 | |
535 /** | |
536 * @return {number} | |
537 */ | |
538 selfTime: function() | |
539 { | |
540 return this._event.selfTime; | |
541 }, | |
542 | |
543 /** | |
544 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
545 */ | |
546 children: function() | |
547 { | |
548 return this._children; | |
549 }, | |
550 | |
551 /** | |
552 * @return {!WebInspector.TimelineCategory} | |
553 */ | |
554 category: function() | |
555 { | |
556 var style = WebInspector.TimelineUIUtils.styleForTimelineEvent(this._eve
nt.name); | |
557 return style.category; | |
558 }, | |
559 | |
560 /** | |
561 * @return {string} | |
562 */ | |
563 title: function() | |
564 { | |
565 return WebInspector.TimelineUIUtils.recordTitle(this, this._model); | |
566 }, | |
567 | |
568 /** | |
569 * @return {number} | |
570 */ | |
571 startTime: function() | |
572 { | |
573 return this._event.startTime; | |
574 }, | |
575 | |
576 /** | |
577 * @return {string|undefined} | |
578 */ | |
579 thread: function() | |
580 { | |
581 return "CPU"; | |
582 }, | |
583 | |
584 /** | |
585 * @return {number} | |
586 */ | |
587 endTime: function() | |
588 { | |
589 return this._event.endTime || this._event.startTime; | |
590 }, | |
591 | |
592 /** | |
593 * @param {number} endTime | |
594 */ | |
595 setEndTime: function(endTime) | |
596 { | |
597 throw new Error("Unsupported operation setEndTime"); | |
598 }, | |
599 | |
600 /** | |
601 * @return {!Object} | |
602 */ | |
603 data: function() | |
604 { | |
605 return this._event.args.data; | |
606 }, | |
607 | |
608 /** | |
609 * @return {string} | |
610 */ | |
611 type: function() | |
612 { | |
613 return this._event.name; | |
614 }, | |
615 | |
616 /** | |
617 * @return {string} | |
618 */ | |
619 frameId: function() | |
620 { | |
621 switch (this._event.name) { | |
622 case WebInspector.TracingTimelineModel.RecordType.ScheduleStyleRecalcula
tion: | |
623 case WebInspector.TracingTimelineModel.RecordType.RecalculateStyles: | |
624 case WebInspector.TracingTimelineModel.RecordType.InvalidateLayout: | |
625 return this._event.args["frameId"]; | |
626 case WebInspector.TracingTimelineModel.RecordType.Layout: | |
627 return this._event.args["beginData"]["frameId"]; | |
628 default: | |
629 var data = this._event.args.data; | |
630 return (data && data["frame"]) || ""; | |
631 } | |
632 }, | |
633 | |
634 /** | |
635 * @return {?Array.<!ConsoleAgent.CallFrame>} | |
636 */ | |
637 stackTrace: function() | |
638 { | |
639 return this._event.stackTrace; | |
640 }, | |
641 | |
642 /** | |
643 * @param {string} key | |
644 * @return {?Object} | |
645 */ | |
646 getUserObject: function(key) | |
647 { | |
648 if (key === "TimelineUIUtils::preview-element") | |
649 return this._event.previewElement; | |
650 throw new Error("Unexpected key: " + key); | |
651 }, | |
652 | |
653 /** | |
654 * @param {string} key | |
655 * @param {?Object|undefined} value | |
656 */ | |
657 setUserObject: function(key, value) | |
658 { | |
659 if (key !== "TimelineUIUtils::preview-element") | |
660 throw new Error("Unexpected key: " + key); | |
661 this._event.previewElement = /** @type {?Element} */ (value); | |
662 }, | |
663 | |
664 /** | |
665 * @return {!Object.<string, number>} | |
666 */ | |
667 aggregatedStats: function() | |
668 { | |
669 return {}; | |
670 }, | |
671 | |
672 /** | |
673 * @return {?Array.<string>} | |
674 */ | |
675 warnings: function() | |
676 { | |
677 if (this._event.warning) | |
678 return [this._event.warning]; | |
679 return null; | |
680 }, | |
681 | |
682 /** | |
683 * @param {!RegExp} regExp | |
684 * @return {boolean} | |
685 */ | |
686 testContentMatching: function(regExp) | |
687 { | |
688 var tokens = [this.title()]; | |
689 var data = this._event.args.data; | |
690 if (data) { | |
691 for (var key in data) | |
692 tokens.push(data[key]); | |
693 } | |
694 return regExp.test(tokens.join("|")); | |
695 } | |
696 } | |
697 | |
698 /** | 434 /** |
699 * @constructor | 435 * @constructor |
700 */ | 436 */ |
701 WebInspector.TimelineModel.Filter = function() | 437 WebInspector.TimelineModel.Filter = function() |
702 { | 438 { |
703 /** @type {!WebInspector.TimelineModel} */ | 439 /** @type {!WebInspector.TimelineModel} */ |
704 this._model; | 440 this._model; |
705 } | 441 } |
706 | 442 |
707 WebInspector.TimelineModel.Filter.prototype = { | 443 WebInspector.TimelineModel.Filter.prototype = { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 function recordTimestampComparator(a, b) | 486 function recordTimestampComparator(a, b) |
751 { | 487 { |
752 // Never return 0, as the merge function will squash identical entri
es. | 488 // Never return 0, as the merge function will squash identical entri
es. |
753 return a.startTime() < b.startTime() ? -1 : 1; | 489 return a.startTime() < b.startTime() ? -1 : 1; |
754 } | 490 } |
755 var result = this._backgroundRecordsBuffer.mergeOrdered(records, recordT
imestampComparator); | 491 var result = this._backgroundRecordsBuffer.mergeOrdered(records, recordT
imestampComparator); |
756 this._backgroundRecordsBuffer = []; | 492 this._backgroundRecordsBuffer = []; |
757 return result; | 493 return result; |
758 } | 494 } |
759 } | 495 } |
OLD | NEW |