OLD | NEW |
1 /* | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * | 3 // found in the LICENSE file. |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
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. | |
29 */ | |
30 | 4 |
31 /** | 5 /** |
32 * @constructor | 6 * @constructor |
33 * @extends {WebInspector.Object} | 7 * @extends {WebInspector.TimelineModel} |
34 * @param {!WebInspector.TimelineManager} timelineManager | 8 * @param {!WebInspector.TimelineManager} timelineManager |
35 */ | 9 */ |
36 WebInspector.TimelineModel = function(timelineManager) | 10 WebInspector.TimelineModelImpl = function(timelineManager) |
37 { | 11 { |
| 12 WebInspector.TimelineModel.call(this, timelineManager.target()); |
38 this._timelineManager = timelineManager; | 13 this._timelineManager = timelineManager; |
39 this._filters = []; | 14 this._filters = []; |
40 this._bindings = new WebInspector.TimelineModel.InterRecordBindings(); | 15 this._bindings = new WebInspector.TimelineModelImpl.InterRecordBindings(); |
41 | 16 |
42 this.reset(); | 17 this.reset(); |
43 | 18 |
44 this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTyp
es.TimelineEventRecorded, this._onRecordAdded, this); | 19 this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTyp
es.TimelineEventRecorded, this._onRecordAdded, this); |
45 this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTyp
es.TimelineStarted, this._onStarted, this); | 20 this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTyp
es.TimelineStarted, this._onStarted, this); |
46 this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTyp
es.TimelineStopped, this._onStopped, this); | 21 this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTyp
es.TimelineStopped, this._onStopped, this); |
47 this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTyp
es.TimelineProgress, this._onProgress, this); | 22 this._timelineManager.addEventListener(WebInspector.TimelineManager.EventTyp
es.TimelineProgress, this._onProgress, this); |
48 } | 23 } |
49 | 24 |
50 WebInspector.TimelineModel.TransferChunkLengthBytes = 5000000; | 25 WebInspector.TimelineModelImpl.TransferChunkLengthBytes = 5000000; |
51 | 26 |
52 WebInspector.TimelineModel.RecordType = { | 27 WebInspector.TimelineModelImpl.prototype = { |
53 Root: "Root", | |
54 Program: "Program", | |
55 EventDispatch: "EventDispatch", | |
56 | |
57 GPUTask: "GPUTask", | |
58 | |
59 RequestMainThreadFrame: "RequestMainThreadFrame", | |
60 BeginFrame: "BeginFrame", | |
61 ActivateLayerTree: "ActivateLayerTree", | |
62 DrawFrame: "DrawFrame", | |
63 ScheduleStyleRecalculation: "ScheduleStyleRecalculation", | |
64 RecalculateStyles: "RecalculateStyles", | |
65 InvalidateLayout: "InvalidateLayout", | |
66 Layout: "Layout", | |
67 UpdateLayerTree: "UpdateLayerTree", | |
68 PaintSetup: "PaintSetup", | |
69 Paint: "Paint", | |
70 Rasterize: "Rasterize", | |
71 ScrollLayer: "ScrollLayer", | |
72 DecodeImage: "DecodeImage", | |
73 ResizeImage: "ResizeImage", | |
74 CompositeLayers: "CompositeLayers", | |
75 | |
76 ParseHTML: "ParseHTML", | |
77 | |
78 TimerInstall: "TimerInstall", | |
79 TimerRemove: "TimerRemove", | |
80 TimerFire: "TimerFire", | |
81 | |
82 XHRReadyStateChange: "XHRReadyStateChange", | |
83 XHRLoad: "XHRLoad", | |
84 EvaluateScript: "EvaluateScript", | |
85 | |
86 MarkLoad: "MarkLoad", | |
87 MarkDOMContent: "MarkDOMContent", | |
88 MarkFirstPaint: "MarkFirstPaint", | |
89 | |
90 TimeStamp: "TimeStamp", | |
91 ConsoleTime: "ConsoleTime", | |
92 | |
93 ResourceSendRequest: "ResourceSendRequest", | |
94 ResourceReceiveResponse: "ResourceReceiveResponse", | |
95 ResourceReceivedData: "ResourceReceivedData", | |
96 ResourceFinish: "ResourceFinish", | |
97 | |
98 FunctionCall: "FunctionCall", | |
99 GCEvent: "GCEvent", | |
100 JSFrame: "JSFrame", | |
101 | |
102 UpdateCounters: "UpdateCounters", | |
103 | |
104 RequestAnimationFrame: "RequestAnimationFrame", | |
105 CancelAnimationFrame: "CancelAnimationFrame", | |
106 FireAnimationFrame: "FireAnimationFrame", | |
107 | |
108 WebSocketCreate : "WebSocketCreate", | |
109 WebSocketSendHandshakeRequest : "WebSocketSendHandshakeRequest", | |
110 WebSocketReceiveHandshakeResponse : "WebSocketReceiveHandshakeResponse", | |
111 WebSocketDestroy : "WebSocketDestroy", | |
112 | |
113 EmbedderCallback : "EmbedderCallback", | |
114 } | |
115 | |
116 WebInspector.TimelineModel.Events = { | |
117 RecordAdded: "RecordAdded", | |
118 RecordsCleared: "RecordsCleared", | |
119 RecordingStarted: "RecordingStarted", | |
120 RecordingStopped: "RecordingStopped", | |
121 RecordingProgress: "RecordingProgress", | |
122 RecordFilterChanged: "RecordFilterChanged" | |
123 } | |
124 | |
125 /** | |
126 * @param {!Array.<!WebInspector.TimelineModel.Record>} recordsArray | |
127 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspector
.TimelineModel.Record,number)} preOrderCallback | |
128 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspector.T
imelineModel.Record,number)=} postOrderCallback | |
129 * @return {boolean} | |
130 */ | |
131 WebInspector.TimelineModel.forAllRecords = function(recordsArray, preOrderCallba
ck, postOrderCallback) | |
132 { | |
133 /** | |
134 * @param {!Array.<!WebInspector.TimelineModel.Record>} records | |
135 * @param {number} depth | |
136 * @return {boolean} | |
137 */ | |
138 function processRecords(records, depth) | |
139 { | |
140 for (var i = 0; i < records.length; ++i) { | |
141 var record = records[i]; | |
142 if (preOrderCallback && preOrderCallback(record, depth)) | |
143 return true; | |
144 if (processRecords(record.children(), depth + 1)) | |
145 return true; | |
146 if (postOrderCallback && postOrderCallback(record, depth)) | |
147 return true; | |
148 } | |
149 return false; | |
150 } | |
151 return processRecords(recordsArray, 0); | |
152 } | |
153 | |
154 WebInspector.TimelineModel.prototype = { | |
155 /** | |
156 * @return {!WebInspector.Target} | |
157 */ | |
158 target: function() | |
159 { | |
160 return this._timelineManager.target(); | |
161 }, | |
162 | |
163 /** | 28 /** |
164 * @return {boolean} | 29 * @return {boolean} |
165 */ | 30 */ |
166 loadedFromFile: function() | 31 loadedFromFile: function() |
167 { | 32 { |
168 return this._loadedFromFile; | 33 return this._loadedFromFile; |
169 }, | 34 }, |
170 | 35 |
171 /** | 36 /** |
172 * @param {?function(!WebInspector.TimelineModel.Record)|?function(!WebInspe
ctor.TimelineModel.Record,number)} preOrderCallback | |
173 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect
or.TimelineModel.Record,number)=} postOrderCallback | |
174 */ | |
175 forAllRecords: function(preOrderCallback, postOrderCallback) | |
176 { | |
177 WebInspector.TimelineModel.forAllRecords(this._records, preOrderCallback
, postOrderCallback); | |
178 }, | |
179 | |
180 /** | |
181 * @param {!WebInspector.TimelineModel.Filter} filter | |
182 */ | |
183 addFilter: function(filter) | |
184 { | |
185 this._filters.push(filter); | |
186 filter._model = this; | |
187 }, | |
188 | |
189 /** | |
190 * @param {function(!WebInspector.TimelineModel.Record)|function(!WebInspect
or.TimelineModel.Record,number)} callback | |
191 */ | |
192 forAllFilteredRecords: function(callback) | |
193 { | |
194 /** | |
195 * @param {!WebInspector.TimelineModel.Record} record | |
196 * @param {number} depth | |
197 * @this {WebInspector.TimelineModel} | |
198 * @return {boolean} | |
199 */ | |
200 function processRecord(record, depth) | |
201 { | |
202 var visible = this.isVisible(record); | |
203 if (visible) { | |
204 if (callback(record, depth)) | |
205 return true; | |
206 } | |
207 | |
208 for (var i = 0; i < record.children().length; ++i) { | |
209 if (processRecord.call(this, record.children()[i], visible ? dep
th + 1 : depth)) | |
210 return true; | |
211 } | |
212 return false; | |
213 } | |
214 | |
215 for (var i = 0; i < this._records.length; ++i) | |
216 processRecord.call(this, this._records[i], 0); | |
217 }, | |
218 | |
219 /** | |
220 * @param {!WebInspector.TimelineModel.Record} record | |
221 * @return {boolean} | |
222 */ | |
223 isVisible: function(record) | |
224 { | |
225 for (var i = 0; i < this._filters.length; ++i) { | |
226 if (!this._filters[i].accept(record)) | |
227 return false; | |
228 } | |
229 return true; | |
230 }, | |
231 | |
232 _filterChanged: function() | |
233 { | |
234 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordFi
lterChanged); | |
235 }, | |
236 | |
237 /** | |
238 * @param {boolean} captureStacks | 37 * @param {boolean} captureStacks |
239 * @param {boolean} captureMemory | 38 * @param {boolean} captureMemory |
240 */ | 39 */ |
241 startRecording: function(captureStacks, captureMemory) | 40 startRecording: function(captureStacks, captureMemory) |
242 { | 41 { |
243 this._clientInitiatedRecording = true; | 42 this._clientInitiatedRecording = true; |
244 this.reset(); | 43 this.reset(); |
245 var maxStackFrames = captureStacks ? 30 : 0; | 44 var maxStackFrames = captureStacks ? 30 : 0; |
246 this._bufferEvents = WebInspector.experimentsSettings.timelineNoLiveUpda
te.isEnabled(); | 45 this._bufferEvents = WebInspector.experimentsSettings.timelineNoLiveUpda
te.isEnabled(); |
247 var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEn
abled(); | 46 var includeGPUEvents = WebInspector.experimentsSettings.gpuTimeline.isEn
abled(); |
248 var liveEvents = [ WebInspector.TimelineModel.RecordType.BeginFrame, | 47 var liveEvents = [ WebInspector.TimelineModel.RecordType.BeginFrame, |
249 WebInspector.TimelineModel.RecordType.DrawFrame, | 48 WebInspector.TimelineModel.RecordType.DrawFrame, |
250 WebInspector.TimelineModel.RecordType.RequestMainThre
adFrame, | 49 WebInspector.TimelineModel.RecordType.RequestMainThre
adFrame, |
251 WebInspector.TimelineModel.RecordType.ActivateLayerTr
ee ]; | 50 WebInspector.TimelineModel.RecordType.ActivateLayerTr
ee ]; |
252 this._timelineManager.start(maxStackFrames, this._bufferEvents, liveEven
ts.join(","), captureMemory, includeGPUEvents, this._fireRecordingStarted.bind(t
his)); | 51 this._timelineManager.start(maxStackFrames, this._bufferEvents, liveEven
ts.join(","), captureMemory, includeGPUEvents, this._fireRecordingStarted.bind(t
his)); |
253 }, | 52 }, |
254 | 53 |
255 stopRecording: function() | 54 stopRecording: function() |
256 { | 55 { |
257 if (!this._clientInitiatedRecording) { | 56 if (!this._clientInitiatedRecording) { |
258 this._timelineManager.start(undefined, undefined, undefined, undefin
ed, undefined, stopTimeline.bind(this)); | 57 this._timelineManager.start(undefined, undefined, undefined, undefin
ed, undefined, stopTimeline.bind(this)); |
259 return; | 58 return; |
260 } | 59 } |
261 | 60 |
262 /** | 61 /** |
263 * Console started this one and we are just sniffing it. Initiate record
ing so that we | 62 * Console started this one and we are just sniffing it. Initiate record
ing so that we |
264 * could stop it. | 63 * could stop it. |
265 * @this {WebInspector.TimelineModel} | 64 * @this {WebInspector.TimelineModelImpl} |
266 */ | 65 */ |
267 function stopTimeline() | 66 function stopTimeline() |
268 { | 67 { |
269 this._timelineManager.stop(this._fireRecordingStopped.bind(this)); | 68 this._timelineManager.stop(this._fireRecordingStopped.bind(this)); |
270 } | 69 } |
271 | 70 |
272 this._clientInitiatedRecording = false; | 71 this._clientInitiatedRecording = false; |
273 this._timelineManager.stop(this._fireRecordingStopped.bind(this)); | 72 this._timelineManager.stop(this._fireRecordingStopped.bind(this)); |
274 }, | 73 }, |
275 | 74 |
276 willStartRecordingTraceEvents: function() | |
277 { | |
278 this.reset(); | |
279 this._fireRecordingStarted(); | |
280 }, | |
281 | |
282 /** | |
283 * @param {!Array.<!WebInspector.TracingModel.Event>} mainThreadEvents | |
284 */ | |
285 didStopRecordingTraceEvents: function(mainThreadEvents) | |
286 { | |
287 var recordStack = []; | |
288 for (var i = 0, size = mainThreadEvents.length; i < size; ++i) { | |
289 var event = mainThreadEvents[i]; | |
290 while (recordStack.length) { | |
291 var top = recordStack.peekLast(); | |
292 if (top._event.endTime >= event.startTime) | |
293 break; | |
294 recordStack.pop(); | |
295 } | |
296 var parentRecord = recordStack.peekLast() || null; | |
297 var record = new WebInspector.TimelineModel.TraceEventRecord(this, e
vent, parentRecord); | |
298 if (WebInspector.TimelineUIUtils.isEventDivider(record)) | |
299 this._eventDividerRecords.push(record); | |
300 if (!recordStack.length) | |
301 this._addTopLevelRecord(record); | |
302 if (event.endTime) | |
303 recordStack.push(record); | |
304 } | |
305 this._fireRecordingStopped(null, null); | |
306 }, | |
307 | |
308 /** | |
309 * @param {!WebInspector.TimelineModel.TraceEventRecord} record | |
310 */ | |
311 _addTopLevelRecord: function(record) | |
312 { | |
313 this._updateBoundaries(record); | |
314 this._records.push(record); | |
315 if (record.type() === WebInspector.TimelineModel.RecordType.Program) | |
316 this._mainThreadTasks.push(record); | |
317 if (record.type() === WebInspector.TimelineModel.RecordType.GPUTask) | |
318 this._gpuThreadTasks.push(record); | |
319 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordAd
ded, record); | |
320 }, | |
321 | |
322 /** | 75 /** |
323 * @return {!Array.<!WebInspector.TimelineModel.Record>} | 76 * @return {!Array.<!WebInspector.TimelineModel.Record>} |
324 */ | 77 */ |
325 records: function() | 78 records: function() |
326 { | 79 { |
327 return this._records; | 80 return this._records; |
328 }, | 81 }, |
329 | 82 |
330 /** | 83 /** |
331 * @param {!WebInspector.Event} event | 84 * @param {!WebInspector.Event} event |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 loadFromURL: function(url, progress) | 205 loadFromURL: function(url, progress) |
453 { | 206 { |
454 var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this,
progress); | 207 var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(this,
progress); |
455 var urlReader = new WebInspector.ChunkedXHRReader(url, delegate); | 208 var urlReader = new WebInspector.ChunkedXHRReader(url, delegate); |
456 var loader = new WebInspector.TimelineModelLoader(this, urlReader, progr
ess); | 209 var loader = new WebInspector.TimelineModelLoader(this, urlReader, progr
ess); |
457 urlReader.start(loader); | 210 urlReader.start(loader); |
458 }, | 211 }, |
459 | 212 |
460 _createFileReader: function(file, delegate) | 213 _createFileReader: function(file, delegate) |
461 { | 214 { |
462 return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineMod
el.TransferChunkLengthBytes, delegate); | 215 return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineMod
elImpl.TransferChunkLengthBytes, delegate); |
463 }, | 216 }, |
464 | 217 |
465 _createFileWriter: function() | 218 _createFileWriter: function() |
466 { | 219 { |
467 return new WebInspector.FileOutputStream(); | 220 return new WebInspector.FileOutputStream(); |
468 }, | 221 }, |
469 | 222 |
470 saveToFile: function() | 223 saveToFile: function() |
471 { | 224 { |
472 var now = new Date(); | 225 var now = new Date(); |
473 var fileName = "TimelineRawData-" + now.toISO8601Compact() + ".json"; | 226 var fileName = "TimelineRawData-" + now.toISO8601Compact() + ".json"; |
474 var stream = this._createFileWriter(); | 227 var stream = this._createFileWriter(); |
475 | 228 |
476 /** | 229 /** |
477 * @param {boolean} accepted | 230 * @param {boolean} accepted |
478 * @this {WebInspector.TimelineModel} | 231 * @this {WebInspector.TimelineModelImpl} |
479 */ | 232 */ |
480 function callback(accepted) | 233 function callback(accepted) |
481 { | 234 { |
482 if (!accepted) | 235 if (!accepted) |
483 return; | 236 return; |
484 var saver = new WebInspector.TimelineSaver(stream); | 237 var saver = new WebInspector.TimelineSaver(stream); |
485 saver.save(this._payloads, window.navigator.appVersion); | 238 saver.save(this._payloads, window.navigator.appVersion); |
486 } | 239 } |
487 stream.open(fileName, callback.bind(this)); | 240 stream.open(fileName, callback.bind(this)); |
488 }, | 241 }, |
489 | 242 |
490 reset: function() | 243 reset: function() |
491 { | 244 { |
492 this._loadedFromFile = false; | 245 this._loadedFromFile = false; |
493 this._records = []; | |
494 this._payloads = []; | 246 this._payloads = []; |
495 this._stringPool = {}; | 247 this._stringPool = {}; |
496 this._minimumRecordTime = -1; | |
497 this._maximumRecordTime = -1; | |
498 this._bindings._reset(); | 248 this._bindings._reset(); |
499 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ | 249 WebInspector.TimelineModel.prototype.reset.call(this); |
500 this._mainThreadTasks = []; | |
501 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ | |
502 this._gpuThreadTasks = []; | |
503 /** @type {!Array.<!WebInspector.TimelineModel.Record>} */ | |
504 this._eventDividerRecords = []; | |
505 this.dispatchEventToListeners(WebInspector.TimelineModel.Events.RecordsC
leared); | |
506 }, | 250 }, |
507 | 251 |
508 /** | 252 /** |
509 * @return {number} | |
510 */ | |
511 minimumRecordTime: function() | |
512 { | |
513 return this._minimumRecordTime; | |
514 }, | |
515 | |
516 /** | |
517 * @return {number} | |
518 */ | |
519 maximumRecordTime: function() | |
520 { | |
521 return this._maximumRecordTime; | |
522 }, | |
523 | |
524 /** | |
525 * @param {!WebInspector.TimelineModel.Record} record | |
526 */ | |
527 _updateBoundaries: function(record) | |
528 { | |
529 var startTime = record.startTime(); | |
530 var endTime = record.endTime(); | |
531 | |
532 if (this._minimumRecordTime === -1 || startTime < this._minimumRecordTim
e) | |
533 this._minimumRecordTime = startTime; | |
534 if ((this._maximumRecordTime === -1 && endTime) || endTime > this._maxim
umRecordTime) | |
535 this._maximumRecordTime = endTime; | |
536 }, | |
537 | |
538 /** | |
539 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
540 */ | |
541 mainThreadTasks: function() | |
542 { | |
543 return this._mainThreadTasks; | |
544 }, | |
545 | |
546 /** | |
547 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
548 */ | |
549 gpuThreadTasks: function() | |
550 { | |
551 return this._gpuThreadTasks; | |
552 }, | |
553 | |
554 /** | |
555 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
556 */ | |
557 eventDividerRecords: function() | |
558 { | |
559 return this._eventDividerRecords; | |
560 }, | |
561 | |
562 /** | |
563 * @param {!TimelineAgent.TimelineEvent} record | 253 * @param {!TimelineAgent.TimelineEvent} record |
564 */ | 254 */ |
565 _internStrings: function(record) | 255 _internStrings: function(record) |
566 { | 256 { |
567 for (var name in record) { | 257 for (var name in record) { |
568 var value = record[name]; | 258 var value = record[name]; |
569 if (typeof value !== "string") | 259 if (typeof value !== "string") |
570 continue; | 260 continue; |
571 | 261 |
572 var interned = this._stringPool[value]; | 262 var interned = this._stringPool[value]; |
573 if (typeof interned === "string") | 263 if (typeof interned === "string") |
574 record[name] = interned; | 264 record[name] = interned; |
575 else | 265 else |
576 this._stringPool[value] = value; | 266 this._stringPool[value] = value; |
577 } | 267 } |
578 | 268 |
579 var children = record.children; | 269 var children = record.children; |
580 for (var i = 0; children && i < children.length; ++i) | 270 for (var i = 0; children && i < children.length; ++i) |
581 this._internStrings(children[i]); | 271 this._internStrings(children[i]); |
582 }, | 272 }, |
583 | 273 |
584 __proto__: WebInspector.Object.prototype | 274 __proto__: WebInspector.TimelineModel.prototype |
585 } | 275 } |
586 | 276 |
587 | 277 |
588 /** | 278 /** |
589 * @constructor | 279 * @constructor |
590 */ | 280 */ |
591 WebInspector.TimelineModel.InterRecordBindings = function() { | 281 WebInspector.TimelineModelImpl.InterRecordBindings = function() { |
592 this._reset(); | 282 this._reset(); |
593 } | 283 } |
594 | 284 |
595 WebInspector.TimelineModel.InterRecordBindings.prototype = { | 285 WebInspector.TimelineModelImpl.InterRecordBindings.prototype = { |
596 _reset: function() | 286 _reset: function() |
597 { | 287 { |
598 this._sendRequestRecords = {}; | 288 this._sendRequestRecords = {}; |
599 this._timerRecords = {}; | 289 this._timerRecords = {}; |
600 this._requestAnimationFrameRecords = {}; | 290 this._requestAnimationFrameRecords = {}; |
601 this._layoutInvalidate = {}; | 291 this._layoutInvalidate = {}; |
602 this._lastScheduleStyleRecalculation = {}; | 292 this._lastScheduleStyleRecalculation = {}; |
603 this._webSocketCreateRecords = {}; | 293 this._webSocketCreateRecords = {}; |
604 } | 294 } |
605 } | 295 } |
606 | 296 |
607 /** | 297 /** |
608 * @interface | |
609 */ | |
610 WebInspector.TimelineModel.Record = function() | |
611 { | |
612 } | |
613 | |
614 WebInspector.TimelineModel.Record.prototype = { | |
615 /** | |
616 * @return {?Array.<!ConsoleAgent.CallFrame>} | |
617 */ | |
618 callSiteStackTrace: function() { }, | |
619 | |
620 /** | |
621 * @return {?WebInspector.TimelineModel.Record} | |
622 */ | |
623 initiator: function() { }, | |
624 | |
625 /** | |
626 * @return {!WebInspector.Target} | |
627 */ | |
628 target: function() { }, | |
629 | |
630 /** | |
631 * @return {number} | |
632 */ | |
633 selfTime: function() { }, | |
634 | |
635 /** | |
636 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
637 */ | |
638 children: function() { }, | |
639 | |
640 /** | |
641 * @return {!WebInspector.TimelineCategory} | |
642 */ | |
643 category: function() { }, | |
644 | |
645 /** | |
646 * @return {string} | |
647 */ | |
648 title: function() { }, | |
649 | |
650 /** | |
651 * @return {number} | |
652 */ | |
653 startTime: function() { }, | |
654 | |
655 /** | |
656 * @return {string|undefined} | |
657 */ | |
658 thread: function() { }, | |
659 | |
660 /** | |
661 * @return {number} | |
662 */ | |
663 endTime: function() { }, | |
664 | |
665 /** | |
666 * @param {number} endTime | |
667 */ | |
668 setEndTime: function(endTime) { }, | |
669 | |
670 /** | |
671 * @return {!Object} | |
672 */ | |
673 data: function() { }, | |
674 | |
675 /** | |
676 * @return {string} | |
677 */ | |
678 type: function() { }, | |
679 | |
680 /** | |
681 * @return {string} | |
682 */ | |
683 frameId: function() { }, | |
684 | |
685 /** | |
686 * @return {?Array.<!ConsoleAgent.CallFrame>} | |
687 */ | |
688 stackTrace: function() { }, | |
689 | |
690 /** | |
691 * @param {string} key | |
692 * @return {?Object} | |
693 */ | |
694 getUserObject: function(key) { }, | |
695 | |
696 /** | |
697 * @param {string} key | |
698 * @param {?Object|undefined} value | |
699 */ | |
700 setUserObject: function(key, value) { }, | |
701 | |
702 /** | |
703 * @return {!Object.<string, number>} | |
704 */ | |
705 aggregatedStats: function() { }, | |
706 | |
707 /** | |
708 * @return {?Array.<string>} | |
709 */ | |
710 warnings: function() { }, | |
711 | |
712 /** | |
713 * @param {!RegExp} regExp | |
714 * @return {boolean} | |
715 */ | |
716 testContentMatching: function(regExp) { } | |
717 } | |
718 | |
719 | |
720 /** | |
721 * @constructor | |
722 * @implements {WebInspector.TimelineModel.Record} | |
723 * @param {!WebInspector.TimelineModel} model | |
724 * @param {!WebInspector.TracingModel.Event} traceEvent | |
725 * @param {?WebInspector.TimelineModel.TraceEventRecord} parentRecord | |
726 */ | |
727 WebInspector.TimelineModel.TraceEventRecord = function(model, traceEvent, parent
Record) | |
728 { | |
729 this._model = model; | |
730 this._event = traceEvent; | |
731 traceEvent._timelineRecord = this; | |
732 if (parentRecord) { | |
733 this.parent = parentRecord; | |
734 parentRecord._children.push(this); | |
735 } | |
736 this._children = []; | |
737 } | |
738 | |
739 WebInspector.TimelineModel.TraceEventRecord.prototype = { | |
740 /** | |
741 * @return {?Array.<!ConsoleAgent.CallFrame>} | |
742 */ | |
743 callSiteStackTrace: function() | |
744 { | |
745 var initiator = this._event.initiator; | |
746 return initiator ? initiator.stackTrace : null; | |
747 }, | |
748 | |
749 /** | |
750 * @return {?WebInspector.TimelineModel.Record} | |
751 */ | |
752 initiator: function() | |
753 { | |
754 var initiator = this._event.initiator; | |
755 return initiator ? initiator._timelineRecord : null; | |
756 }, | |
757 | |
758 /** | |
759 * @return {!WebInspector.Target} | |
760 */ | |
761 target: function() | |
762 { | |
763 return this._model.target(); | |
764 }, | |
765 | |
766 /** | |
767 * @return {number} | |
768 */ | |
769 selfTime: function() | |
770 { | |
771 return this._event.selfTime / 1000; | |
772 }, | |
773 | |
774 /** | |
775 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
776 */ | |
777 children: function() | |
778 { | |
779 return this._children; | |
780 }, | |
781 | |
782 /** | |
783 * @return {!WebInspector.TimelineCategory} | |
784 */ | |
785 category: function() | |
786 { | |
787 var style = WebInspector.TimelineUIUtils.styleForTimelineEvent(this._eve
nt.name); | |
788 return style.category; | |
789 }, | |
790 | |
791 /** | |
792 * @return {string} | |
793 */ | |
794 title: function() | |
795 { | |
796 return WebInspector.TimelineUIUtils.recordTitle(this, this._model); | |
797 }, | |
798 | |
799 /** | |
800 * @return {number} | |
801 */ | |
802 startTime: function() | |
803 { | |
804 return this._event.startTime / 1000; | |
805 }, | |
806 | |
807 /** | |
808 * @return {string|undefined} | |
809 */ | |
810 thread: function() | |
811 { | |
812 return "CPU"; | |
813 }, | |
814 | |
815 /** | |
816 * @return {number} | |
817 */ | |
818 endTime: function() | |
819 { | |
820 return (this._event.endTime || this._event.startTime) / 1000; | |
821 }, | |
822 | |
823 /** | |
824 * @param {number} endTime | |
825 */ | |
826 setEndTime: function(endTime) | |
827 { | |
828 throw new Error("Unsupported operation setEndTime"); | |
829 }, | |
830 | |
831 /** | |
832 * @return {!Object} | |
833 */ | |
834 data: function() | |
835 { | |
836 return this._event.args.data; | |
837 }, | |
838 | |
839 /** | |
840 * @return {string} | |
841 */ | |
842 type: function() | |
843 { | |
844 return this._event.name; | |
845 }, | |
846 | |
847 /** | |
848 * @return {string} | |
849 */ | |
850 frameId: function() | |
851 { | |
852 switch (this._event.name) { | |
853 case WebInspector.TracingTimelineModel.RecordType.ScheduleStyleRecalcula
tion: | |
854 case WebInspector.TracingTimelineModel.RecordType.RecalculateStyles: | |
855 case WebInspector.TracingTimelineModel.RecordType.InvalidateLayout: | |
856 return this._event.args["frameId"]; | |
857 case WebInspector.TracingTimelineModel.RecordType.Layout: | |
858 return this._event.args["beginData"]["frameId"]; | |
859 default: | |
860 var data = this._event.args.data; | |
861 return (data && data["frame"]) || ""; | |
862 } | |
863 }, | |
864 | |
865 /** | |
866 * @return {?Array.<!ConsoleAgent.CallFrame>} | |
867 */ | |
868 stackTrace: function() | |
869 { | |
870 return this._event.stackTrace; | |
871 }, | |
872 | |
873 /** | |
874 * @param {string} key | |
875 * @return {?Object} | |
876 */ | |
877 getUserObject: function(key) | |
878 { | |
879 if (key === "TimelineUIUtils::preview-element") | |
880 return this._event.previewElement; | |
881 throw new Error("Unexpected key: " + key); | |
882 }, | |
883 | |
884 /** | |
885 * @param {string} key | |
886 * @param {?Object|undefined} value | |
887 */ | |
888 setUserObject: function(key, value) | |
889 { | |
890 if (key !== "TimelineUIUtils::preview-element") | |
891 throw new Error("Unexpected key: " + key); | |
892 this._event.previewElement = /** @type {?Element} */ (value); | |
893 }, | |
894 | |
895 /** | |
896 * @return {!Object.<string, number>} | |
897 */ | |
898 aggregatedStats: function() | |
899 { | |
900 return {}; | |
901 }, | |
902 | |
903 /** | |
904 * @return {?Array.<string>} | |
905 */ | |
906 warnings: function() | |
907 { | |
908 if (this._event.warning) | |
909 return [this._event.warning]; | |
910 return null; | |
911 }, | |
912 | |
913 /** | |
914 * @param {!RegExp} regExp | |
915 * @return {boolean} | |
916 */ | |
917 testContentMatching: function(regExp) | |
918 { | |
919 var tokens = [this.title()]; | |
920 var data = this._event.args.data; | |
921 if (data) { | |
922 for (var key in data) | |
923 tokens.push(data[key]); | |
924 } | |
925 return regExp.test(tokens.join("|")); | |
926 } | |
927 } | |
928 | |
929 /** | |
930 * @constructor | 298 * @constructor |
931 * @implements {WebInspector.TimelineModel.Record} | 299 * @implements {WebInspector.TimelineModel.Record} |
932 * @param {!WebInspector.TimelineModel} model | 300 * @param {!WebInspector.TimelineModel} model |
933 * @param {!TimelineAgent.TimelineEvent} timelineEvent | 301 * @param {!TimelineAgent.TimelineEvent} timelineEvent |
934 * @param {?WebInspector.TimelineModel.Record} parentRecord | 302 * @param {?WebInspector.TimelineModel.Record} parentRecord |
935 */ | 303 */ |
936 WebInspector.TimelineModel.RecordImpl = function(model, timelineEvent, parentRec
ord) | 304 WebInspector.TimelineModel.RecordImpl = function(model, timelineEvent, parentRec
ord) |
937 { | 305 { |
938 this._model = model; | 306 this._model = model; |
939 var bindings = this._model._bindings; | 307 var bindings = this._model._bindings; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 { | 571 { |
1204 var tokens = [this.title()]; | 572 var tokens = [this.title()]; |
1205 for (var key in this._record.data) | 573 for (var key in this._record.data) |
1206 tokens.push(this._record.data[key]) | 574 tokens.push(this._record.data[key]) |
1207 return regExp.test(tokens.join("|")); | 575 return regExp.test(tokens.join("|")); |
1208 } | 576 } |
1209 } | 577 } |
1210 | 578 |
1211 /** | 579 /** |
1212 * @constructor | 580 * @constructor |
1213 */ | |
1214 WebInspector.TimelineModel.Filter = function() | |
1215 { | |
1216 /** @type {!WebInspector.TimelineModel} */ | |
1217 this._model; | |
1218 } | |
1219 | |
1220 WebInspector.TimelineModel.Filter.prototype = { | |
1221 /** | |
1222 * @param {!WebInspector.TimelineModel.Record} record | |
1223 * @return {boolean} | |
1224 */ | |
1225 accept: function(record) | |
1226 { | |
1227 return true; | |
1228 }, | |
1229 | |
1230 notifyFilterChanged: function() | |
1231 { | |
1232 this._model._filterChanged(); | |
1233 } | |
1234 } | |
1235 | |
1236 /** | |
1237 * @constructor | |
1238 * @implements {WebInspector.OutputStream} | 581 * @implements {WebInspector.OutputStream} |
1239 * @param {!WebInspector.TimelineModel} model | 582 * @param {!WebInspector.TimelineModel} model |
1240 * @param {!{cancel: function()}} reader | 583 * @param {!{cancel: function()}} reader |
1241 * @param {!WebInspector.Progress} progress | 584 * @param {!WebInspector.Progress} progress |
1242 */ | 585 */ |
1243 WebInspector.TimelineModelLoader = function(model, reader, progress) | 586 WebInspector.TimelineModelLoader = function(model, reader, progress) |
1244 { | 587 { |
1245 this._model = model; | 588 this._model = model; |
1246 this._reader = reader; | 589 this._reader = reader; |
1247 this._progress = progress; | 590 this._progress = progress; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1402 } else { | 745 } else { |
1403 if (this._recordIndex === this._payloads.length) { | 746 if (this._recordIndex === this._payloads.length) { |
1404 stream.close(); | 747 stream.close(); |
1405 return; | 748 return; |
1406 } | 749 } |
1407 data.push(""); | 750 data.push(""); |
1408 } | 751 } |
1409 while (this._recordIndex < this._payloads.length) { | 752 while (this._recordIndex < this._payloads.length) { |
1410 var item = JSON.stringify(this._payloads[this._recordIndex]); | 753 var item = JSON.stringify(this._payloads[this._recordIndex]); |
1411 var itemLength = item.length + separator.length; | 754 var itemLength = item.length + separator.length; |
1412 if (length + itemLength > WebInspector.TimelineModel.TransferChunkLe
ngthBytes) | 755 if (length + itemLength > WebInspector.TimelineModelImpl.TransferChu
nkLengthBytes) |
1413 break; | 756 break; |
1414 length += itemLength; | 757 length += itemLength; |
1415 data.push(item); | 758 data.push(item); |
1416 ++this._recordIndex; | 759 ++this._recordIndex; |
1417 } | 760 } |
1418 if (this._recordIndex === this._payloads.length) | 761 if (this._recordIndex === this._payloads.length) |
1419 data.push(data.pop() + "]"); | 762 data.push(data.pop() + "]"); |
1420 stream.write(data.join(separator), this._writeNextChunk.bind(this)); | 763 stream.write(data.join(separator), this._writeNextChunk.bind(this)); |
1421 } | 764 } |
1422 } | 765 } |
1423 | |
1424 /** | |
1425 * @constructor | |
1426 */ | |
1427 WebInspector.TimelineMergingRecordBuffer = function() | |
1428 { | |
1429 this._backgroundRecordsBuffer = []; | |
1430 } | |
1431 | |
1432 /** | |
1433 * @constructor | |
1434 */ | |
1435 WebInspector.TimelineMergingRecordBuffer.prototype = { | |
1436 /** | |
1437 * @param {string} thread | |
1438 * @param {!Array.<!WebInspector.TimelineModel.Record>} records | |
1439 * @return {!Array.<!WebInspector.TimelineModel.Record>} | |
1440 */ | |
1441 process: function(thread, records) | |
1442 { | |
1443 if (thread) { | |
1444 this._backgroundRecordsBuffer = this._backgroundRecordsBuffer.concat
(records); | |
1445 return []; | |
1446 } | |
1447 /** | |
1448 * @param {!WebInspector.TimelineModel.Record} a | |
1449 * @param {!WebInspector.TimelineModel.Record} b | |
1450 */ | |
1451 function recordTimestampComparator(a, b) | |
1452 { | |
1453 // Never return 0, as the merge function will squash identical entri
es. | |
1454 return a.startTime() < b.startTime() ? -1 : 1; | |
1455 } | |
1456 var result = this._backgroundRecordsBuffer.mergeOrdered(records, recordT
imestampComparator); | |
1457 this._backgroundRecordsBuffer = []; | |
1458 return result; | |
1459 } | |
1460 } | |
OLD | NEW |