Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 | 5 |
| 6 /** | 6 /** |
| 7 * @fileoverview TimelineModel is a parsed representation of the | 7 * @fileoverview TimelineModel is a parsed representation of the |
| 8 * TraceEvents obtained from base/trace_event in which the begin-end | 8 * TraceEvents obtained from base/trace_event in which the begin-end |
| 9 * tokens are converted into a hierarchy of processes, threads, | 9 * tokens are converted into a hierarchy of processes, threads, |
| 10 * subrows, and slices. | 10 * subrows, and slices. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 * @constructor | 58 * @constructor |
| 59 */ | 59 */ |
| 60 function TimelineThread(parent, tid) { | 60 function TimelineThread(parent, tid) { |
| 61 this.parent = parent; | 61 this.parent = parent; |
| 62 this.tid = tid; | 62 this.tid = tid; |
| 63 this.subRows = [[]]; | 63 this.subRows = [[]]; |
| 64 this.nonNestedSubRows = []; | 64 this.nonNestedSubRows = []; |
| 65 } | 65 } |
| 66 | 66 |
| 67 TimelineThread.prototype = { | 67 TimelineThread.prototype = { |
| 68 name: undefined, | |
|
James Hawkins
2011/07/28 21:52:15
Document var. If it's intended to be private, appe
nduca
2011/08/01 01:22:45
Done.
| |
| 69 | |
| 68 getSubrow: function(i) { | 70 getSubrow: function(i) { |
| 69 while (i >= this.subRows.length) | 71 while (i >= this.subRows.length) |
| 70 this.subRows.push([]); | 72 this.subRows.push([]); |
| 71 return this.subRows[i]; | 73 return this.subRows[i]; |
| 72 }, | 74 }, |
| 73 | 75 |
| 74 addNonNestedSlice: function(slice) { | 76 addNonNestedSlice: function(slice) { |
| 75 for (var i = 0; i < this.nonNestedSubRows.length; i++) { | 77 for (var i = 0; i < this.nonNestedSubRows.length; i++) { |
| 76 var currSubRow = this.nonNestedSubRows[i]; | 78 var currSubRow = this.nonNestedSubRows[i]; |
| 77 var lastSlice = currSubRow[currSubRow.length - 1]; | 79 var lastSlice = currSubRow[currSubRow.length - 1]; |
| 78 if (slice.start >= lastSlice.start + lastSlice.duration) { | 80 if (slice.start >= lastSlice.start + lastSlice.duration) { |
| 79 currSubRow.push(slice); | 81 currSubRow.push(slice); |
| 80 return; | 82 return; |
| 81 } | 83 } |
| 82 } | 84 } |
| 83 this.nonNestedSubRows.push([slice]); | 85 this.nonNestedSubRows.push([slice]); |
| 84 }, | 86 }, |
| 85 | 87 |
| 86 updateBounds: function() { | 88 updateBounds: function() { |
| 87 var slices = this.subRows[0]; | 89 var values = []; |
| 88 if (slices.length != 0) { | 90 var slices; |
| 89 this.minTimestamp = slices[0].start; | 91 if (this.subRows[0].length != 0) { |
| 90 this.maxTimestamp = slices[slices.length - 1].end; | 92 slices = this.subRows[0]; |
| 93 values.push(slices[0].start); | |
| 94 values.push(slices[slices.length - 1].end); | |
| 95 } | |
| 96 for (var i = 0; i < this.nonNestedSubRows.length; ++i) { | |
| 97 slices = this.nonNestedSubRows[i]; | |
| 98 values.push(slices[0].start); | |
| 99 values.push(slices[slices.length - 1].end); | |
| 100 } | |
| 101 if (values.length) { | |
| 102 this.minTimestamp = Math.min.apply(Math, values); | |
| 103 this.maxTimestamp = Math.max.apply(Math, values); | |
| 91 } else { | 104 } else { |
| 92 this.minTimestamp = undefined; | 105 this.minTimestamp = undefined; |
| 93 this.maxTimestamp = undefined; | 106 this.maxTimestamp = undefined; |
| 94 } | 107 } |
| 95 } | 108 } |
| 96 | 109 |
| 97 }; | 110 }; |
| 111 /** | |
| 112 * Comparison between threads that orders first by pid, | |
| 113 * then by names, then by tid. | |
| 114 */ | |
| 115 TimelineThread.compare = function(x,y) { | |
| 116 if(x.parent.pid == y.parent.pid) { | |
| 117 if (x.name && y.name) { | |
| 118 var tmp = x.name.localeCompare(y.name); | |
| 119 if (tmp == 0) | |
| 120 return x.tid - y.tid; | |
| 121 return tmp; | |
| 122 } else if(x.name) { | |
| 123 return -1; | |
| 124 } else if(y.name){ | |
| 125 return 1; | |
| 126 } else { | |
| 127 return x.tid - y.tid; | |
| 128 } | |
| 129 } else { | |
| 130 return x.parent.pid - y.parent.pid; | |
| 131 } | |
| 132 }; | |
| 133 | |
| 98 | 134 |
| 99 /** | 135 /** |
| 100 * The TimelineProcess represents a single process in the | 136 * The TimelineProcess represents a single process in the |
| 101 * trace. Right now, we keep this around purely for bookkeeping | 137 * trace. Right now, we keep this around purely for bookkeeping |
| 102 * reasons. | 138 * reasons. |
| 103 * @constructor | 139 * @constructor |
| 104 */ | 140 */ |
| 105 function TimelineProcess(pid) { | 141 function TimelineProcess(pid) { |
| 106 this.pid = pid; | 142 this.pid = pid; |
| 107 this.threads = {}; | 143 this.threads = {}; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 | 258 |
| 223 // Add the slice to the subSlices array of its parent. | 259 // Add the slice to the subSlices array of its parent. |
| 224 if (state.openSlices.length) { | 260 if (state.openSlices.length) { |
| 225 var parentSlice = state.openSlices[state.openSlices.length - 1]; | 261 var parentSlice = state.openSlices[state.openSlices.length - 1]; |
| 226 parentSlice.slice.subSlices.push(slice); | 262 parentSlice.slice.subSlices.push(slice); |
| 227 } | 263 } |
| 228 } | 264 } |
| 229 } else if (event.ph == 'I') { | 265 } else if (event.ph == 'I') { |
| 230 // TODO(nduca): Implement parsing of immediate events. | 266 // TODO(nduca): Implement parsing of immediate events. |
| 231 console.log('Parsing of I-type events not implemented.'); | 267 console.log('Parsing of I-type events not implemented.'); |
| 268 } else if (event.ph == 'M') { | |
| 269 if (event.name == 'thread_name') { | |
| 270 var thread = this.getProcess(event.pid).getThread(event.tid); | |
| 271 thread.name = event.args.name; | |
| 272 } else { | |
| 273 console.log('Unrecognized metadata name: ' + event.name); | |
|
James Hawkins
2011/07/28 21:52:15
Remove console spam here and elsewhere.
nduca
2011/08/01 01:22:45
Done.
| |
| 274 } | |
| 232 } else { | 275 } else { |
| 233 throw new Error('Unrecognized event phase: ' + event.ph + | 276 console.log('Unrecognized event phase: ' + event.ph + |
| 234 '(' + event.name + ')'); | 277 '(' + event.name + ')'); |
| 235 } | 278 } |
| 236 } | 279 } |
| 237 | 280 this.pruneEmptyThreads(); |
| 238 this.updateBounds(); | 281 this.updateBounds(); |
| 239 | 282 |
| 240 // Add end events for any events that are still on the stack. These | 283 // Add end events for any events that are still on the stack. These |
| 241 // are events that were still open when trace was ended, and can often | 284 // are events that were still open when trace was ended, and can often |
| 242 // indicate deadlock behavior. | 285 // indicate deadlock behavior. |
| 243 for (var ptid in threadStateByPTID) { | 286 for (var ptid in threadStateByPTID) { |
| 244 var state = threadStateByPTID[ptid]; | 287 var state = threadStateByPTID[ptid]; |
| 245 while (state.openSlices.length > 0) { | 288 while (state.openSlices.length > 0) { |
| 246 var slice = state.openSlices.pop(); | 289 var slice = state.openSlices.pop(); |
| 247 slice.slice.duration = this.maxTimestamp - slice.slice.start; | 290 slice.slice.duration = this.maxTimestamp - slice.slice.start; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 261 } | 304 } |
| 262 } | 305 } |
| 263 | 306 |
| 264 this.shiftWorldToMicroseconds(); | 307 this.shiftWorldToMicroseconds(); |
| 265 | 308 |
| 266 var boost = (this.maxTimestamp - this.minTimestamp) * 0.15; | 309 var boost = (this.maxTimestamp - this.minTimestamp) * 0.15; |
| 267 this.minTimestamp = this.minTimestamp - boost; | 310 this.minTimestamp = this.minTimestamp - boost; |
| 268 this.maxTimestamp = this.maxTimestamp + boost; | 311 this.maxTimestamp = this.maxTimestamp + boost; |
| 269 }, | 312 }, |
| 270 | 313 |
| 314 pruneEmptyThreads: function() { | |
|
James Hawkins
2011/07/28 21:52:15
Document method.
nduca
2011/08/01 01:22:45
Done.
| |
| 315 for (var pid in this.processes) { | |
| 316 var process = this.processes[pid]; | |
| 317 var prunedThreads = []; | |
| 318 for (var tid in process.threads) { | |
| 319 var thread = process.threads[tid]; | |
| 320 if (thread.subRows[0].length) | |
| 321 prunedThreads.push(thread); | |
| 322 } | |
| 323 process.threads = prunedThreads; | |
| 324 } | |
| 325 }, | |
| 326 | |
| 271 updateBounds: function() { | 327 updateBounds: function() { |
| 272 var wmin = Infinity; | 328 var wmin = Infinity; |
| 273 var wmax = -wmin; | 329 var wmax = -wmin; |
| 274 var threads = this.getAllThreads(); | 330 var threads = this.getAllThreads(); |
| 275 for (var tI = 0; tI < threads.length; tI++) { | 331 for (var tI = 0; tI < threads.length; tI++) { |
| 276 var thread = threads[tI]; | 332 var thread = threads[tI]; |
| 277 thread.updateBounds(); | 333 thread.updateBounds(); |
| 278 if (thread.minTimestamp && thread.maxTimestamp) { | 334 if (thread.minTimestamp != undefined && |
| 335 thread.maxTimestamp != undefined) { | |
| 279 wmin = Math.min(wmin, thread.minTimestamp); | 336 wmin = Math.min(wmin, thread.minTimestamp); |
| 280 wmax = Math.max(wmax, thread.maxTimestamp); | 337 wmax = Math.max(wmax, thread.maxTimestamp); |
| 281 } | 338 } |
| 282 } | 339 } |
| 283 this.minTimestamp = wmin; | 340 this.minTimestamp = wmin; |
| 284 this.maxTimestamp = wmax; | 341 this.maxTimestamp = wmax; |
| 285 }, | 342 }, |
| 286 | 343 |
| 287 shiftWorldToMicroseconds: function() { | 344 shiftWorldToMicroseconds: function() { |
| 288 var timeBase = this.minTimestamp; | 345 var timeBase = this.minTimestamp; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 | 377 |
| 321 }; | 378 }; |
| 322 | 379 |
| 323 return { | 380 return { |
| 324 TimelineSlice: TimelineSlice, | 381 TimelineSlice: TimelineSlice, |
| 325 TimelineThread: TimelineThread, | 382 TimelineThread: TimelineThread, |
| 326 TimelineProcess: TimelineProcess, | 383 TimelineProcess: TimelineProcess, |
| 327 TimelineModel: TimelineModel | 384 TimelineModel: TimelineModel |
| 328 }; | 385 }; |
| 329 }); | 386 }); |
| OLD | NEW |