Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sdk/TracingModel.js

Issue 2746153005: DevTools: move flow events tracking to TracingModel, support cross-threads case (Closed)
Patch Set: fixed infinite chains of flow events Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698