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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 // Try to combine with the previous code run. | 104 // Try to combine with the previous code run. |
105 if (paths.length > 0 && | 105 if (paths.length > 0 && |
106 paths[paths.length - 3] + 1 === pathIndex && | 106 paths[paths.length - 3] + 1 === pathIndex && |
107 paths[paths.length - 2] === depth) { | 107 paths[paths.length - 2] === depth) { |
108 paths[paths.length - 1]++; | 108 paths[paths.length - 1]++; |
109 } else { | 109 } else { |
110 paths.push(pathIndex, depth, 1); | 110 paths.push(pathIndex, depth, 1); |
111 } | 111 } |
112 } | 112 } |
113 | 113 |
| 114 function findNextFrame(file, stack, stackPos, step, filter) { |
| 115 let codeId = -1; |
| 116 let code = null; |
| 117 while (stackPos >= 0 && stackPos < stack.length) { |
| 118 codeId = stack[stackPos]; |
| 119 code = codeId >= 0 ? file.code[codeId] : undefined; |
| 120 if (filter) { |
| 121 let type = code ? code.type : undefined; |
| 122 let kind = code ? code.kind : undefined; |
| 123 if (filter(type, kind)) return stackPos; |
| 124 } |
| 125 stackPos += step; |
| 126 } |
| 127 return -1; |
| 128 } |
| 129 |
| 130 function addOrUpdateChildNode(parent, file, stackIndex, stackPos, ascending) { |
| 131 let stack = file.ticks[stackIndex].s; |
| 132 let codeId = stack[stackPos]; |
| 133 let code = codeId >= 0 ? file.code[codeId] : undefined; |
| 134 if (stackPos === -1) { |
| 135 // We reached the end without finding the next step. |
| 136 // If we are doing top-down call tree, update own ticks. |
| 137 if (!ascending) { |
| 138 parent.ownTicks++; |
| 139 } |
| 140 } else { |
| 141 console.assert(stackPos >= 0 && stackPos < stack.length); |
| 142 // We found a child node. |
| 143 let childId = childIdFromCode(codeId, code); |
| 144 let child = parent.children[childId]; |
| 145 if (!child) { |
| 146 child = createNodeFromStackEntry(code); |
| 147 child.delayedExpansion = { frameList : [], ascending }; |
| 148 parent.children[childId] = child; |
| 149 } |
| 150 child.ticks++; |
| 151 addFrameToFrameList(child.delayedExpansion.frameList, stackIndex, stackPos); |
| 152 } |
| 153 } |
| 154 |
114 // This expands a tree node (direct children only). | 155 // This expands a tree node (direct children only). |
115 function expandTreeNode(file, node, filter) { | 156 function expandTreeNode(file, node, filter) { |
116 let { frameList, ascending } = node.delayedExpansion; | 157 let { frameList, ascending } = node.delayedExpansion; |
117 | 158 |
118 let step = ascending ? 2 : -2; | 159 let step = ascending ? 2 : -2; |
119 | 160 |
120 for (let i = 0; i < frameList.length; i+= 3) { | 161 for (let i = 0; i < frameList.length; i+= 3) { |
121 let stackIndex = frameList[i]; | 162 let firstStackIndex = frameList[i]; |
122 let depth = frameList[i + 1]; | 163 let depth = frameList[i + 1]; |
123 let count = frameList[i + 2]; | 164 let count = frameList[i + 2]; |
124 for (let j = 0; j < count; j++) { | 165 for (let j = 0; j < count; j++) { |
125 let tick = file.ticks[stackIndex + j]; | 166 let stackIndex = firstStackIndex + j; |
126 let stack = tick.s; | 167 let stack = file.ticks[stackIndex].s; |
127 | 168 |
128 // Get to the next frame that has not been filtered out. | 169 // Get to the next frame that has not been filtered out. |
129 let k = depth + step; | 170 let stackPos = findNextFrame(file, stack, depth + step, step, filter); |
130 let codeId = -1; | 171 addOrUpdateChildNode(node, file, stackIndex, stackPos, ascending); |
131 let code = null; | |
132 while (k >= 0 && k < stack.length) { | |
133 codeId = stack[k]; | |
134 code = codeId >= 0 ? file.code[codeId] : undefined; | |
135 if (filter) { | |
136 let type = code ? code.type : undefined; | |
137 let kind = code ? code.kind : undefined; | |
138 if (filter(type, kind)) break; | |
139 } | |
140 k += step; | |
141 } | |
142 if (k < 0 || k >= stack.length) { | |
143 // We reached the end without finding the next step. | |
144 // If we are doing top-down call tree, update own ticks. | |
145 if (!ascending) { | |
146 node.ownTicks++; | |
147 } | |
148 } else { | |
149 // We found a child node. | |
150 let childId = childIdFromCode(codeId, code); | |
151 let child = node.children[childId]; | |
152 if (!child) { | |
153 child = createNodeFromStackEntry(code); | |
154 child.delayedExpansion = { frameList : [], ascending }; | |
155 node.children[childId] = child; | |
156 } | |
157 child.ticks++; | |
158 addFrameToFrameList(child.delayedExpansion.frameList, stackIndex, k); | |
159 } | |
160 } | 172 } |
161 } | 173 } |
162 node.delayedExpansion = null; | 174 node.delayedExpansion = null; |
163 } | 175 } |
164 | 176 |
165 function addStackToTree(file, stack, tree, filter, ascending, start) { | |
166 if (start === undefined) { | |
167 start = ascending ? 0 : stack.length - 2; | |
168 } | |
169 tree.ticks++; | |
170 for (let i = start; | |
171 ascending ? (i < stack.length) : (i >= 0); | |
172 i += ascending ? 2 : -2) { | |
173 let codeId = stack[i]; | |
174 let code = codeId >= 0 ? file.code[codeId] : undefined; | |
175 if (filter) { | |
176 let type = code ? code.type : undefined; | |
177 let kind = code ? code.kind : undefined; | |
178 if (!filter(type, kind)) continue; | |
179 } | |
180 | |
181 // For JavaScript function, pretend there is one instance of optimized | |
182 // function and one instance of unoptimized function per SFI. | |
183 let childId = childIdFromCode(codeId, code); | |
184 let child = tree.children[childId]; | |
185 if (!child) { | |
186 child = createNodeFromStackEntry(code); | |
187 tree.children[childId] = child; | |
188 } | |
189 child.ticks++; | |
190 tree = child; | |
191 } | |
192 tree.ownTicks++; | |
193 } | |
194 | |
195 function createEmptyNode(name) { | 177 function createEmptyNode(name) { |
196 return { | 178 return { |
197 name : name, | 179 name : name, |
198 type : "CAT", | 180 type : "CAT", |
199 children : [], | 181 children : [], |
200 ownTicks : 0, | 182 ownTicks : 0, |
201 ticks : 0 | 183 ticks : 0 |
202 }; | 184 }; |
203 } | 185 } |
204 | 186 |
205 class PlainCallTreeProcessor { | 187 class PlainCallTreeProcessor { |
206 constructor(filter, isBottomUp) { | 188 constructor(filter, isBottomUp) { |
207 this.filter = filter; | 189 this.filter = filter; |
208 this.tree = createEmptyNode("root"); | 190 this.tree = createEmptyNode("root"); |
| 191 this.tree.delayedExpansion = { frameList : [], ascending : isBottomUp }; |
209 this.isBottomUp = isBottomUp; | 192 this.isBottomUp = isBottomUp; |
210 } | 193 } |
211 | 194 |
212 addStack(file, tickIndex) { | 195 addStack(file, tickIndex) { |
213 let stack = file.ticks[tickIndex].s; | 196 let stack = file.ticks[tickIndex].s; |
214 addStackToTree(file, stack, this.tree, this.filter, this.isBottomUp); | 197 let step = this.isBottomUp ? 2 : -2; |
| 198 let start = this.isBottomUp ? 0 : stack.length - 2; |
| 199 |
| 200 let stackPos = findNextFrame(file, stack, start, step, this.filter); |
| 201 addOrUpdateChildNode(this.tree, file, tickIndex, stackPos, this.isBottomUp); |
| 202 |
| 203 this.tree.ticks++; |
215 } | 204 } |
216 } | 205 } |
217 | 206 |
218 function buildCategoryTreeAndLookup() { | 207 function buildCategoryTreeAndLookup() { |
219 let root = createEmptyNode("root"); | 208 let root = createEmptyNode("root"); |
220 let categories = {}; | 209 let categories = {}; |
221 function addCategory(name, types) { | 210 function addCategory(name, types) { |
222 let n = createEmptyNode(name); | 211 let n = createEmptyNode(name); |
223 for (let i = 0; i < types.length; i++) { | 212 for (let i = 0; i < types.length; i++) { |
224 categories[types[i]] = n; | 213 categories[types[i]] = n; |
(...skipping 27 matching lines...) Expand all Loading... |
252 addStack(file, tickIndex) { | 241 addStack(file, tickIndex) { |
253 let stack = file.ticks[tickIndex].s; | 242 let stack = file.ticks[tickIndex].s; |
254 let vmState = file.ticks[tickIndex].vm; | 243 let vmState = file.ticks[tickIndex].vm; |
255 if (stack.length === 0) return; | 244 if (stack.length === 0) return; |
256 let codeId = stack[0]; | 245 let codeId = stack[0]; |
257 let code = codeId >= 0 ? file.code[codeId] : undefined; | 246 let code = codeId >= 0 ? file.code[codeId] : undefined; |
258 let kind = resolveCodeKindAndVmState(code, vmState); | 247 let kind = resolveCodeKindAndVmState(code, vmState); |
259 let node = this.categories[kind]; | 248 let node = this.categories[kind]; |
260 | 249 |
261 this.tree.ticks++; | 250 this.tree.ticks++; |
| 251 node.ticks++; |
262 | 252 |
263 console.assert(node); | 253 let step = this.isBottomUp ? 2 : -2; |
| 254 let start = this.isBottomUp ? 0 : stack.length - 2; |
264 | 255 |
265 addStackToTree(file, stack, node, this.filter, this.isBottomUp); | 256 let stackPos = findNextFrame(file, stack, start, step, this.filter); |
| 257 addOrUpdateChildNode(node, file, tickIndex, stackPos, this.isBottomUp); |
266 } | 258 } |
267 } | 259 } |
268 | 260 |
269 class FunctionListTree { | 261 class FunctionListTree { |
270 constructor(filter, withCategories) { | 262 constructor(filter, withCategories) { |
271 if (withCategories) { | 263 if (withCategories) { |
272 let { categories, root } = buildCategoryTreeAndLookup(); | 264 let { categories, root } = buildCategoryTreeAndLookup(); |
273 this.tree = root; | 265 this.tree = root; |
274 this.categories = categories; | 266 this.categories = categories; |
275 } else { | 267 } else { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 | 381 |
390 let tickCount = 0; | 382 let tickCount = 0; |
391 while (i < ticks.length && ticks[i].tm < endTime) { | 383 while (i < ticks.length && ticks[i].tm < endTime) { |
392 tree.addStack(file, i); | 384 tree.addStack(file, i); |
393 i++; | 385 i++; |
394 tickCount++; | 386 tickCount++; |
395 } | 387 } |
396 | 388 |
397 return tickCount; | 389 return tickCount; |
398 } | 390 } |
OLD | NEW |