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

Side by Side Diff: tools/profview/profile-utils.js

Issue 2737083003: [tools/profview] Add individual function timeline view (Closed)
Patch Set: Rebase Created 3 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
OLDNEW
1 // Copyright 2017 the V8 project authors. All rights reserved. 1 // Copyright 2017 the V8 project 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 "use strict" 5 "use strict"
6 6
7 let codeKinds = [ 7 let codeKinds = [
8 "UNKNOWN", 8 "UNKNOWN",
9 "CPPCOMP", 9 "CPPCOMP",
10 "CPPGC", 10 "CPPGC",
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 kind = "CPPGC"; 65 kind = "CPPGC";
66 } else if (vmState === 2) { 66 } else if (vmState === 2) {
67 kind = "CPPCOMP"; 67 kind = "CPPCOMP";
68 } else if (vmState === 4) { 68 } else if (vmState === 4) {
69 kind = "CPPEXT"; 69 kind = "CPPEXT";
70 } 70 }
71 } 71 }
72 return kind; 72 return kind;
73 } 73 }
74 74
75 function createNodeFromStackEntry(code) { 75 function createNodeFromStackEntry(code, codeId) {
76 let name = code ? code.name : "UNKNOWN"; 76 let name = code ? code.name : "UNKNOWN";
77 77
78 return { name, type : resolveCodeKind(code), 78 return { name, codeId, type : resolveCodeKind(code),
79 children : [], ownTicks : 0, ticks : 0 }; 79 children : [], ownTicks : 0, ticks : 0 };
80 } 80 }
81 81
82 function childIdFromCode(codeId, code) { 82 function childIdFromCode(codeId, code) {
83 // For JavaScript function, pretend there is one instance of optimized 83 // For JavaScript function, pretend there is one instance of optimized
84 // function and one instance of unoptimized function per SFI. 84 // function and one instance of unoptimized function per SFI.
85 // Otherwise, just compute the id from code id. 85 // Otherwise, just compute the id from code id.
86 let type = resolveCodeKind(code); 86 let type = resolveCodeKind(code);
87 if (type === "JSOPT") { 87 if (type === "JSOPT") {
88 return code.func * 4 + 1; 88 return code.func * 4 + 1;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 // If we are doing top-down call tree, update own ticks. 136 // If we are doing top-down call tree, update own ticks.
137 if (!ascending) { 137 if (!ascending) {
138 parent.ownTicks++; 138 parent.ownTicks++;
139 } 139 }
140 } else { 140 } else {
141 console.assert(stackPos >= 0 && stackPos < stack.length); 141 console.assert(stackPos >= 0 && stackPos < stack.length);
142 // We found a child node. 142 // We found a child node.
143 let childId = childIdFromCode(codeId, code); 143 let childId = childIdFromCode(codeId, code);
144 let child = parent.children[childId]; 144 let child = parent.children[childId];
145 if (!child) { 145 if (!child) {
146 child = createNodeFromStackEntry(code); 146 child = createNodeFromStackEntry(code, codeId);
147 child.delayedExpansion = { frameList : [], ascending }; 147 child.delayedExpansion = { frameList : [], ascending };
148 parent.children[childId] = child; 148 parent.children[childId] = child;
149 } 149 }
150 child.ticks++; 150 child.ticks++;
151 addFrameToFrameList(child.delayedExpansion.frameList, stackIndex, stackPos); 151 addFrameToFrameList(child.delayedExpansion.frameList, stackIndex, stackPos);
152 } 152 }
153 } 153 }
154 154
155 // This expands a tree node (direct children only). 155 // This expands a tree node (direct children only).
156 function expandTreeNode(file, node, filter) { 156 function expandTreeNode(file, node, filter) {
(...skipping 13 matching lines...) Expand all
170 let stackPos = findNextFrame(file, stack, depth + step, step, filter); 170 let stackPos = findNextFrame(file, stack, depth + step, step, filter);
171 addOrUpdateChildNode(node, file, stackIndex, stackPos, ascending); 171 addOrUpdateChildNode(node, file, stackIndex, stackPos, ascending);
172 } 172 }
173 } 173 }
174 node.delayedExpansion = null; 174 node.delayedExpansion = null;
175 } 175 }
176 176
177 function createEmptyNode(name) { 177 function createEmptyNode(name) {
178 return { 178 return {
179 name : name, 179 name : name,
180 codeId: -1,
180 type : "CAT", 181 type : "CAT",
181 children : [], 182 children : [],
182 ownTicks : 0, 183 ownTicks : 0,
183 ticks : 0 184 ticks : 0
184 }; 185 };
185 } 186 }
186 187
187 class PlainCallTreeProcessor { 188 class PlainCallTreeProcessor {
188 constructor(filter, isBottomUp) { 189 constructor(filter, isBottomUp) {
189 this.filter = filter; 190 this.filter = filter;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 } 259 }
259 } 260 }
260 261
261 class FunctionListTree { 262 class FunctionListTree {
262 constructor(filter, withCategories) { 263 constructor(filter, withCategories) {
263 if (withCategories) { 264 if (withCategories) {
264 let { categories, root } = buildCategoryTreeAndLookup(); 265 let { categories, root } = buildCategoryTreeAndLookup();
265 this.tree = root; 266 this.tree = root;
266 this.categories = categories; 267 this.categories = categories;
267 } else { 268 } else {
268 this.tree = { name : "root", children : [], ownTicks : 0, ticks : 0 }; 269 this.tree = {
270 name : "root",
271 codeId: -1,
272 children : [],
273 ownTicks : 0,
274 ticks : 0
275 };
269 this.categories = null; 276 this.categories = null;
270 } 277 }
271 278
272 this.codeVisited = []; 279 this.codeVisited = [];
273 this.filter = filter; 280 this.filter = filter;
274 } 281 }
275 282
276 addStack(file, tickIndex) { 283 addStack(file, tickIndex) {
277 let stack = file.ticks[tickIndex].s; 284 let stack = file.ticks[tickIndex].s;
278 let vmState = file.ticks[tickIndex].vm; 285 let vmState = file.ticks[tickIndex].vm;
(...skipping 13 matching lines...) Expand all
292 } 299 }
293 let childId = childIdFromCode(codeId, code); 300 let childId = childIdFromCode(codeId, code);
294 if (this.categories) { 301 if (this.categories) {
295 let kind = resolveCodeKindAndVmState(code, vmState); 302 let kind = resolveCodeKindAndVmState(code, vmState);
296 tree = this.categories[kind]; 303 tree = this.categories[kind];
297 } else { 304 } else {
298 tree = this.tree; 305 tree = this.tree;
299 } 306 }
300 child = tree.children[childId]; 307 child = tree.children[childId];
301 if (!child) { 308 if (!child) {
302 child = createNodeFromStackEntry(code); 309 child = createNodeFromStackEntry(code, codeId);
303 child.children[0] = createEmptyNode("Top-down tree"); 310 child.children[0] = createEmptyNode("Top-down tree");
304 child.children[0].delayedExpansion = 311 child.children[0].delayedExpansion =
305 { frameList : [], ascending : false }; 312 { frameList : [], ascending : false };
306 child.children[1] = createEmptyNode("Bottom-up tree"); 313 child.children[1] = createEmptyNode("Bottom-up tree");
307 child.children[1].delayedExpansion = 314 child.children[1].delayedExpansion =
308 { frameList : [], ascending : true }; 315 { frameList : [], ascending : true };
309 tree.children[childId] = child; 316 tree.children[childId] = child;
310 } 317 }
311 child.ticks++; 318 child.ticks++;
312 child.children[0].ticks++; 319 child.children[0].ticks++;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 let bucket = this.buckets[i]; 367 let bucket = this.buckets[i];
361 bucket.total++; 368 bucket.total++;
362 369
363 let codeId = (stack.length > 0) ? stack[0] : -1; 370 let codeId = (stack.length > 0) ? stack[0] : -1;
364 let code = codeId >= 0 ? file.code[codeId] : undefined; 371 let code = codeId >= 0 ? file.code[codeId] : undefined;
365 let kind = resolveCodeKindAndVmState(code, vmState); 372 let kind = resolveCodeKindAndVmState(code, vmState);
366 bucket[kind]++; 373 bucket[kind]++;
367 } 374 }
368 } 375 }
369 376
377 class FunctionTimelineProcessor {
378 constructor(functionCodeId, filter) {
379 this.functionCodeId = functionCodeId;
380 this.filter = filter;
381 this.blocks = [];
382 this.currentBlock = null;
383 }
384
385 addStack(file, tickIndex) {
386 let { tm : timestamp, vm : vmState, s : stack } = file.ticks[tickIndex];
387
388 let codeInStack = stack.includes(this.functionCodeId);
389 if (codeInStack) {
390 let topOfStack = -1;
391 for (let i = 0; i < stack.length - 1; i += 2) {
392 let codeId = stack[i];
393 let code = codeId >= 0 ? file.code[codeId] : undefined;
394 let type = code ? code.type : undefined;
395 let kind = code ? code.kind : undefined;
396 if (!this.filter(type, kind)) continue;
397
398 topOfStack = i;
399 break;
400 }
401
402 let codeIsTopOfStack =
403 (topOfStack !== -1 && stack[topOfStack] === this.functionCodeId);
Jarin 2017/03/08 16:35:56 This will not quite work for optimized code becaus
404
405 if (this.currentBlock !== null) {
406 this.currentBlock.end = timestamp;
407
408 if (codeIsTopOfStack === this.currentBlock.topOfStack) {
409 return;
410 }
411 }
412
413 this.currentBlock = {
414 start: timestamp,
415 end: timestamp,
416 topOfStack: codeIsTopOfStack
417 };
418 this.blocks.push(this.currentBlock);
419 } else {
420 this.currentBlock = null;
421 }
422 }
423 }
424
370 // Generates a tree out of a ticks sequence. 425 // Generates a tree out of a ticks sequence.
371 // {file} is the JSON files with the ticks and code objects. 426 // {file} is the JSON files with the ticks and code objects.
372 // {startTime}, {endTime} is the interval. 427 // {startTime}, {endTime} is the interval.
373 // {tree} is the processor of stacks. 428 // {tree} is the processor of stacks.
374 function generateTree( 429 function generateTree(
375 file, startTime, endTime, tree) { 430 file, startTime, endTime, tree) {
376 let ticks = file.ticks; 431 let ticks = file.ticks;
377 let i = 0; 432 let i = 0;
378 while (i < ticks.length && ticks[i].tm < startTime) { 433 while (i < ticks.length && ticks[i].tm < startTime) {
379 i++; 434 i++;
380 } 435 }
381 436
382 let tickCount = 0; 437 let tickCount = 0;
383 while (i < ticks.length && ticks[i].tm < endTime) { 438 while (i < ticks.length && ticks[i].tm < endTime) {
384 tree.addStack(file, i); 439 tree.addStack(file, i);
385 i++; 440 i++;
386 tickCount++; 441 tickCount++;
387 } 442 }
388 443
389 return tickCount; 444 return tickCount;
390 } 445 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698