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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/timeline/TimelineLoader.js

Issue 2729793003: DevTools: Support reading CPU profile format on Performance panel (Closed)
Patch Set: addressing comments 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 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 /** 4 /**
5 * @implements {Common.OutputStream} 5 * @implements {Common.OutputStream}
6 * @implements {Bindings.OutputStreamDelegate} 6 * @implements {Bindings.OutputStreamDelegate}
7 * @unrestricted 7 * @unrestricted
8 */ 8 */
9 Timeline.TimelineLoader = class { 9 Timeline.TimelineLoader = class {
10 /** 10 /**
11 * @param {!Timeline.TimelineLoader.Client} client 11 * @param {!Timeline.TimelineLoader.Client} client
12 */ 12 */
13 constructor(client) { 13 constructor(client) {
14 this._client = client; 14 this._client = client;
15 15
16 this._backingStorage = new Bindings.TempFileBackingStorage('tracing'); 16 this._backingStorage = new Bindings.TempFileBackingStorage('tracing');
17 this._tracingModel = new SDK.TracingModel(this._backingStorage); 17 this._tracingModel = new SDK.TracingModel(this._backingStorage);
18 18
19 /** @type {?function()} */ 19 /** @type {?function()} */
20 this._canceledCallback = null; 20 this._canceledCallback = null;
21 this._state = Timeline.TimelineLoader.State.Initial; 21 this._state = Timeline.TimelineLoader.State.Initial;
22 this._buffer = ''; 22 this._buffer = '';
23 this._firstRawChunk = true;
23 this._firstChunk = true; 24 this._firstChunk = true;
24 25
25 this._loadedBytes = 0; 26 this._loadedBytes = 0;
26 /** @type {number} */ 27 /** @type {number} */
27 this._totalSize; 28 this._totalSize;
28 this._jsonTokenizer = new Common.TextUtils.BalancedJSONTokenizer(this._write BalancedJSON.bind(this), true); 29 this._jsonTokenizer = new Common.TextUtils.BalancedJSONTokenizer(this._write BalancedJSON.bind(this), true);
29 } 30 }
30 31
31 /** 32 /**
32 * @param {!File} file 33 * @param {!File} file
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 } 73 }
73 74
74 /** 75 /**
75 * @override 76 * @override
76 * @param {string} chunk 77 * @param {string} chunk
77 */ 78 */
78 write(chunk) { 79 write(chunk) {
79 if (!this._client) 80 if (!this._client)
80 return; 81 return;
81 this._loadedBytes += chunk.length; 82 this._loadedBytes += chunk.length;
82 if (!this._firstChunk) 83 if (this._firstRawChunk)
84 this._client.loadingStarted();
85 else
83 this._client.loadingProgress(this._totalSize ? this._loadedBytes / this._t otalSize : undefined); 86 this._client.loadingProgress(this._totalSize ? this._loadedBytes / this._t otalSize : undefined);
87 this._firstRawChunk = false;
84 88
85 if (this._state === Timeline.TimelineLoader.State.Initial) { 89 if (this._state === Timeline.TimelineLoader.State.Initial) {
86 if (chunk[0] === '{') { 90 if (chunk.startsWith('{"nodes":[')) {
91 this._state = Timeline.TimelineLoader.State.LoadingCPUProfileFormat;
92 } else if (chunk[0] === '{') {
87 this._state = Timeline.TimelineLoader.State.LookingForEvents; 93 this._state = Timeline.TimelineLoader.State.LookingForEvents;
88 } else if (chunk[0] === '[') { 94 } else if (chunk[0] === '[') {
89 this._state = Timeline.TimelineLoader.State.ReadingEvents; 95 this._state = Timeline.TimelineLoader.State.ReadingEvents;
90 } else { 96 } else {
91 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline da ta: Unknown JSON format')); 97 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline da ta: Unknown JSON format'));
92 return; 98 return;
93 } 99 }
94 } 100 }
95 101
102 if (this._state === Timeline.TimelineLoader.State.LoadingCPUProfileFormat) {
103 this._buffer += chunk;
104 return;
105 }
106
96 if (this._state === Timeline.TimelineLoader.State.LookingForEvents) { 107 if (this._state === Timeline.TimelineLoader.State.LookingForEvents) {
97 var objectName = '"traceEvents":'; 108 var objectName = '"traceEvents":';
98 var startPos = this._buffer.length - objectName.length; 109 var startPos = this._buffer.length - objectName.length;
99 this._buffer += chunk; 110 this._buffer += chunk;
100 var pos = this._buffer.indexOf(objectName, startPos); 111 var pos = this._buffer.indexOf(objectName, startPos);
101 if (pos === -1) 112 if (pos === -1)
102 return; 113 return;
103 chunk = this._buffer.slice(pos + objectName.length); 114 chunk = this._buffer.slice(pos + objectName.length);
104 this._state = Timeline.TimelineLoader.State.ReadingEvents; 115 this._state = Timeline.TimelineLoader.State.ReadingEvents;
105 } 116 }
106 117
107 if (this._state !== Timeline.TimelineLoader.State.ReadingEvents) 118 if (this._state !== Timeline.TimelineLoader.State.ReadingEvents)
108 return; 119 return;
109 if (this._jsonTokenizer.write(chunk)) 120 if (this._jsonTokenizer.write(chunk))
110 return; 121 return;
111 this._state = Timeline.TimelineLoader.State.SkippingTail; 122 this._state = Timeline.TimelineLoader.State.SkippingTail;
112 if (this._firstChunk) { 123 if (this._firstChunk) {
113 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline inpu t, wrong JSON brackets balance')); 124 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline inpu t, wrong JSON brackets balance'));
114 return; 125 return;
115 } 126 }
116 } 127 }
117 128
118 /** 129 /**
119 * @param {string} data 130 * @param {string} data
120 */ 131 */
121 _writeBalancedJSON(data) { 132 _writeBalancedJSON(data) {
122 var json = data + ']'; 133 var json = data + ']';
123 134
124 if (this._firstChunk) { 135 if (!this._firstChunk) {
125 this._client.loadingStarted();
126 } else {
127 var commaIndex = json.indexOf(','); 136 var commaIndex = json.indexOf(',');
128 if (commaIndex !== -1) 137 if (commaIndex !== -1)
129 json = json.slice(commaIndex + 1); 138 json = json.slice(commaIndex + 1);
130 json = '[' + json; 139 json = '[' + json;
131 } 140 }
132 141
133 var items; 142 var items;
134 try { 143 try {
135 items = /** @type {!Array.<!SDK.TracingManager.EventPayload>} */ (JSON.par se(json)); 144 items = /** @type {!Array.<!SDK.TracingManager.EventPayload>} */ (JSON.par se(json));
136 } catch (e) { 145 } catch (e) {
137 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data : %s', e.toString())); 146 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data : %s', e.toString()));
138 return; 147 return;
139 } 148 }
140 149
141 if (this._firstChunk) { 150 if (this._firstChunk) {
142 this._firstChunk = false; 151 this._firstChunk = false;
143 if (this._looksLikeAppVersion(items[0])) { 152 if (this._looksLikeAppVersion(items[0])) {
144 this._reportErrorAndCancelLoading(Common.UIString('Legacy Timeline forma t is not supported.')); 153 this._reportErrorAndCancelLoading(Common.UIString('Legacy Timeline forma t is not supported.'));
145 return; 154 return;
146 } 155 }
147 } 156 }
148 157
149 try { 158 try {
150 this._tracingModel.addEvents(items); 159 this._tracingModel.addEvents(items);
151 } catch (e) { 160 } catch (e) {
152 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data : %s', e.toString())); 161 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data : %s', e.toString()));
153 return;
154 } 162 }
155 } 163 }
156 164
157 /** 165 /**
158 * @param {string=} message 166 * @param {string=} message
159 */ 167 */
160 _reportErrorAndCancelLoading(message) { 168 _reportErrorAndCancelLoading(message) {
161 if (message) 169 if (message)
162 Common.console.error(message); 170 Common.console.error(message);
163 this.cancel(); 171 this.cancel();
(...skipping 11 matching lines...) Expand all
175 * @override 183 * @override
176 */ 184 */
177 close() { 185 close() {
178 if (!this._client) 186 if (!this._client)
179 return; 187 return;
180 this._client.processingStarted(); 188 this._client.processingStarted();
181 setTimeout(() => this._finalizeTrace(), 0); 189 setTimeout(() => this._finalizeTrace(), 0);
182 } 190 }
183 191
184 _finalizeTrace() { 192 _finalizeTrace() {
193 if (this._state === Timeline.TimelineLoader.State.LoadingCPUProfileFormat) {
194 this._parseCPUProfileFormat(this._buffer);
195 this._buffer = '';
196 }
185 this._tracingModel.tracingComplete(); 197 this._tracingModel.tracingComplete();
186 this._client.loadingComplete(this._tracingModel, this._backingStorage); 198 this._client.loadingComplete(this._tracingModel, this._backingStorage);
187 } 199 }
188 200
189 /** 201 /**
190 * @override 202 * @override
191 */ 203 */
192 onTransferStarted() { 204 onTransferStarted() {
193 } 205 }
194 206
(...skipping 23 matching lines...) Expand all
218 case 'NotReadableError': 230 case 'NotReadableError':
219 this._reportErrorAndCancelLoading(Common.UIString('File "%s" is not read able', reader.fileName())); 231 this._reportErrorAndCancelLoading(Common.UIString('File "%s" is not read able', reader.fileName()));
220 break; 232 break;
221 case 'AbortError': 233 case 'AbortError':
222 break; 234 break;
223 default: 235 default:
224 this._reportErrorAndCancelLoading( 236 this._reportErrorAndCancelLoading(
225 Common.UIString('An error occurred while reading the file "%s"', rea der.fileName())); 237 Common.UIString('An error occurred while reading the file "%s"', rea der.fileName()));
226 } 238 }
227 } 239 }
240
241 /**
242 * @param {string} text
243 */
244 _parseCPUProfileFormat(text) {
245 var traceEvents;
246 try {
247 var profile = JSON.parse(text);
248 traceEvents = TimelineModel.TimelineJSProfileProcessor.buildTraceProfileFr omCpuProfile(profile);
249 } catch (e) {
250 this._reportErrorAndCancelLoading(Common.UIString('Malformed CPU profile f ormat'));
251 return;
252 }
253 this._tracingModel.addEvents(traceEvents);
254 }
228 }; 255 };
229 256
230 257
231 Timeline.TimelineLoader.TransferChunkLengthBytes = 5000000; 258 Timeline.TimelineLoader.TransferChunkLengthBytes = 5000000;
232 259
233 /** 260 /**
234 * @interface 261 * @interface
235 */ 262 */
236 Timeline.TimelineLoader.Client = function() {}; 263 Timeline.TimelineLoader.Client = function() {};
237 264
(...skipping 14 matching lines...) Expand all
252 loadingComplete(tracingModel, backingStorage) {}, 279 loadingComplete(tracingModel, backingStorage) {},
253 }; 280 };
254 281
255 /** 282 /**
256 * @enum {symbol} 283 * @enum {symbol}
257 */ 284 */
258 Timeline.TimelineLoader.State = { 285 Timeline.TimelineLoader.State = {
259 Initial: Symbol('Initial'), 286 Initial: Symbol('Initial'),
260 LookingForEvents: Symbol('LookingForEvents'), 287 LookingForEvents: Symbol('LookingForEvents'),
261 ReadingEvents: Symbol('ReadingEvents'), 288 ReadingEvents: Symbol('ReadingEvents'),
262 SkippingTail: Symbol('SkippingTail') 289 SkippingTail: Symbol('SkippingTail'),
290 LoadingCPUProfileFormat: Symbol('LoadingCPUProfileFormat')
263 }; 291 };
264 292
265 /** 293 /**
266 * @implements {Bindings.OutputStreamDelegate} 294 * @implements {Bindings.OutputStreamDelegate}
267 * @unrestricted 295 * @unrestricted
268 */ 296 */
269 Timeline.TracingTimelineSaver = class { 297 Timeline.TracingTimelineSaver = class {
270 /** 298 /**
271 * @override 299 * @override
272 */ 300 */
(...skipping 17 matching lines...) Expand all
290 * @override 318 * @override
291 * @param {!Bindings.ChunkedReader} reader 319 * @param {!Bindings.ChunkedReader} reader
292 * @param {!Event} event 320 * @param {!Event} event
293 */ 321 */
294 onError(reader, event) { 322 onError(reader, event) {
295 var error = event.target.error; 323 var error = event.target.error;
296 Common.console.error( 324 Common.console.error(
297 Common.UIString('Failed to save timeline: %s (%s, %s)', error.message, e rror.name, error.code)); 325 Common.UIString('Failed to save timeline: %s (%s, %s)', error.message, e rror.name, error.code));
298 } 326 }
299 }; 327 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698