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

Side by Side Diff: Source/devtools/front_end/AllocationProfile.js

Issue 202953003: Use top-down and bottom-up profile notions in allocation profiler (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Added type annotations Created 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 25 matching lines...) Expand all
36 this._strings = profile.strings; 36 this._strings = profile.strings;
37 this._liveObjectStats = liveObjectStats; 37 this._liveObjectStats = liveObjectStats;
38 38
39 this._nextNodeId = 1; 39 this._nextNodeId = 1;
40 this._functionInfos = [] 40 this._functionInfos = []
41 this._idToNode = {}; 41 this._idToNode = {};
42 this._collapsedTopNodeIdToFunctionInfo = {}; 42 this._collapsedTopNodeIdToFunctionInfo = {};
43 43
44 this._traceTops = null; 44 this._traceTops = null;
45 45
46 this._buildAllocationFunctionInfos(profile); 46 this._buildFunctionAllocationInfos(profile);
47 this._traceTree = this._buildInvertedAllocationTree(profile, liveObjectStats ); 47 this._traceTree = this._buildAllocationTree(profile, liveObjectStats);
48 } 48 }
49 49
50 WebInspector.AllocationProfile.prototype = { 50 WebInspector.AllocationProfile.prototype = {
51 _buildAllocationFunctionInfos: function(profile) 51 _buildFunctionAllocationInfos: function(profile)
52 { 52 {
53 var strings = this._strings; 53 var strings = this._strings;
54 54
55 var functionInfoFields = profile.snapshot.meta.trace_function_info_field s; 55 var functionInfoFields = profile.snapshot.meta.trace_function_info_field s;
56 var functionIdOffset = functionInfoFields.indexOf("function_id"); 56 var functionIdOffset = functionInfoFields.indexOf("function_id");
57 var functionNameOffset = functionInfoFields.indexOf("name"); 57 var functionNameOffset = functionInfoFields.indexOf("name");
58 var scriptNameOffset = functionInfoFields.indexOf("script_name"); 58 var scriptNameOffset = functionInfoFields.indexOf("script_name");
59 var scriptIdOffset = functionInfoFields.indexOf("script_id"); 59 var scriptIdOffset = functionInfoFields.indexOf("script_id");
60 var lineOffset = functionInfoFields.indexOf("line"); 60 var lineOffset = functionInfoFields.indexOf("line");
61 var columnOffset = functionInfoFields.indexOf("column"); 61 var columnOffset = functionInfoFields.indexOf("column");
62 var functionInfoFieldCount = functionInfoFields.length; 62 var functionInfoFieldCount = functionInfoFields.length;
63 63
64 var rawInfos = profile.trace_function_infos; 64 var rawInfos = profile.trace_function_infos;
65 var infoLength = rawInfos.length; 65 var infoLength = rawInfos.length;
66 var functionInfos = this._functionInfos = new Array(infoLength / functio nInfoFieldCount); 66 var functionInfos = this._functionInfos = new Array(infoLength / functio nInfoFieldCount);
67 var index = 0; 67 var index = 0;
68 for (var i = 0; i < infoLength; i += functionInfoFieldCount) { 68 for (var i = 0; i < infoLength; i += functionInfoFieldCount) {
69 functionInfos[index++] = new WebInspector.FunctionAllocationInfo( 69 functionInfos[index++] = new WebInspector.FunctionAllocationInfo(
70 strings[rawInfos[i + functionNameOffset]], 70 strings[rawInfos[i + functionNameOffset]],
71 strings[rawInfos[i + scriptNameOffset]], 71 strings[rawInfos[i + scriptNameOffset]],
72 rawInfos[i + scriptIdOffset], 72 rawInfos[i + scriptIdOffset],
73 rawInfos[i + lineOffset], 73 rawInfos[i + lineOffset],
74 rawInfos[i + columnOffset]); 74 rawInfos[i + columnOffset]);
75 } 75 }
76 }, 76 },
77 77
78 _buildInvertedAllocationTree: function(profile, liveObjectStats) 78 _buildAllocationTree: function(profile, liveObjectStats)
79 { 79 {
80 var traceTreeRaw = profile.trace_tree; 80 var traceTreeRaw = profile.trace_tree;
81 var functionInfos = this._functionInfos; 81 var functionInfos = this._functionInfos;
82 82
83 var traceNodeFields = profile.snapshot.meta.trace_node_fields; 83 var traceNodeFields = profile.snapshot.meta.trace_node_fields;
84 var nodeIdOffset = traceNodeFields.indexOf("id"); 84 var nodeIdOffset = traceNodeFields.indexOf("id");
85 var functionInfoIndexOffset = traceNodeFields.indexOf("function_info_ind ex"); 85 var functionInfoIndexOffset = traceNodeFields.indexOf("function_info_ind ex");
86 var allocationCountOffset = traceNodeFields.indexOf("count"); 86 var allocationCountOffset = traceNodeFields.indexOf("count");
87 var allocationSizeOffset = traceNodeFields.indexOf("size"); 87 var allocationSizeOffset = traceNodeFields.indexOf("size");
88 var childrenOffset = traceNodeFields.indexOf("children"); 88 var childrenOffset = traceNodeFields.indexOf("children");
89 var nodeFieldCount = traceNodeFields.length; 89 var nodeFieldCount = traceNodeFields.length;
90 90
91 function traverseNode(rawNodeArray, nodeOffset, parent) 91 function traverseNode(rawNodeArray, nodeOffset, parent)
92 { 92 {
93 var functionInfo = functionInfos[rawNodeArray[nodeOffset + functionI nfoIndexOffset]]; 93 var functionInfo = functionInfos[rawNodeArray[nodeOffset + functionI nfoIndexOffset]];
94 var id = rawNodeArray[nodeOffset + nodeIdOffset]; 94 var id = rawNodeArray[nodeOffset + nodeIdOffset];
95 var stats = liveObjectStats[id]; 95 var stats = liveObjectStats[id];
96 var liveCount = stats ? stats.count : 0; 96 var liveCount = stats ? stats.count : 0;
97 var liveSize = stats ? stats.size : 0; 97 var liveSize = stats ? stats.size : 0;
98 var result = new WebInspector.AllocationTraceNode( 98 var result = new WebInspector.TopDownAllocationNode(
99 id, 99 id,
100 functionInfo, 100 functionInfo,
101 rawNodeArray[nodeOffset + allocationCountOffset], 101 rawNodeArray[nodeOffset + allocationCountOffset],
102 rawNodeArray[nodeOffset + allocationSizeOffset], 102 rawNodeArray[nodeOffset + allocationSizeOffset],
103 liveCount, 103 liveCount,
104 liveSize, 104 liveSize,
105 parent); 105 parent);
106 functionInfo.addTraceTopNode(result); 106 functionInfo.addTraceTopNode(result);
107 107
108 var rawChildren = rawNodeArray[nodeOffset + childrenOffset]; 108 var rawChildren = rawNodeArray[nodeOffset + childrenOffset];
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 147
148 /** 148 /**
149 * @param {string} nodeId 149 * @param {string} nodeId
150 * @return {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers} 150 * @return {!WebInspector.HeapSnapshotCommon.AllocationNodeCallers}
151 */ 151 */
152 serializeCallers: function(nodeId) 152 serializeCallers: function(nodeId)
153 { 153 {
154 var node = this._idToNode[nodeId]; 154 var node = this._idToNode[nodeId];
155 if (!node) { 155 if (!node) {
156 var functionInfo = this._collapsedTopNodeIdToFunctionInfo[nodeId]; 156 var functionInfo = this._collapsedTopNodeIdToFunctionInfo[nodeId];
157 node = functionInfo.tracesWithThisTop(); 157 node = functionInfo.bottomUpRoot();
158 delete this._collapsedTopNodeIdToFunctionInfo[nodeId]; 158 delete this._collapsedTopNodeIdToFunctionInfo[nodeId];
159 this._idToNode[nodeId] = node; 159 this._idToNode[nodeId] = node;
160 } 160 }
161 161
162 var nodesWithSingleCaller = []; 162 var nodesWithSingleCaller = [];
163 while (node.callers().length === 1) { 163 while (node.callers().length === 1) {
164 node = node.callers()[0]; 164 node = node.callers()[0];
165 nodesWithSingleCaller.push(this._serializeCaller(node)); 165 nodesWithSingleCaller.push(this._serializeCaller(node));
166 } 166 }
167 167
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 liveCount, 210 liveCount,
211 liveSize, 211 liveSize,
212 hasChildren 212 hasChildren
213 ); 213 );
214 } 214 }
215 } 215 }
216 216
217 217
218 /** 218 /**
219 * @constructor 219 * @constructor
220 * @param {number} id
221 * @param {!WebInspector.FunctionAllocationInfo} functionInfo
222 * @param {number} count
223 * @param {number} size
224 * @param {number} liveCount
225 * @param {number} liveSize
226 * @param {?WebInspector.TopDownAllocationNode} parent
220 */ 227 */
221 WebInspector.AllocationTraceNode = function(id, functionInfo, count, size, liveC ount, liveSize, parent) 228 WebInspector.TopDownAllocationNode = function(id, functionInfo, count, size, liv eCount, liveSize, parent)
222 { 229 {
223 this.id = id; 230 this.id = id;
224 this.functionInfo = functionInfo; 231 this.functionInfo = functionInfo;
225 this.allocationCount = count; 232 this.allocationCount = count;
226 this.allocationSize = size; 233 this.allocationSize = size;
227 this.liveCount = liveCount; 234 this.liveCount = liveCount;
228 this.liveSize = liveSize; 235 this.liveSize = liveSize;
229 this.parent = parent; 236 this.parent = parent;
230 this.children = []; 237 this.children = [];
231 } 238 }
232 239
233 240
234 /** 241 /**
235 * @constructor 242 * @constructor
236 * @param {!WebInspector.FunctionAllocationInfo} functionInfo 243 * @param {!WebInspector.FunctionAllocationInfo} functionInfo
237 */ 244 */
238 WebInspector.AllocationBackTraceNode = function(functionInfo) 245 WebInspector.BottomUpAllocationNode = function(functionInfo)
239 { 246 {
240 this.functionInfo = functionInfo; 247 this.functionInfo = functionInfo;
241 this.allocationCount = 0; 248 this.allocationCount = 0;
242 this.allocationSize = 0; 249 this.allocationSize = 0;
243 this.liveCount = 0; 250 this.liveCount = 0;
244 this.liveSize = 0; 251 this.liveSize = 0;
245 this._callers = []; 252 this._callers = [];
246 } 253 }
247 254
248 255
249 WebInspector.AllocationBackTraceNode.prototype = { 256 WebInspector.BottomUpAllocationNode.prototype = {
250 /** 257 /**
251 * @param {!WebInspector.AllocationTraceNode} traceNode 258 * @param {!WebInspector.TopDownAllocationNode} traceNode
252 * @return {!WebInspector.AllocationTraceNode} 259 * @return {!WebInspector.TopDownAllocationNode}
253 */ 260 */
254 addCaller: function(traceNode) 261 addCaller: function(traceNode)
255 { 262 {
256 var functionInfo = traceNode.functionInfo; 263 var functionInfo = traceNode.functionInfo;
257 var result; 264 var result;
258 for (var i = 0; i < this._callers.length; i++) { 265 for (var i = 0; i < this._callers.length; i++) {
259 var caller = this._callers[i]; 266 var caller = this._callers[i];
260 if (caller.functionInfo === functionInfo) { 267 if (caller.functionInfo === functionInfo) {
261 result = caller; 268 result = caller;
262 break; 269 break;
263 } 270 }
264 } 271 }
265 if (!result) { 272 if (!result) {
266 result = new WebInspector.AllocationBackTraceNode(functionInfo); 273 result = new WebInspector.BottomUpAllocationNode(functionInfo);
267 this._callers.push(result); 274 this._callers.push(result);
268 } 275 }
269 return result; 276 return result;
270 }, 277 },
271 278
272 /** 279 /**
273 * @return {!Array.<!WebInspector.AllocationBackTraceNode>} 280 * @return {!Array.<!WebInspector.BottomUpAllocationNode>}
274 */ 281 */
275 callers: function() 282 callers: function()
276 { 283 {
277 return this._callers; 284 return this._callers;
278 }, 285 },
279 286
280 /** 287 /**
281 * @return {boolean} 288 * @return {boolean}
282 */ 289 */
283 hasCallers: function() 290 hasCallers: function()
284 { 291 {
285 return this._callers.length > 0; 292 return this._callers.length > 0;
286 } 293 }
287 } 294 }
288 295
289 296
290 /** 297 /**
291 * @constructor 298 * @constructor
299 * @param {string} functionName
300 * @param {string} scriptName
301 * @param {number} scriptId
302 * @param {number} line
303 * @param {number} column
292 */ 304 */
293 WebInspector.FunctionAllocationInfo = function(functionName, scriptName, scriptI d, line, column) 305 WebInspector.FunctionAllocationInfo = function(functionName, scriptName, scriptI d, line, column)
294 { 306 {
295 this.functionName = functionName; 307 this.functionName = functionName;
296 this.scriptName = scriptName; 308 this.scriptName = scriptName;
297 this.scriptId = scriptId; 309 this.scriptId = scriptId;
298 this.line = line; 310 this.line = line;
299 this.column = column; 311 this.column = column;
300 this.totalCount = 0; 312 this.totalCount = 0;
301 this.totalSize = 0; 313 this.totalSize = 0;
302 this.totalLiveCount = 0; 314 this.totalLiveCount = 0;
303 this.totalLiveSize = 0; 315 this.totalLiveSize = 0;
304 this._traceTops = []; 316 this._traceTops = [];
305 } 317 }
306 318
307 WebInspector.FunctionAllocationInfo.prototype = { 319 WebInspector.FunctionAllocationInfo.prototype = {
320 /**
321 * @param {!WebInspector.TopDownAllocationNode} node
322 */
308 addTraceTopNode: function(node) 323 addTraceTopNode: function(node)
309 { 324 {
310 if (node.allocationCount === 0) 325 if (node.allocationCount === 0)
311 return; 326 return;
312 this._traceTops.push(node); 327 this._traceTops.push(node);
313 this.totalCount += node.allocationCount; 328 this.totalCount += node.allocationCount;
314 this.totalSize += node.allocationSize; 329 this.totalSize += node.allocationSize;
315 this.totalLiveCount += node.liveCount; 330 this.totalLiveCount += node.liveCount;
316 this.totalLiveSize += node.liveSize; 331 this.totalLiveSize += node.liveSize;
317 }, 332 },
318 333
319 /** 334 /**
320 * @return {?WebInspector.AllocationBackTraceNode} 335 * @return {?WebInspector.BottomUpAllocationNode}
321 */ 336 */
322 tracesWithThisTop: function() 337 bottomUpRoot: function()
323 { 338 {
324 if (!this._traceTops.length) 339 if (!this._traceTops.length)
325 return null; 340 return null;
326 if (!this._backTraceTree) 341 if (!this._bottomUpTree)
327 this._buildAllocationTraceTree(); 342 this._buildAllocationTraceTree();
328 return this._backTraceTree; 343 return this._bottomUpTree;
329 }, 344 },
330 345
331 _buildAllocationTraceTree: function() 346 _buildAllocationTraceTree: function()
332 { 347 {
333 this._backTraceTree = new WebInspector.AllocationBackTraceNode(this._tra ceTops[0].functionInfo); 348 this._bottomUpTree = new WebInspector.BottomUpAllocationNode(this);
334 349
335 for (var i = 0; i < this._traceTops.length; i++) { 350 for (var i = 0; i < this._traceTops.length; i++) {
336 var node = this._traceTops[i]; 351 var node = this._traceTops[i];
337 var backTraceNode = this._backTraceTree; 352 var bottomUpNode = this._bottomUpTree;
338 var count = node.allocationCount; 353 var count = node.allocationCount;
339 var size = node.allocationSize; 354 var size = node.allocationSize;
340 var liveCount = node.liveCount; 355 var liveCount = node.liveCount;
341 var liveSize = node.liveSize; 356 var liveSize = node.liveSize;
342 while (true) { 357 while (true) {
343 backTraceNode.allocationCount += count; 358 bottomUpNode.allocationCount += count;
344 backTraceNode.allocationSize += size; 359 bottomUpNode.allocationSize += size;
345 backTraceNode.liveCount += liveCount; 360 bottomUpNode.liveCount += liveCount;
346 backTraceNode.liveSize += liveSize; 361 bottomUpNode.liveSize += liveSize;
347 node = node.parent; 362 node = node.parent;
348 if (node === null) { 363 if (node === null) {
349 break; 364 break;
350 } 365 }
351 backTraceNode = backTraceNode.addCaller(node); 366 bottomUpNode = bottomUpNode.addCaller(node);
352 } 367 }
353 } 368 }
354 } 369 }
355 } 370 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698