Chromium Code Reviews| 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 |