| OLD | NEW |
| 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 TimelineModel.TimelineProfileTree = {}; | 5 TimelineModel.TimelineProfileTree = class { |
| 6 /** |
| 7 * @param {!Array<!SDK.TracingModel.Event>} events |
| 8 * @param {!Array<!TimelineModel.TimelineModelFilter>} filters |
| 9 * @param {number} startTime |
| 10 * @param {number} endTime |
| 11 * @param {function(!SDK.TracingModel.Event):string=} eventGroupIdCallback |
| 12 */ |
| 13 constructor(events, filters, startTime, endTime, eventGroupIdCallback) { |
| 14 this._events = events; |
| 15 this._filter = e => TimelineModel.TimelineModel.isVisible(filters, e); |
| 16 this._startTime = startTime; |
| 17 this._endTime = endTime; |
| 18 this._eventGroupIdCallback = eventGroupIdCallback; |
| 19 } |
| 20 |
| 21 /** |
| 22 * @return {!TimelineModel.TimelineProfileTree.Node} |
| 23 */ |
| 24 bottomUpTreeRoot() { |
| 25 return new TimelineModel.TimelineProfileTree.BottomUpTreeRootNode(this); |
| 26 } |
| 27 }; |
| 6 | 28 |
| 7 /** | 29 /** |
| 8 * @unrestricted | 30 * @unrestricted |
| 9 */ | 31 */ |
| 10 TimelineModel.TimelineProfileTree.Node = class { | 32 TimelineModel.TimelineProfileTree.Node = class { |
| 11 constructor() { | 33 /** |
| 34 * @param {string} id |
| 35 * @param {?SDK.TracingModel.Event} event |
| 36 */ |
| 37 constructor(id, event) { |
| 12 /** @type {number} */ | 38 /** @type {number} */ |
| 13 this.totalTime; | 39 this.totalTime = 0; |
| 14 /** @type {number} */ | 40 /** @type {number} */ |
| 15 this.selfTime; | 41 this.selfTime = 0; |
| 16 /** @type {string} */ | 42 /** @type {string} */ |
| 17 this.id; | 43 this.id = id; |
| 18 /** @type {!SDK.TracingModel.Event} */ | 44 /** @type {?SDK.TracingModel.Event} */ |
| 19 this.event; | 45 this.event = event; |
| 20 /** @type {?Map<string|symbol,!TimelineModel.TimelineProfileTree.Node>} */ | |
| 21 this.children; | |
| 22 /** @type {?TimelineModel.TimelineProfileTree.Node} */ | 46 /** @type {?TimelineModel.TimelineProfileTree.Node} */ |
| 23 this.parent; | 47 this.parent; |
| 24 | 48 |
| 25 /** @type {string} */ | 49 /** @type {string} */ |
| 26 this._groupId = ''; | 50 this._groupId = ''; |
| 27 this._isGroupNode = false; | 51 this._isGroupNode = false; |
| 28 } | 52 } |
| 29 | 53 |
| 30 /** | 54 /** |
| 31 * @return {boolean} | 55 * @return {boolean} |
| 32 */ | 56 */ |
| 33 isGroupNode() { | 57 isGroupNode() { |
| 34 return this._isGroupNode; | 58 return this._isGroupNode; |
| 35 } | 59 } |
| 60 |
| 61 /** |
| 62 * @return {boolean} |
| 63 */ |
| 64 hasChildren() { |
| 65 throw 'Not implemented'; |
| 66 } |
| 67 |
| 68 /** |
| 69 * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>} |
| 70 */ |
| 71 children() { |
| 72 throw 'Not implemented'; |
| 73 } |
| 74 }; |
| 75 |
| 76 TimelineModel.TimelineProfileTree.TopDownNode = class extends TimelineModel.Time
lineProfileTree.Node { |
| 77 /** |
| 78 * @param {string} id |
| 79 * @param {?SDK.TracingModel.Event} event |
| 80 */ |
| 81 constructor(id, event) { |
| 82 super(id, event); |
| 83 /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Node>} */ |
| 84 this._children = new Map(); |
| 85 } |
| 86 |
| 87 /** |
| 88 * @override |
| 89 * @return {boolean} |
| 90 */ |
| 91 hasChildren() { |
| 92 return !!this._children.size; |
| 93 } |
| 94 |
| 95 /** |
| 96 * @override |
| 97 * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>} |
| 98 */ |
| 99 children() { |
| 100 return this._children; |
| 101 } |
| 36 }; | 102 }; |
| 37 | 103 |
| 38 /** | 104 /** |
| 39 * @param {!Array<!SDK.TracingModel.Event>} events | 105 * @param {!Array<!SDK.TracingModel.Event>} events |
| 40 * @param {!Array<!TimelineModel.TimelineModelFilter>} filters | 106 * @param {!Array<!TimelineModel.TimelineModelFilter>} filters |
| 41 * @param {number} startTime | 107 * @param {number} startTime |
| 42 * @param {number} endTime | 108 * @param {number} endTime |
| 43 * @param {function(!SDK.TracingModel.Event):string=} eventGroupIdCallback | 109 * @param {function(!SDK.TracingModel.Event):string=} eventGroupIdCallback |
| 44 * @return {!TimelineModel.TimelineProfileTree.Node} | 110 * @return {!TimelineModel.TimelineProfileTree.Node} |
| 45 */ | 111 */ |
| 46 TimelineModel.TimelineProfileTree.buildTopDown = function(events, filters, start
Time, endTime, eventGroupIdCallback) { | 112 TimelineModel.TimelineProfileTree.buildTopDown = function(events, filters, start
Time, endTime, eventGroupIdCallback) { |
| 47 // Temporarily deposit a big enough value that exceeds the max recording time. | 113 // Temporarily deposit a big enough value that exceeds the max recording time. |
| 48 var /** @const */ initialTime = 1e7; | 114 var /** @const */ initialTime = 1e7; |
| 49 var root = new TimelineModel.TimelineProfileTree.Node(); | 115 var root = new TimelineModel.TimelineProfileTree.TopDownNode('', null); |
| 50 root.totalTime = initialTime; | 116 root.totalTime = initialTime; |
| 51 root.selfTime = initialTime; | 117 root.selfTime = initialTime; |
| 52 root.children = /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Nod
e>} */ (new Map()); | |
| 53 var parent = root; | 118 var parent = root; |
| 54 | 119 |
| 55 /** | 120 /** |
| 56 * @param {!SDK.TracingModel.Event} e | 121 * @param {!SDK.TracingModel.Event} e |
| 57 */ | 122 */ |
| 58 function onStartEvent(e) { | 123 function onStartEvent(e) { |
| 59 if (!TimelineModel.TimelineModel.isVisible(filters, e)) | 124 if (!TimelineModel.TimelineModel.isVisible(filters, e)) |
| 60 return; | 125 return; |
| 61 var time = e.endTime ? Math.min(endTime, e.endTime) - Math.max(startTime, e.
startTime) : 0; | 126 var time = e.endTime ? Math.min(endTime, e.endTime) - Math.max(startTime, e.
startTime) : 0; |
| 62 var groupId = eventGroupIdCallback ? eventGroupIdCallback(e) : Symbol('uniqu
eGroupId'); | 127 var groupId = eventGroupIdCallback ? eventGroupIdCallback(e) : Symbol('uniqu
eGroupId'); |
| 63 var id = eventGroupIdCallback ? TimelineModel.TimelineProfileTree._eventId(e
) : Symbol('uniqueEventId'); | 128 var id = eventGroupIdCallback ? TimelineModel.TimelineProfileTree._eventId(e
) : Symbol('uniqueEventId'); |
| 64 if (typeof groupId === 'string' && typeof id === 'string') | 129 if (typeof groupId === 'string' && typeof id === 'string') |
| 65 id += '/' + groupId; | 130 id += '/' + groupId; |
| 66 if (!parent.children) | 131 var node = parent.children().get(id); |
| 67 parent.children = /** @type {!Map<string,!TimelineModel.TimelineProfileTre
e.Node>} */ (new Map()); | |
| 68 var node = parent.children.get(id); | |
| 69 if (node) { | 132 if (node) { |
| 70 node.selfTime += time; | 133 node.selfTime += time; |
| 71 node.totalTime += time; | 134 node.totalTime += time; |
| 72 } else { | 135 } else { |
| 73 node = new TimelineModel.TimelineProfileTree.Node(); | 136 node = new TimelineModel.TimelineProfileTree.TopDownNode(id, e); |
| 74 node.totalTime = time; | 137 node.totalTime = time; |
| 75 node.selfTime = time; | 138 node.selfTime = time; |
| 76 node.parent = parent; | 139 node.parent = parent; |
| 77 node.id = id; | |
| 78 node.event = e; | |
| 79 node._groupId = groupId; | 140 node._groupId = groupId; |
| 80 parent.children.set(id, node); | 141 parent.children().set(id, node); |
| 81 } | 142 } |
| 82 parent.selfTime -= time; | 143 parent.selfTime -= time; |
| 83 if (parent.selfTime < 0) { | 144 if (parent.selfTime < 0) { |
| 84 console.error('Error: Negative self of ' + parent.selfTime, e); | 145 console.error('Error: Negative self of ' + parent.selfTime, e); |
| 85 parent.selfTime = 0; | 146 parent.selfTime = 0; |
| 86 } | 147 } |
| 87 if (e.endTime) | 148 if (e.endTime) |
| 88 parent = node; | 149 parent = node; |
| 89 } | 150 } |
| 90 | 151 |
| 91 /** | 152 /** |
| 92 * @param {!SDK.TracingModel.Event} e | 153 * @param {!SDK.TracingModel.Event} e |
| 93 */ | 154 */ |
| 94 function onEndEvent(e) { | 155 function onEndEvent(e) { |
| 95 if (!TimelineModel.TimelineModel.isVisible(filters, e)) | 156 if (!TimelineModel.TimelineModel.isVisible(filters, e)) |
| 96 return; | 157 return; |
| 97 parent = parent.parent; | 158 parent = parent.parent; |
| 98 } | 159 } |
| 99 | 160 |
| 100 var instantEventCallback = | 161 var instantEventCallback = |
| 101 eventGroupIdCallback ? undefined : onStartEvent; // Ignore instant events
when aggregating. | 162 eventGroupIdCallback ? undefined : onStartEvent; // Ignore instant events
when aggregating. |
| 102 TimelineModel.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, ins
tantEventCallback, startTime, endTime); | 163 TimelineModel.TimelineModel.forEachEvent(events, onStartEvent, onEndEvent, ins
tantEventCallback, startTime, endTime); |
| 103 root.totalTime -= root.selfTime; | 164 root.totalTime -= root.selfTime; |
| 104 root.selfTime = 0; | 165 root.selfTime = 0; |
| 105 return root; | 166 return root; |
| 106 }; | 167 }; |
| 107 | 168 |
| 169 TimelineModel.TimelineProfileTree.BottomUpTreeRootNode = class extends TimelineM
odel.TimelineProfileTree.Node { |
| 170 /** |
| 171 * @param {!TimelineModel.TimelineProfileTree} tree |
| 172 */ |
| 173 constructor(tree) { |
| 174 super('', null); |
| 175 this._tree = tree; |
| 176 this.totalTime = this._tree._endTime - this._tree._startTime; |
| 177 } |
| 178 |
| 179 /** |
| 180 * @override |
| 181 * @return {boolean} |
| 182 */ |
| 183 hasChildren() { |
| 184 return true; |
| 185 } |
| 186 |
| 187 /** |
| 188 * @override |
| 189 * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>} |
| 190 */ |
| 191 children() { |
| 192 return this._grouppedTopNodes(); |
| 193 } |
| 194 |
| 195 /** |
| 196 * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>} |
| 197 */ |
| 198 _ungrouppedTopNodes() { |
| 199 var root = this; |
| 200 var startTime = this._tree._startTime; |
| 201 var endTime = this._tree._endTime; |
| 202 /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Node>} */ |
| 203 var nodeById = new Map(); |
| 204 /** @type {!Array<number>} */ |
| 205 var selfTimeStack = [endTime - startTime]; |
| 206 /** @type {!Array<boolean>} */ |
| 207 var firstNodeStack = []; |
| 208 /** @type {!Map<string, number>} */ |
| 209 var totalTimeById = new Map(); |
| 210 TimelineModel.TimelineModel.forEachEvent( |
| 211 this._tree._events, onStartEvent, onEndEvent, undefined, startTime, endT
ime, this._tree._filter); |
| 212 |
| 213 /** |
| 214 * @param {!SDK.TracingModel.Event} e |
| 215 */ |
| 216 function onStartEvent(e) { |
| 217 var duration = Math.min(e.endTime, endTime) - Math.max(e.startTime, startT
ime); |
| 218 selfTimeStack[selfTimeStack.length - 1] -= duration; |
| 219 selfTimeStack.push(duration); |
| 220 var id = TimelineModel.TimelineProfileTree._eventId(e); |
| 221 var noNodeOnStack = !totalTimeById.has(id); |
| 222 if (noNodeOnStack) |
| 223 totalTimeById.set(id, duration); |
| 224 firstNodeStack.push(noNodeOnStack); |
| 225 } |
| 226 |
| 227 /** |
| 228 * @param {!SDK.TracingModel.Event} e |
| 229 */ |
| 230 function onEndEvent(e) { |
| 231 var id = TimelineModel.TimelineProfileTree._eventId(e); |
| 232 var node = nodeById.get(id); |
| 233 if (!node) { |
| 234 node = new TimelineModel.TimelineProfileTree.BottomUpTreeNode(root._tree
, id, e, true, root); |
| 235 nodeById.set(id, node); |
| 236 } |
| 237 node.selfTime += selfTimeStack.pop(); |
| 238 if (firstNodeStack.pop()) { |
| 239 node.totalTime += totalTimeById.get(id); |
| 240 totalTimeById.delete(id); |
| 241 } |
| 242 } |
| 243 |
| 244 this.selfTime = selfTimeStack.pop(); |
| 245 for (var pair of nodeById) { |
| 246 if (pair[1].selfTime <= 0) |
| 247 nodeById.delete(/** @type {string} */ (pair[0])); |
| 248 } |
| 249 return nodeById; |
| 250 } |
| 251 |
| 252 /** |
| 253 * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>} |
| 254 */ |
| 255 _grouppedTopNodes() { |
| 256 var flatNodes = this._ungrouppedTopNodes(); |
| 257 var groupNodes = new Map(); |
| 258 for (var node of flatNodes.values()) { |
| 259 var groupId = this._tree._eventGroupIdCallback(/** @type {!SDK.TracingMode
l.Event} */ (node.event)); |
| 260 if (typeof groupId !== 'string') |
| 261 return flatNodes; |
| 262 var groupNode = groupNodes.get(groupId); |
| 263 if (!groupNode) { |
| 264 groupNode = new TimelineModel.TimelineProfileTree.BottomUpTreeGroupNode( |
| 265 groupId, /** @type {!SDK.TracingModel.Event} */ (node.event)); |
| 266 groupNode.parent = this; |
| 267 groupNodes.set(groupId, groupNode); |
| 268 } |
| 269 groupNode.addChild(node); |
| 270 node.parent = groupNode; |
| 271 } |
| 272 return groupNodes; |
| 273 } |
| 274 }; |
| 275 |
| 276 TimelineModel.TimelineProfileTree.BottomUpTreeGroupNode = class extends Timeline
Model.TimelineProfileTree.Node { |
| 277 /** |
| 278 * @param {string} id |
| 279 * @param {!SDK.TracingModel.Event} event |
| 280 */ |
| 281 constructor(id, event) { |
| 282 super(id, event); |
| 283 this._children = new Map(); |
| 284 this._isGroupNode = true; |
| 285 } |
| 286 |
| 287 /** |
| 288 * @param {!TimelineModel.TimelineProfileTree.BottomUpTreeNode} child |
| 289 */ |
| 290 addChild(child) { |
| 291 this._children.set(child.id, child); |
| 292 this.selfTime += child.selfTime; |
| 293 this.totalTime += child.selfTime; |
| 294 } |
| 295 |
| 296 /** |
| 297 * @override |
| 298 * @return {boolean} |
| 299 */ |
| 300 hasChildren() { |
| 301 return true; |
| 302 } |
| 303 |
| 304 /** |
| 305 * @override |
| 306 * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>} |
| 307 */ |
| 308 children() { |
| 309 return this._children; |
| 310 } |
| 311 }; |
| 312 |
| 313 TimelineModel.TimelineProfileTree.BottomUpTreeNode = class extends TimelineModel
.TimelineProfileTree.Node { |
| 314 /** |
| 315 * @param {!TimelineModel.TimelineProfileTree} tree |
| 316 * @param {string} id |
| 317 * @param {!SDK.TracingModel.Event} event |
| 318 * @param {boolean} hasChildren |
| 319 * @param {!TimelineModel.TimelineProfileTree.Node} parent |
| 320 */ |
| 321 constructor(tree, id, event, hasChildren, parent) { |
| 322 super(id, event); |
| 323 this.parent = parent; |
| 324 this._tree = tree; |
| 325 this._depth = (parent._depth || 0) + 1; |
| 326 this._cachedChildren = null; |
| 327 this._hasChildren = hasChildren; |
| 328 } |
| 329 |
| 330 /** |
| 331 * @override |
| 332 * @return {boolean} |
| 333 */ |
| 334 hasChildren() { |
| 335 return this._hasChildren; |
| 336 } |
| 337 |
| 338 /** |
| 339 * @override |
| 340 * @return {!Map<string, !TimelineModel.TimelineProfileTree.Node>} |
| 341 */ |
| 342 children() { |
| 343 if (this._cachedChildren) |
| 344 return this._cachedChildren; |
| 345 /** @type {!Array<number>} */ |
| 346 var selfTimeStack = [0]; |
| 347 /** @type {!Array<string>} */ |
| 348 var eventIdStack = []; |
| 349 /** @type {!Array<!SDK.TracingModel.Event>} */ |
| 350 var eventStack = []; |
| 351 /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Node>} */ |
| 352 var nodeById = new Map(); |
| 353 var startTime = this._tree._startTime; |
| 354 var endTime = this._tree._endTime; |
| 355 var lastTimeMarker = startTime; |
| 356 var self = this; |
| 357 TimelineModel.TimelineModel.forEachEvent( |
| 358 this._tree._events, onStartEvent, onEndEvent, undefined, startTime, endT
ime, this._tree._filter); |
| 359 |
| 360 /** |
| 361 * @param {!SDK.TracingModel.Event} e |
| 362 */ |
| 363 function onStartEvent(e) { |
| 364 var duration = Math.min(e.endTime, endTime) - Math.max(e.startTime, startT
ime); |
| 365 if (duration < 0) |
| 366 console.assert(false, 'Negative duration of an event'); |
| 367 selfTimeStack[selfTimeStack.length - 1] -= duration; |
| 368 selfTimeStack.push(duration); |
| 369 var id = TimelineModel.TimelineProfileTree._eventId(e); |
| 370 eventIdStack.push(id); |
| 371 eventStack.push(e); |
| 372 } |
| 373 |
| 374 /** |
| 375 * @param {!SDK.TracingModel.Event} e |
| 376 */ |
| 377 function onEndEvent(e) { |
| 378 var selfTime = selfTimeStack.pop(); |
| 379 var id = eventIdStack.pop(); |
| 380 eventStack.pop(); |
| 381 for (var node = self; node._depth > 1; node = node.parent) { |
| 382 if (node.id !== eventIdStack[eventIdStack.length + 1 - node._depth]) |
| 383 return; |
| 384 } |
| 385 if (node.id !== id || eventIdStack.length < self._depth) |
| 386 return; |
| 387 var childId = eventIdStack[eventIdStack.length - self._depth]; |
| 388 var node = nodeById.get(childId); |
| 389 if (!node) { |
| 390 var event = eventStack[eventStack.length - self._depth]; |
| 391 var hasChildren = eventStack.length > self._depth; |
| 392 node = new TimelineModel.TimelineProfileTree.BottomUpTreeNode(self._tree
, childId, event, hasChildren, self); |
| 393 nodeById.set(childId, node); |
| 394 } |
| 395 var totalTime = Math.min(e.endTime, endTime) - Math.max(e.startTime, lastT
imeMarker); |
| 396 node.selfTime += selfTime; |
| 397 node.totalTime += totalTime; |
| 398 lastTimeMarker = Math.min(e.endTime, endTime); |
| 399 } |
| 400 |
| 401 this._cachedChildren = nodeById; |
| 402 return nodeById; |
| 403 } |
| 404 }; |
| 405 |
| 108 /** | 406 /** |
| 109 * @param {!TimelineModel.TimelineProfileTree.Node} topDownTree | |
| 110 * @return {!TimelineModel.TimelineProfileTree.Node} | |
| 111 */ | |
| 112 TimelineModel.TimelineProfileTree.buildBottomUp = function(topDownTree) { | |
| 113 var buRoot = new TimelineModel.TimelineProfileTree.Node(); | |
| 114 var aggregator = new TimelineModel.TimelineAggregator(); | |
| 115 buRoot.selfTime = 0; | |
| 116 buRoot.totalTime = 0; | |
| 117 /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Node>} */ | |
| 118 buRoot.children = new Map(); | |
| 119 var nodesOnStack = /** @type {!Set<string>} */ (new Set()); | |
| 120 if (topDownTree.children) | |
| 121 topDownTree.children.forEach(processNode); | |
| 122 buRoot.totalTime = topDownTree.totalTime; | |
| 123 | |
| 124 /** | |
| 125 * @param {!TimelineModel.TimelineProfileTree.Node} tdNode | |
| 126 */ | |
| 127 function processNode(tdNode) { | |
| 128 var buParent = | |
| 129 typeof tdNode._groupId === 'string' ? aggregator.groupNodeForId(tdNode._
groupId, tdNode.event) : buRoot; | |
| 130 if (buParent !== buRoot && !buParent.parent) { | |
| 131 buRoot.children.set(buParent.id, buParent); | |
| 132 buParent.parent = buRoot; | |
| 133 } | |
| 134 appendNode(tdNode, buParent); | |
| 135 var hadNode = nodesOnStack.has(tdNode.id); | |
| 136 if (!hadNode) | |
| 137 nodesOnStack.add(tdNode.id); | |
| 138 if (tdNode.children) | |
| 139 tdNode.children.forEach(processNode); | |
| 140 if (!hadNode) | |
| 141 nodesOnStack.delete(tdNode.id); | |
| 142 } | |
| 143 | |
| 144 /** | |
| 145 * @param {!TimelineModel.TimelineProfileTree.Node} tdNode | |
| 146 * @param {!TimelineModel.TimelineProfileTree.Node} buParent | |
| 147 */ | |
| 148 function appendNode(tdNode, buParent) { | |
| 149 var selfTime = tdNode.selfTime; | |
| 150 var totalTime = tdNode.totalTime; | |
| 151 buParent.selfTime += selfTime; | |
| 152 buParent.totalTime += selfTime; | |
| 153 while (tdNode.parent) { | |
| 154 if (!buParent.children) | |
| 155 buParent.children = /** @type {!Map<string,!TimelineModel.TimelineProfil
eTree.Node>} */ (new Map()); | |
| 156 var id = tdNode.id; | |
| 157 var buNode = buParent.children.get(id); | |
| 158 if (!buNode) { | |
| 159 buNode = new TimelineModel.TimelineProfileTree.Node(); | |
| 160 buNode.selfTime = selfTime; | |
| 161 buNode.totalTime = totalTime; | |
| 162 buNode.event = tdNode.event; | |
| 163 buNode.id = id; | |
| 164 buNode.parent = buParent; | |
| 165 buParent.children.set(id, buNode); | |
| 166 } else { | |
| 167 buNode.selfTime += selfTime; | |
| 168 if (!nodesOnStack.has(id)) | |
| 169 buNode.totalTime += totalTime; | |
| 170 } | |
| 171 tdNode = tdNode.parent; | |
| 172 buParent = buNode; | |
| 173 } | |
| 174 } | |
| 175 | |
| 176 // Purge zero self time nodes. | |
| 177 var rootChildren = buRoot.children; | |
| 178 for (var item of rootChildren.entries()) { | |
| 179 if (item[1].selfTime === 0) | |
| 180 rootChildren.delete(/** @type {string} */ (item[0])); | |
| 181 } | |
| 182 | |
| 183 return buRoot; | |
| 184 }; | |
| 185 | |
| 186 /** | |
| 187 * @param {!SDK.TracingModel.Event} event | 407 * @param {!SDK.TracingModel.Event} event |
| 188 * @return {?string} | 408 * @return {?string} |
| 189 */ | 409 */ |
| 190 TimelineModel.TimelineProfileTree.eventURL = function(event) { | 410 TimelineModel.TimelineProfileTree.eventURL = function(event) { |
| 191 var data = event.args['data'] || event.args['beginData']; | 411 var data = event.args['data'] || event.args['beginData']; |
| 192 if (data && data['url']) | 412 if (data && data['url']) |
| 193 return data['url']; | 413 return data['url']; |
| 194 var frame = TimelineModel.TimelineProfileTree.eventStackFrame(event); | 414 var frame = TimelineModel.TimelineProfileTree.eventStackFrame(event); |
| 195 while (frame) { | 415 while (frame) { |
| 196 var url = frame['url']; | 416 var url = frame['url']; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 225 TimelineModel.TimelineJSProfileProcessor.nativeGroup(functionName) || func
tionName : | 445 TimelineModel.TimelineJSProfileProcessor.nativeGroup(functionName) || func
tionName : |
| 226 functionName; | 446 functionName; |
| 227 return `f:${name}@${location}`; | 447 return `f:${name}@${location}`; |
| 228 }; | 448 }; |
| 229 | 449 |
| 230 /** | 450 /** |
| 231 * @unrestricted | 451 * @unrestricted |
| 232 */ | 452 */ |
| 233 TimelineModel.TimelineAggregator = class { | 453 TimelineModel.TimelineAggregator = class { |
| 234 constructor() { | 454 constructor() { |
| 235 /** @type {!Map<string, !TimelineModel.TimelineProfileTree.Node>} */ | 455 /** @type {!Map<string, !TimelineModel.TimelineProfileTree.TopDownNode>} */ |
| 236 this._groupNodes = new Map(); | 456 this._groupNodes = new Map(); |
| 237 } | 457 } |
| 238 | 458 |
| 239 /** | 459 /** |
| 240 * @param {!TimelineModel.TimelineProfileTree.Node} root | 460 * @param {!TimelineModel.TimelineProfileTree.Node} root |
| 241 * @return {!TimelineModel.TimelineProfileTree.Node} | 461 * @return {!TimelineModel.TimelineProfileTree.Node} |
| 242 */ | 462 */ |
| 243 performGrouping(root) { | 463 performGrouping(root) { |
| 244 for (var node of root.children.values()) { | 464 for (var node of root.children().values()) { |
| 245 var groupNode = this.groupNodeForId(node._groupId, node.event); | 465 var groupNode = this.groupNodeForId(node._groupId, /** @type {!SDK.Tracing
Model.Event} */ (node.event)); |
| 246 groupNode.parent = root; | 466 groupNode.parent = root; |
| 247 groupNode.selfTime += node.selfTime; | 467 groupNode.selfTime += node.selfTime; |
| 248 groupNode.totalTime += node.totalTime; | 468 groupNode.totalTime += node.totalTime; |
| 249 groupNode.children.set(node.id, node); | 469 groupNode.children().set(node.id, node); |
| 250 node.parent = root; | 470 node.parent = root; |
| 251 } | 471 } |
| 252 root.children = this._groupNodes; | 472 root._children = this._groupNodes; |
| 253 return root; | 473 return root; |
| 254 } | 474 } |
| 255 | 475 |
| 256 /** | 476 /** |
| 257 * @param {string} groupId | 477 * @param {string} groupId |
| 258 * @param {!SDK.TracingModel.Event} event | 478 * @param {!SDK.TracingModel.Event} event |
| 259 * @return {!TimelineModel.TimelineProfileTree.Node} | 479 * @return {!TimelineModel.TimelineProfileTree.Node} |
| 260 */ | 480 */ |
| 261 groupNodeForId(groupId, event) { | 481 groupNodeForId(groupId, event) { |
| 262 var node = this._groupNodes.get(groupId); | 482 var node = this._groupNodes.get(groupId); |
| 263 return node || this._buildGroupNode(groupId, event); | 483 return node || this._buildGroupNode(groupId, event); |
| 264 } | 484 } |
| 265 | 485 |
| 266 /** | 486 /** |
| 267 * @param {string} id | 487 * @param {string} id |
| 268 * @param {!SDK.TracingModel.Event} event | 488 * @param {!SDK.TracingModel.Event} event |
| 269 * @return {!TimelineModel.TimelineProfileTree.Node} | 489 * @return {!TimelineModel.TimelineProfileTree.Node} |
| 270 */ | 490 */ |
| 271 _buildGroupNode(id, event) { | 491 _buildGroupNode(id, event) { |
| 272 var groupNode = new TimelineModel.TimelineProfileTree.Node(); | 492 var groupNode = new TimelineModel.TimelineProfileTree.TopDownNode(id, event)
; |
| 273 groupNode.id = id; | |
| 274 groupNode.selfTime = 0; | 493 groupNode.selfTime = 0; |
| 275 groupNode.totalTime = 0; | 494 groupNode.totalTime = 0; |
| 276 groupNode.children = new Map(); | |
| 277 groupNode.event = event; | |
| 278 groupNode._isGroupNode = true; | 495 groupNode._isGroupNode = true; |
| 279 this._groupNodes.set(id, groupNode); | 496 this._groupNodes.set(id, groupNode); |
| 280 return groupNode; | 497 return groupNode; |
| 281 } | 498 } |
| 282 }; | 499 }; |
| 283 | |
| 284 TimelineModel.TimelineAggregator._groupNodeFlag = Symbol('groupNode'); | |
| OLD | NEW |