Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2014 The Chromium Authors. All rights reserved. | 2 * Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * @unrestricted | 8 * @unrestricted |
| 9 */ | 9 */ |
| 10 SDK.TracingModel = class { | 10 SDK.TracingModel = class { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 } | 111 } |
| 112 | 112 |
| 113 /** | 113 /** |
| 114 * @return {!Array.<!SDK.TracingModel.Event>} | 114 * @return {!Array.<!SDK.TracingModel.Event>} |
| 115 */ | 115 */ |
| 116 devToolsMetadataEvents() { | 116 devToolsMetadataEvents() { |
| 117 return this._devToolsMetadataEvents; | 117 return this._devToolsMetadataEvents; |
| 118 } | 118 } |
| 119 | 119 |
| 120 /** | 120 /** |
| 121 * @return {!Array.<!SDK.TracingModel.Event>} | |
| 122 */ | |
| 123 flowHeads() { | |
| 124 return this._flowHeads; | |
| 125 } | |
| 126 | |
| 127 /** | |
| 121 * @param {!Array.<!SDK.TracingManager.EventPayload>} events | 128 * @param {!Array.<!SDK.TracingManager.EventPayload>} events |
| 122 */ | 129 */ |
| 123 setEventsForTest(events) { | 130 setEventsForTest(events) { |
| 124 this.reset(); | 131 this.reset(); |
| 125 this.addEvents(events); | 132 this.addEvents(events); |
| 126 this.tracingComplete(); | 133 this.tracingComplete(); |
| 127 } | 134 } |
| 128 | 135 |
| 129 /** | 136 /** |
| 130 * @param {!Array.<!SDK.TracingManager.EventPayload>} events | 137 * @param {!Array.<!SDK.TracingManager.EventPayload>} events |
| 131 */ | 138 */ |
| 132 addEvents(events) { | 139 addEvents(events) { |
| 133 for (var i = 0; i < events.length; ++i) | 140 for (var i = 0; i < events.length; ++i) |
| 134 this._addEvent(events[i]); | 141 this._addEvent(events[i]); |
| 135 } | 142 } |
| 136 | 143 |
| 137 tracingComplete() { | 144 tracingComplete() { |
| 138 this._processPendingAsyncEvents(); | 145 this._processPendingAsyncEvents(); |
| 146 this._processFlowEvents(); | |
| 139 this._backingStorage.appendString(this._firstWritePending ? '[]' : ']'); | 147 this._backingStorage.appendString(this._firstWritePending ? '[]' : ']'); |
| 140 this._backingStorage.finishWriting(); | 148 this._backingStorage.finishWriting(); |
| 141 this._firstWritePending = false; | 149 this._firstWritePending = false; |
| 142 for (var process of this._processById.values()) { | 150 for (var process of this._processById.values()) { |
| 143 for (var thread of process._threads.values()) | 151 for (var thread of process._threads.values()) |
| 144 thread.tracingComplete(); | 152 thread.tracingComplete(); |
| 145 } | 153 } |
| 146 } | 154 } |
| 147 | 155 |
| 148 reset() { | 156 reset() { |
| 149 /** @type {!Map<(number|string), !SDK.TracingModel.Process>} */ | 157 /** @type {!Map<(number|string), !SDK.TracingModel.Process>} */ |
| 150 this._processById = new Map(); | 158 this._processById = new Map(); |
| 151 this._processByName = new Map(); | 159 this._processByName = new Map(); |
| 152 this._minimumRecordTime = 0; | 160 this._minimumRecordTime = 0; |
| 153 this._maximumRecordTime = 0; | 161 this._maximumRecordTime = 0; |
| 154 this._devToolsMetadataEvents = []; | 162 this._devToolsMetadataEvents = []; |
| 155 if (!this._firstWritePending) | 163 if (!this._firstWritePending) |
| 156 this._backingStorage.reset(); | 164 this._backingStorage.reset(); |
| 157 | 165 |
| 158 this._firstWritePending = true; | 166 this._firstWritePending = true; |
| 159 /** @type {!Array<!SDK.TracingModel.Event>} */ | 167 /** @type {!Array<!SDK.TracingModel.Event>} */ |
| 160 this._asyncEvents = []; | 168 this._asyncEvents = []; |
| 161 /** @type {!Map<string, !SDK.TracingModel.AsyncEvent>} */ | 169 /** @type {!Map<string, !SDK.TracingModel.AsyncEvent>} */ |
| 162 this._openAsyncEvents = new Map(); | 170 this._openAsyncEvents = new Map(); |
| 163 /** @type {!Map<string, !Array<!SDK.TracingModel.AsyncEvent>>} */ | 171 /** @type {!Map<string, !Array<!SDK.TracingModel.AsyncEvent>>} */ |
| 164 this._openNestableAsyncEvents = new Map(); | 172 this._openNestableAsyncEvents = new Map(); |
| 173 /** @type {!Map<string, !Array<!SDK.TracingModel.Event>>} */ | |
| 174 this._flowEventsById = new Map(); | |
| 165 /** @type {!Map<string, !SDK.TracingModel.ProfileEventsGroup>} */ | 175 /** @type {!Map<string, !SDK.TracingModel.ProfileEventsGroup>} */ |
| 166 this._profileGroups = new Map(); | 176 this._profileGroups = new Map(); |
| 167 /** @type {!Map<string, !Set<string>>} */ | 177 /** @type {!Map<string, !Set<string>>} */ |
| 168 this._parsedCategories = new Map(); | 178 this._parsedCategories = new Map(); |
| 179 /** @type {!Array<!SDK.TracingModel.Event>} */ | |
| 180 this._flowHeads = []; | |
| 169 } | 181 } |
| 170 | 182 |
| 171 /** | 183 /** |
| 172 * @param {number} offset | 184 * @param {number} offset |
| 173 */ | 185 */ |
| 174 adjustTime(offset) { | 186 adjustTime(offset) { |
| 175 this._minimumRecordTime += offset; | 187 this._minimumRecordTime += offset; |
| 176 this._maximumRecordTime += offset; | 188 this._maximumRecordTime += offset; |
| 177 for (const process of this._processById.values()) { | 189 for (const process of this._processById.values()) { |
| 178 for (const thread of process._threads.values()) { | 190 for (const thread of process._threads.values()) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 const event = process._addEvent(payload); | 236 const event = process._addEvent(payload); |
| 225 if (!event) | 237 if (!event) |
| 226 return; | 238 return; |
| 227 if (payload.ph === phase.Sample) { | 239 if (payload.ph === phase.Sample) { |
| 228 this._addSampleEvent(event); | 240 this._addSampleEvent(event); |
| 229 return; | 241 return; |
| 230 } | 242 } |
| 231 // Build async event when we've got events from all threads & processes, so we can sort them and process in the | 243 // Build async event when we've got events from all threads & processes, so we can sort them and process in the |
| 232 // chronological order. However, also add individual async events to the thr ead flow (above), so we can easily | 244 // chronological order. However, also add individual async events to the thr ead flow (above), so we can easily |
| 233 // display them on the same chart as other events, should we choose so. | 245 // display them on the same chart as other events, should we choose so. |
| 234 if (SDK.TracingModel.isAsyncPhase(payload.ph)) | 246 if (SDK.TracingModel.isAsyncPhase(payload.ph)) { |
| 235 this._asyncEvents.push(event); | 247 this._asyncEvents.push(event); |
| 248 } else if (SDK.TracingModel.isFlowPhase(payload.ph)) { | |
| 249 var key = `${event.categoriesString}-${event.name}-${event.id}`; | |
|
pfeldman
2017/03/16 07:03:50
I don't think categoriesString and event name shou
| |
| 250 var flowEvents = this._flowEventsById.get(key); | |
| 251 if (!flowEvents) { | |
| 252 flowEvents = []; | |
| 253 this._flowEventsById.set(key, flowEvents); | |
| 254 } | |
| 255 flowEvents.push(event); | |
| 256 } | |
| 257 | |
| 236 event._setBackingStorage(backingStorage); | 258 event._setBackingStorage(backingStorage); |
| 237 if (event.hasCategory(SDK.TracingModel.DevToolsMetadataEventCategory)) | 259 if (event.hasCategory(SDK.TracingModel.DevToolsMetadataEventCategory)) |
| 238 this._devToolsMetadataEvents.push(event); | 260 this._devToolsMetadataEvents.push(event); |
| 239 | 261 |
| 240 if (payload.ph !== phase.Metadata) | 262 if (payload.ph !== phase.Metadata) |
| 241 return; | 263 return; |
| 242 | 264 |
| 243 switch (payload.name) { | 265 switch (payload.name) { |
| 244 case SDK.TracingModel.MetadataEvent.ProcessSortIndex: | 266 case SDK.TracingModel.MetadataEvent.ProcessSortIndex: |
| 245 process._setSortIndex(payload.args['sort_index']); | 267 process._setSortIndex(payload.args['sort_index']); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 var event = this._asyncEvents[i]; | 344 var event = this._asyncEvents[i]; |
| 323 if (SDK.TracingModel.isNestableAsyncPhase(event.phase)) | 345 if (SDK.TracingModel.isNestableAsyncPhase(event.phase)) |
| 324 this._addNestableAsyncEvent(event); | 346 this._addNestableAsyncEvent(event); |
| 325 else | 347 else |
| 326 this._addAsyncEvent(event); | 348 this._addAsyncEvent(event); |
| 327 } | 349 } |
| 328 this._asyncEvents = []; | 350 this._asyncEvents = []; |
| 329 this._closeOpenAsyncEvents(); | 351 this._closeOpenAsyncEvents(); |
| 330 } | 352 } |
| 331 | 353 |
| 354 _processFlowEvents() { | |
| 355 var phases = SDK.TracingModel.Phase; | |
| 356 for (var events of this._flowEventsById.values()) { | |
| 357 events.stableSort(SDK.TracingModel.Event.compareStartTime); | |
| 358 var lastInChain = null; | |
| 359 for (var e of events) { | |
| 360 if (lastInChain && e.phase !== phases.FlowBegin) | |
| 361 lastInChain._appendFlowEvent(e); | |
| 362 if (!lastInChain && e.phase !== phases.FlowEnd) | |
| 363 this._flowHeads.push(e); | |
|
pfeldman
2017/03/16 02:00:22
So if there is no begin, you still consider it a h
| |
| 364 lastInChain = e.phase !== phases.FlowEnd ? e : null; | |
|
pfeldman
2017/03/16 02:00:22
why do you need all this logic? it is either begin
| |
| 365 } | |
| 366 } | |
| 367 this._flowEventsById.clear(); | |
| 368 } | |
| 369 | |
| 332 _closeOpenAsyncEvents() { | 370 _closeOpenAsyncEvents() { |
| 333 for (var event of this._openAsyncEvents.values()) { | 371 for (var event of this._openAsyncEvents.values()) { |
| 334 event.setEndTime(this._maximumRecordTime); | 372 event.setEndTime(this._maximumRecordTime); |
| 335 // FIXME: remove this once we figure a better way to convert async console | 373 // FIXME: remove this once we figure a better way to convert async console |
| 336 // events to sync [waterfall] timeline records. | 374 // events to sync [waterfall] timeline records. |
| 337 event.steps[0].setEndTime(this._maximumRecordTime); | 375 event.steps[0].setEndTime(this._maximumRecordTime); |
| 338 } | 376 } |
| 339 this._openAsyncEvents.clear(); | 377 this._openAsyncEvents.clear(); |
| 340 | 378 |
| 341 for (var eventStack of this._openNestableAsyncEvents.values()) { | 379 for (var eventStack of this._openNestableAsyncEvents.values()) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 /** @type {string} */ | 556 /** @type {string} */ |
| 519 this.name = name; | 557 this.name = name; |
| 520 /** @type {!SDK.TracingModel.Phase} */ | 558 /** @type {!SDK.TracingModel.Phase} */ |
| 521 this.phase = phase; | 559 this.phase = phase; |
| 522 /** @type {number} */ | 560 /** @type {number} */ |
| 523 this.startTime = startTime; | 561 this.startTime = startTime; |
| 524 /** @type {!SDK.TracingModel.Thread} */ | 562 /** @type {!SDK.TracingModel.Thread} */ |
| 525 this.thread = thread; | 563 this.thread = thread; |
| 526 /** @type {!Object} */ | 564 /** @type {!Object} */ |
| 527 this.args = {}; | 565 this.args = {}; |
| 566 /** @type {!SDK.TracingModel.Event|undefined} */ | |
| 567 this.nextFlow; | |
| 568 /** @type {!SDK.TracingModel.Event|undefined} */ | |
| 569 this.previousFlow; | |
| 528 | 570 |
| 529 /** @type {number} */ | 571 /** @type {number} */ |
| 530 this.selfTime = 0; | 572 this.selfTime = 0; |
| 531 } | 573 } |
| 532 | 574 |
| 533 /** | 575 /** |
| 534 * @param {!SDK.TracingManager.EventPayload} payload | 576 * @param {!SDK.TracingManager.EventPayload} payload |
| 535 * @param {!SDK.TracingModel.Thread} thread | 577 * @param {!SDK.TracingModel.Thread} thread |
| 536 * @return {!SDK.TracingModel.Event} | 578 * @return {!SDK.TracingModel.Event} |
| 537 */ | 579 */ |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 621 */ | 663 */ |
| 622 _complete(endEvent) { | 664 _complete(endEvent) { |
| 623 if (endEvent.args) | 665 if (endEvent.args) |
| 624 this.addArgs(endEvent.args); | 666 this.addArgs(endEvent.args); |
| 625 else | 667 else |
| 626 console.error('Missing mandatory event argument \'args\' at ' + endEvent.s tartTime); | 668 console.error('Missing mandatory event argument \'args\' at ' + endEvent.s tartTime); |
| 627 this.setEndTime(endEvent.startTime); | 669 this.setEndTime(endEvent.startTime); |
| 628 } | 670 } |
| 629 | 671 |
| 630 /** | 672 /** |
| 673 * @param {!SDK.TracingModel.Event} nextFlow | |
| 674 */ | |
| 675 _appendFlowEvent(nextFlow) { | |
| 676 this.nextFlow = nextFlow; | |
| 677 nextFlow.previousFlow = this; | |
| 678 } | |
| 679 | |
| 680 /** | |
| 631 * @param {?function():!Promise.<?string>} backingStorage | 681 * @param {?function():!Promise.<?string>} backingStorage |
| 632 */ | 682 */ |
| 633 _setBackingStorage(backingStorage) { | 683 _setBackingStorage(backingStorage) { |
| 634 } | 684 } |
| 635 }; | 685 }; |
| 636 | 686 |
| 637 SDK.TracingModel.ObjectSnapshot = class extends SDK.TracingModel.Event { | 687 SDK.TracingModel.ObjectSnapshot = class extends SDK.TracingModel.Event { |
| 638 /** | 688 /** |
| 639 * @param {string} category | 689 * @param {string} category |
| 640 * @param {string} name | 690 * @param {string} name |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 980 return this._events; | 1030 return this._events; |
| 981 } | 1031 } |
| 982 | 1032 |
| 983 /** | 1033 /** |
| 984 * @return {!Array.<!SDK.TracingModel.AsyncEvent>} | 1034 * @return {!Array.<!SDK.TracingModel.AsyncEvent>} |
| 985 */ | 1035 */ |
| 986 asyncEvents() { | 1036 asyncEvents() { |
| 987 return this._asyncEvents; | 1037 return this._asyncEvents; |
| 988 } | 1038 } |
| 989 }; | 1039 }; |
| OLD | NEW |