slice.html revision edfe2194ee8a857cc1e78b4e4020f9b5e7210029
1<!DOCTYPE html> 2<!-- 3Copyright (c) 2013 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7 8<link rel="import" href="/tracing/base/units/time_stamp.html"> 9<link rel="import" href="/tracing/model/timed_event.html"> 10 11<script> 12'use strict'; 13 14/** 15 * @fileoverview Provides the Slice class. 16 */ 17tr.exportTo('tr.model', function() { 18 /** 19 * A Slice represents an interval of time plus parameters associated 20 * with that interval. 21 * 22 * @constructor 23 */ 24 function Slice(category, title, colorId, start, args, opt_duration, 25 opt_cpuStart, opt_cpuDuration, opt_argsStripped, 26 opt_bind_id) { 27 tr.model.TimedEvent.call(this, start); 28 29 this.category = category || ''; 30 this.title = title; 31 this.colorId = colorId; 32 this.args = args; 33 this.startStackFrame = undefined; 34 this.endStackFrame = undefined; 35 this.didNotFinish = false; 36 this.inFlowEvents = []; 37 this.outFlowEvents = []; 38 this.subSlices = []; 39 this.selfTime = undefined; 40 this.cpuSelfTime = undefined; 41 this.important = false; 42 this.parentContainer = undefined; 43 this.argsStripped = false; 44 45 this.bind_id_ = opt_bind_id; 46 47 // parentSlice and isTopLevel will be set by SliceGroup. 48 this.parentSlice = undefined; 49 this.isTopLevel = false; 50 // After SliceGroup processes Slices, isTopLevel should be equivalent to 51 // !parentSlice. 52 53 if (opt_duration !== undefined) 54 this.duration = opt_duration; 55 56 if (opt_cpuStart !== undefined) 57 this.cpuStart = opt_cpuStart; 58 59 if (opt_cpuDuration !== undefined) 60 this.cpuDuration = opt_cpuDuration; 61 62 if (opt_argsStripped !== undefined) 63 this.argsStripped = true; 64 } 65 66 Slice.prototype = { 67 __proto__: tr.model.TimedEvent.prototype, 68 69 70 get analysisTypeName() { 71 return this.title; 72 }, 73 74 get userFriendlyName() { 75 return 'Slice ' + this.title + ' at ' + 76 tr.b.units.TimeStamp.format(this.start); 77 }, 78 79 findDescendentSlice: function(targetTitle) { 80 if (!this.subSlices) 81 return undefined; 82 83 for (var i = 0; i < this.subSlices.length; i++) { 84 if (this.subSlices[i].title == targetTitle) 85 return this.subSlices[i]; 86 var slice = this.subSlices[i].findDescendentSlice(targetTitle); 87 if (slice) return slice; 88 } 89 return undefined; 90 }, 91 92 get mostTopLevelSlice() { 93 var curSlice = this; 94 while (curSlice.parentSlice) 95 curSlice = curSlice.parentSlice; 96 97 return curSlice; 98 }, 99 100 /** 101 * Obtains all subsequent slices of this slice. 102 * 103 * Subsequent slices are slices that get executed after a particular 104 * slice, i.e., all the functions that are called after the current one. 105 * 106 * For instance, E.iterateAllSubsequentSlices() in the following example: 107 * [ A ] 108 * [ B][ D ][ G ] 109 * [C] [E][F] [H] 110 * will pass F, G, then H to the provided callback. 111 * 112 * The reason we need subsequent slices of a particular slice is that 113 * when there is flow event goes into, e.g., E, we only want to highlight 114 * E's subsequent slices to indicate the execution order. 115 * 116 * The idea to calculate the subsequent slices of slice E is to view 117 * the slice group as a tree where the top-level slice A is the root node. 118 * The preorder depth-first-search (DFS) order is naturally equivalent 119 * to the function call order. We just need to perform a DFS, and start 120 * recording the slices after we see the occurance of E. 121 */ 122 iterateAllSubsequentSlices: function(callback, opt_this) { 123 var parentStack = []; 124 var started = false; 125 126 // get the root node and push it to the DFS stack 127 var topmostSlice = this.mostTopLevelSlice; 128 parentStack.push(topmostSlice); 129 130 // Using the stack to perform DFS 131 while (parentStack.length !== 0) { 132 var curSlice = parentStack.pop(); 133 134 if (started) 135 callback.call(opt_this, curSlice); 136 else 137 started = (curSlice.guid === this.guid); 138 139 for (var i = curSlice.subSlices.length - 1; i >= 0; i--) { 140 parentStack.push(curSlice.subSlices[i]); 141 } 142 } 143 }, 144 145 get subsequentSlices() { 146 var res = []; 147 148 this.iterateAllSubsequentSlices(function(subseqSlice) { 149 res.push(subseqSlice); 150 }); 151 152 return res; 153 }, 154 155 /** 156 * Obtains the parents of a slice, from the most immediate to the root. 157 * 158 * For instance, E.iterateAllAncestors() in the following example: 159 * [ A ] 160 * [ B][ D ][ G ] 161 * [C] [E][F] [H] 162 * will pass D, then A to the provided callback, in the order from the 163 * leaves to the root. 164 */ 165 iterateAllAncestors: function(callback, opt_this) { 166 var curSlice = this; 167 168 while (curSlice.parentSlice) { 169 curSlice = curSlice.parentSlice; 170 callback.call(opt_this, curSlice); 171 } 172 }, 173 174 get ancestorSlices() { 175 var res = []; 176 177 this.iterateAllAncestors(function(ancestor) { 178 res.push(ancestor); 179 }); 180 181 return res; 182 }, 183 184 iterateEntireHierarchy: function(callback, opt_this) { 185 var mostTopLevelSlice = this.mostTopLevelSlice; 186 callback.call(opt_this, mostTopLevelSlice); 187 mostTopLevelSlice.iterateAllSubsequentSlices(callback, opt_this); 188 }, 189 190 get entireHierarchy() { 191 var res = []; 192 193 this.iterateEntireHierarchy(function(slice) { 194 res.push(slice); 195 }); 196 197 return res; 198 }, 199 200 /** 201 * Returns this slice, and its ancestor and subsequent slices. 202 * 203 * For instance, E.ancestorAndSubsequentSlices in the following example: 204 * [ A ] 205 * [ B][ D ][ G ] 206 * [C] [E][F] [H] 207 * will return E, D, A, F, G, and H, where E is itself, D and A are 208 * E's ancestors, and F, G, and H are subsequent slices of E 209 */ 210 get ancestorAndSubsequentSlices() { 211 var res = []; 212 213 res.push(this); 214 215 this.iterateAllAncestors(function(aSlice) { 216 res.push(aSlice); 217 }); 218 219 this.iterateAllSubsequentSlices(function(sSlice) { 220 res.push(sSlice); 221 }); 222 223 return res; 224 }, 225 226 iterateAllDescendents: function(callback, opt_this) { 227 this.subSlices.forEach(callback, opt_this); 228 this.subSlices.forEach(function(subSlice) { 229 subSlice.iterateAllDescendents(callback, opt_this); 230 }, opt_this); 231 }, 232 233 get descendentSlices() { 234 var res = []; 235 236 this.iterateAllDescendents(function(des) { 237 res.push(des); 238 }); 239 240 return res; 241 } 242 243 }; 244 245 return { 246 Slice: Slice 247 }; 248}); 249</script> 250 251