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

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

Issue 2696903002: [profiler] Graphical front-end for tick processor. (Closed)
Patch Set: Fix test 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
« no previous file with comments | « tools/profview/index.html ('k') | tools/profview/profview.css » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 "use strict"
6
7 let codeKinds = [
8 "UNKNOWN",
9 "CPPCOMP",
10 "CPPGC",
11 "CPPEXT",
12 "CPP",
13 "LIB",
14 "IC",
15 "BC",
16 "STUB",
17 "BUILTIN",
18 "REGEXP",
19 "JSOPT",
20 "JSUNOPT"
21 ];
22
23 function resolveCodeKind(code) {
24 if (!code || !code.type) {
25 return "UNKNOWN";
26 } else if (code.type === "CPP") {
27 return "CPP";
28 } else if (code.type === "SHARED_LIB") {
29 return "LIB";
30 } else if (code.type === "CODE") {
31 if (code.kind === "LoadIC" ||
32 code.kind === "StoreIC" ||
33 code.kind === "KeyedStoreIC" ||
34 code.kind === "KeyedLoadIC" ||
35 code.kind === "LoadGlobalIC" ||
36 code.kind === "Handler") {
37 return "IC";
38 } else if (code.kind === "BytecodeHandler") {
39 return "BC";
40 } else if (code.kind === "Stub") {
41 return "STUB";
42 } else if (code.kind === "Builtin") {
43 return "BUILTIN";
44 } else if (code.kind === "RegExp") {
45 return "REGEXP";
46 }
47 console.log("Unknown CODE: '" + code.kind + "'.");
48 return "CODE";
49 } else if (code.type === "JS") {
50 if (code.kind === "Builtin") {
51 return "JSUNOPT";
52 } else if (code.kind === "Opt") {
53 return "JSOPT";
54 } else if (code.kind === "Unopt") {
55 return "JSUNOPT";
56 }
57 }
58 console.log("Unknown code type '" + type + "'.");
59 }
60
61 function resolveCodeKindAndVmState(code, vmState) {
62 let kind = resolveCodeKind(code);
63 if (kind === "CPP") {
64 if (vmState === 1) {
65 kind = "CPPGC";
66 } else if (vmState === 2) {
67 kind = "CPPCOMP";
68 } else if (vmState === 4) {
69 kind = "CPPEXT";
70 }
71 }
72 return kind;
73 }
74
75 function createNodeFromStackEntry(code) {
76 let name = code ? code.name : "UNKNOWN";
77
78 return { name, type : resolveCodeKind(code),
79 children : [], ownTicks : 0, ticks : 0 };
80 }
81
82 function addStackToTree(file, stack, tree, filter, ascending, start) {
83 if (start === undefined) {
84 start = ascending ? 0 : stack.length - 2;
85 }
86 tree.ticks++;
87 for (let i = start;
88 ascending ? (i < stack.length) : (i >= 0);
89 i += ascending ? 2 : -2) {
90 let codeId = stack[i];
91 let code = codeId >= 0 ? file.code[codeId] : undefined;
92 if (filter) {
93 let type = code ? code.type : undefined;
94 let kind = code ? code.kind : undefined;
95 if (!filter(type, kind)) continue;
96 }
97
98 // For JavaScript function, pretend there is one instance of optimized
99 // function and one instance of unoptimized function per SFI.
100 let type = resolveCodeKind(code);
101 let childId;
102 if (type === "JSOPT") {
103 childId = code.func * 4 + 1;
104 } else if (type === "JSUNOPT") {
105 childId = code.func * 4 + 2;
106 } else {
107 childId = codeId * 4;
108 }
109 let child = tree.children[childId];
110 if (!child) {
111 child = createNodeFromStackEntry(code);
112 tree.children[childId] = child;
113 }
114 child.ticks++;
115 tree = child;
116 }
117 tree.ownTicks++;
118 }
119
120 function createEmptyNode(name) {
121 return {
122 name : name,
123 type : "CAT",
124 children : [],
125 ownTicks : 0,
126 ticks : 0
127 };
128 }
129
130 class PlainCallTreeProcessor {
131 constructor(filter, isBottomUp) {
132 this.filter = filter;
133 this.tree = createEmptyNode("root");
134 this.isBottomUp = isBottomUp;
135 }
136
137 addStack(file, timestamp, vmState, stack) {
138 addStackToTree(file, stack, this.tree, this.filter, this.isBottomUp);
139 }
140 }
141
142 class CategorizedCallTreeProcessor {
143 constructor(filter, isBottomUp) {
144 this.filter = filter;
145 let root = createEmptyNode("root");
146 let categories = {};
147 function addCategory(name, types) {
148 let n = createEmptyNode(name);
149 for (let i = 0; i < types.length; i++) {
150 categories[types[i]] = n;
151 }
152 root.children.push(n);
153 }
154 addCategory("JS Optimized", [ "JSOPT" ]);
155 addCategory("JS Unoptimized", [ "JSUNOPT", "BC" ]);
156 addCategory("IC", [ "IC" ]);
157 addCategory("RegExp", [ "REGEXP" ]);
158 addCategory("Other generated", [ "STUB", "BUILTIN" ]);
159 addCategory("C++", [ "CPP", "LIB" ]);
160 addCategory("C++/GC", [ "CPPGC" ]);
161 addCategory("C++/Compiler", [ "CPPCOMP" ]);
162 addCategory("C++/External", [ "CPPEXT" ]);
163 addCategory("Unknown", [ "UNKNOWN" ]);
164
165 this.tree = root;
166 this.categories = categories;
167 this.isBottomUp = isBottomUp;
168 }
169
170 addStack(file, timestamp, vmState, stack) {
171 if (stack.length === 0) return;
172 let codeId = stack[0];
173 let code = codeId >= 0 ? file.code[codeId] : undefined;
174 let kind = resolveCodeKindAndVmState(code, vmState);
175 let node = this.categories[kind];
176
177 this.tree.ticks++;
178
179 console.assert(node);
180
181 addStackToTree(file, stack, node, this.filter, this.isBottomUp);
182 }
183 }
184
185 class FunctionListTree {
186 constructor(filter) {
187 this.tree = { name : "root", children : [], ownTicks : 0, ticks : 0 };
188 this.codeVisited = [];
189 this.filter = filter;
190 }
191
192 addStack(file, timestamp, vmState, stack) {
193 this.tree.ticks++;
194 let child = null;
195 for (let i = stack.length - 2; i >= 0; i -= 2) {
196 let codeId = stack[i];
197 if (codeId < 0 || this.codeVisited[codeId]) continue;
198
199 let code = codeId >= 0 ? file.code[codeId] : undefined;
200 if (this.filter) {
201 let type = code ? code.type : undefined;
202 let kind = code ? code.kind : undefined;
203 if (!this.filter(type, kind)) continue;
204 }
205 child = this.tree.children[codeId];
206 if (!child) {
207 child = createNodeFromStackEntry(code);
208 this.tree.children[codeId] = child;
209 }
210 child.ticks++;
211 this.codeVisited[codeId] = true;
212 }
213 if (child) {
214 child.ownTicks++;
215 }
216
217 for (let i = 0; i < stack.length; i += 2) {
218 let codeId = stack[i];
219 if (codeId >= 0) this.codeVisited[codeId] = false;
220 }
221 }
222 }
223
224
225 class CategorySampler {
226 constructor(file, bucketCount) {
227 this.bucketCount = bucketCount;
228
229 this.firstTime = file.ticks[0].tm;
230 let lastTime = file.ticks[file.ticks.length - 1].tm;
231 this.step = (lastTime - this.firstTime) / bucketCount;
232
233 this.buckets = [];
234 let bucket = {};
235 for (let i = 0; i < codeKinds.length; i++) {
236 bucket[codeKinds[i]] = 0;
237 }
238 for (let i = 0; i < bucketCount; i++) {
239 this.buckets.push(Object.assign({ total : 0 }, bucket));
240 }
241 }
242
243 addStack(file, timestamp, vmState, stack) {
244 let i = Math.floor((timestamp - this.firstTime) / this.step);
245 if (i == this.buckets.length) i--;
246 console.assert(i >= 0 && i < this.buckets.length);
247
248 let bucket = this.buckets[i];
249 bucket.total++;
250
251 let codeId = (stack.length > 0) ? stack[0] : -1;
252 let code = codeId >= 0 ? file.code[codeId] : undefined;
253 let kind = resolveCodeKindAndVmState(code, vmState);
254 bucket[kind]++;
255 }
256 }
257
258 // Generates a tree out of a ticks sequence.
259 // {file} is the JSON files with the ticks and code objects.
260 // {startTime}, {endTime} is the interval.
261 // {tree} is the processor of stacks.
262 function generateTree(
263 file, startTime, endTime, tree) {
264 let ticks = file.ticks;
265 let i = 0;
266 while (i < ticks.length && ticks[i].tm < startTime) {
267 i++;
268 }
269
270 let tickCount = 0;
271 while (i < ticks.length && ticks[i].tm < endTime) {
272 tree.addStack(file, ticks[i].tm, ticks[i].vm, ticks[i].s);
273 i++;
274 tickCount++;
275 }
276
277 return tickCount;
278 }
OLDNEW
« no previous file with comments | « tools/profview/index.html ('k') | tools/profview/profview.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698