OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 = { name : "root", codeId: -1, children : [], ownTicks : 0, tick s : 0 }; |
Jarin
2017/03/08 14:25:56
<80 character lines, please (here and below).
Leszek Swirski
2017/03/08 14:32:40
Done.
| |
269 this.categories = null; | 270 this.categories = null; |
270 } | 271 } |
271 | 272 |
272 this.codeVisited = []; | 273 this.codeVisited = []; |
273 this.filter = filter; | 274 this.filter = filter; |
274 } | 275 } |
275 | 276 |
276 addStack(file, tickIndex) { | 277 addStack(file, tickIndex) { |
277 let stack = file.ticks[tickIndex].s; | 278 let stack = file.ticks[tickIndex].s; |
278 let vmState = file.ticks[tickIndex].vm; | 279 let vmState = file.ticks[tickIndex].vm; |
(...skipping 13 matching lines...) Expand all Loading... | |
292 } | 293 } |
293 let childId = childIdFromCode(codeId, code); | 294 let childId = childIdFromCode(codeId, code); |
294 if (this.categories) { | 295 if (this.categories) { |
295 let kind = resolveCodeKindAndVmState(code, vmState); | 296 let kind = resolveCodeKindAndVmState(code, vmState); |
296 tree = this.categories[kind]; | 297 tree = this.categories[kind]; |
297 } else { | 298 } else { |
298 tree = this.tree; | 299 tree = this.tree; |
299 } | 300 } |
300 child = tree.children[childId]; | 301 child = tree.children[childId]; |
301 if (!child) { | 302 if (!child) { |
302 child = createNodeFromStackEntry(code); | 303 child = createNodeFromStackEntry(code, codeId); |
303 child.children[0] = createEmptyNode("Top-down tree"); | 304 child.children[0] = createEmptyNode("Top-down tree"); |
304 child.children[0].delayedExpansion = | 305 child.children[0].delayedExpansion = |
305 { frameList : [], ascending : false }; | 306 { frameList : [], ascending : false }; |
306 child.children[1] = createEmptyNode("Bottom-up tree"); | 307 child.children[1] = createEmptyNode("Bottom-up tree"); |
307 child.children[1].delayedExpansion = | 308 child.children[1].delayedExpansion = |
308 { frameList : [], ascending : true }; | 309 { frameList : [], ascending : true }; |
309 tree.children[childId] = child; | 310 tree.children[childId] = child; |
310 } | 311 } |
311 child.ticks++; | 312 child.ticks++; |
312 child.children[0].ticks++; | 313 child.children[0].ticks++; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
360 let bucket = this.buckets[i]; | 361 let bucket = this.buckets[i]; |
361 bucket.total++; | 362 bucket.total++; |
362 | 363 |
363 let codeId = (stack.length > 0) ? stack[0] : -1; | 364 let codeId = (stack.length > 0) ? stack[0] : -1; |
364 let code = codeId >= 0 ? file.code[codeId] : undefined; | 365 let code = codeId >= 0 ? file.code[codeId] : undefined; |
365 let kind = resolveCodeKindAndVmState(code, vmState); | 366 let kind = resolveCodeKindAndVmState(code, vmState); |
366 bucket[kind]++; | 367 bucket[kind]++; |
367 } | 368 } |
368 } | 369 } |
369 | 370 |
371 class FunctionTimelineProcessor { | |
372 constructor(functionCodeId, filter) { | |
373 this.functionCodeId = functionCodeId; | |
374 this.filter = filter; | |
375 this.blocks = []; | |
376 this.currentBlock = null; | |
377 } | |
378 | |
379 addStack(file, tickIndex) { | |
380 let { tm : timestamp, vm : vmState, s : stack } = file.ticks[tickIndex]; | |
381 | |
382 let codeInStack = stack.includes(this.functionCodeId); | |
383 if (codeInStack) { | |
384 let topOfStack = -1; | |
385 for (let i = 0; i < stack.length - 1; i += 2) { | |
386 let codeId = stack[i]; | |
387 let code = codeId >= 0 ? file.code[codeId] : undefined; | |
388 let type = code ? code.type : undefined; | |
389 let kind = code ? code.kind : undefined; | |
390 if (!this.filter(type, kind)) continue; | |
391 | |
392 topOfStack = i; | |
393 break; | |
394 } | |
395 | |
396 let codeIsTopOfStack = (topOfStack !== -1 && stack[topOfStack] === this.fu nctionCodeId); | |
397 | |
398 if (this.currentBlock !== null) { | |
399 this.currentBlock.end = timestamp; | |
400 | |
401 if (codeIsTopOfStack === this.currentBlock.topOfStack) { | |
402 return; | |
403 } | |
404 } | |
405 | |
406 this.currentBlock = { start: timestamp, end: timestamp, topOfStack: codeIs TopOfStack }; | |
407 this.blocks.push(this.currentBlock); | |
408 } else { | |
409 this.currentBlock = null; | |
410 } | |
411 } | |
412 } | |
413 | |
370 // Generates a tree out of a ticks sequence. | 414 // Generates a tree out of a ticks sequence. |
371 // {file} is the JSON files with the ticks and code objects. | 415 // {file} is the JSON files with the ticks and code objects. |
372 // {startTime}, {endTime} is the interval. | 416 // {startTime}, {endTime} is the interval. |
373 // {tree} is the processor of stacks. | 417 // {tree} is the processor of stacks. |
374 function generateTree( | 418 function generateTree( |
375 file, startTime, endTime, tree) { | 419 file, startTime, endTime, tree) { |
376 let ticks = file.ticks; | 420 let ticks = file.ticks; |
377 let i = 0; | 421 let i = 0; |
378 while (i < ticks.length && ticks[i].tm < startTime) { | 422 while (i < ticks.length && ticks[i].tm < startTime) { |
379 i++; | 423 i++; |
380 } | 424 } |
381 | 425 |
382 let tickCount = 0; | 426 let tickCount = 0; |
383 while (i < ticks.length && ticks[i].tm < endTime) { | 427 while (i < ticks.length && ticks[i].tm < endTime) { |
384 tree.addStack(file, i); | 428 tree.addStack(file, i); |
385 i++; | 429 i++; |
386 tickCount++; | 430 tickCount++; |
387 } | 431 } |
388 | 432 |
389 return tickCount; | 433 return tickCount; |
390 } | 434 } |
OLD | NEW |