Index: chrome/browser/resources/tracing/timeline_model.js |
diff --git a/chrome/browser/resources/tracing/timeline_model.js b/chrome/browser/resources/tracing/timeline_model.js |
index 29d50e55c1efd7db2ed20c85251f7fe14629a165..a75a59d16669928cddb171ef6a18995a124ba882 100644 |
--- a/chrome/browser/resources/tracing/timeline_model.js |
+++ b/chrome/browser/resources/tracing/timeline_model.js |
@@ -506,9 +506,30 @@ cr.define('tracing', function() { |
this.pruneEmptyThreads(); |
this.updateBounds(); |
- // Add end events for any events that are still on the stack. These |
- // are events that were still open when trace was ended, and can often |
- // indicate deadlock behavior. |
+ // Adjust the model's max value temporarily to include the max value of |
+ // any of the open slices, since they wouldn't have been inluded in the |
James Hawkins
2011/12/01 17:12:49
included
nduca
2011/12/01 17:30:33
Done.
|
+ // bounds calculation. We need the true global max value because the |
+ // duration for any open slices is set so that they end at this global |
+ // maximum. |
+ for (var ptid in threadStateByPTID) { |
+ var state = threadStateByPTID[ptid]; |
+ for (var i = 0; i < state.openSlices.length; i++) { |
+ var slice = state.openSlices[i]; |
+ this.minTimestamp = Math.min(this.minTimestamp, slice.slice.start); |
+ this.maxTimestamp = Math.max(this.maxTimestamp, slice.slice.start); |
+ for (var s = 0; s < slice.slice.subSlices.length; ++s) { |
James Hawkins
2011/12/01 17:12:49
s++
nduca
2011/12/01 17:30:33
Done.
|
+ var subSlice = slice.slice.subSlices[s]; |
+ this.minTimestamp = Math.min(this.minTimestamp, subSlice.start); |
+ this.maxTimestamp = Math.max(this.maxTimestamp, subSlice.start); |
+ if (subSlice.duration) |
+ this.maxTimestamp = Math.max(this.maxTimestamp, subSlice.end); |
+ } |
+ } |
+ } |
+ |
+ // Automatically close any slices are still open. These occur in a number |
+ // of reasonable situations, e.g. deadlock. This pass ensures the open |
+ // slices make it into the final model. |
for (var ptid in threadStateByPTID) { |
var state = threadStateByPTID[ptid]; |
while (state.openSlices.length > 0) { |
@@ -539,7 +560,7 @@ cr.define('tracing', function() { |
}, |
/** |
- * Removes threads from the model that have no subrows. |
+ * Removes threads from the model that are fully empty. |
*/ |
pruneEmptyThreads: function() { |
for (var pid in this.processes) { |
@@ -547,7 +568,17 @@ cr.define('tracing', function() { |
var prunedThreads = {}; |
for (var tid in process.threads) { |
var thread = process.threads[tid]; |
- if (thread.subRows[0].length || thread.nonNestedSubRows.legnth) |
+ |
+ // Begin-events without matching end events leave a thread in a state |
+ // where the toplevel subrows are empty but child subrows have |
+ // entries. The autocloser will fix this up later. But, for the |
+ // purposes of pruning, such threads need to be treated as having |
+ // content. |
+ var hasNonEmptySubrow = false; |
+ for (var s = 0; s < thread.subRows.length; s++) |
+ hasNonEmptySubrow |= thread.subRows[s].length > 0; |
+ |
+ if (hasNonEmptySubrow || thread.nonNestedSubRows.legnth) |
prunedThreads[tid] = thread; |
} |
process.threads = prunedThreads; |