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

Side by Side Diff: test/mjsunit/tools/profile.js

Issue 77014: Implemented Profile object that processes profiling events and calculates profiling data. (Closed)
Patch Set: addressed Soeren's comments Created 11 years, 8 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 | « no previous file | tools/codemap.js » ('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 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 // Load source code files from <project root>/tools.
29 // Files: tools/splaytree.js tools/codemap.js tools/profile.js
30
31
32 function stackToString(stack) {
33 return stack.join(' -> ');
34 };
35
36
37 function assertPathExists(root, path, opt_message) {
38 var message = opt_message ? ' (' + opt_message + ')' : '';
39 assertNotNull(root.descendToChild(path, function(node, pos) {
40 assertNotNull(node,
41 stackToString(path.slice(0, pos)) + ' has no child ' +
42 path[pos] + message);
43 }), opt_message);
44 };
45
46
47 function assertNoPathExists(root, path, opt_message) {
48 var message = opt_message ? ' (' + opt_message + ')' : '';
49 assertNull(root.descendToChild(path), opt_message);
50 };
51
52
53 function countNodes(profile, traverseFunc) {
54 var count = 0;
55 traverseFunc.call(profile, function () { count++; });
56 return count;
57 };
58
59
60 function ProfileTestDriver() {
61 this.profile = new devtools.profiler.Profile();
62 this.stack_ = [];
63 this.addFunctions_();
64 };
65
66
67 // Addresses inside functions.
68 ProfileTestDriver.prototype.funcAddrs_ = {
69 'lib1-f1': 0x11110, 'lib1-f2': 0x11210,
70 'lib2-f1': 0x21110, 'lib2-f2': 0x21210,
71 'T: F1': 0x50110, 'T: F2': 0x50210, 'T: F3': 0x50410 };
72
73
74 ProfileTestDriver.prototype.addFunctions_ = function() {
75 this.profile.addStaticCode('lib1', 0x11000, 0x12000);
76 this.profile.addStaticCode('lib1-f1', 0x11100, 0x11900);
77 this.profile.addStaticCode('lib1-f2', 0x11200, 0x11500);
78 this.profile.addStaticCode('lib2', 0x21000, 0x22000);
79 this.profile.addStaticCode('lib2-f1', 0x21100, 0x21900);
80 this.profile.addStaticCode('lib2-f2', 0x21200, 0x21500);
81 this.profile.addCode('T', 'F1', 0x50100, 0x100);
82 this.profile.addCode('T', 'F2', 0x50200, 0x100);
83 this.profile.addCode('T', 'F3', 0x50400, 0x100);
84 };
85
86
87 ProfileTestDriver.prototype.enter = function(funcName) {
88 // Stack looks like this: [pc, caller, ..., main].
89 // Therefore, we are adding entries at the beginning.
90 this.stack_.unshift(this.funcAddrs_[funcName]);
91 this.profile.recordTick(this.stack_);
92 };
93
94
95 ProfileTestDriver.prototype.stay = function() {
96 this.profile.recordTick(this.stack_);
97 };
98
99
100 ProfileTestDriver.prototype.leave = function() {
101 this.stack_.shift();
102 };
103
104
105 ProfileTestDriver.prototype.execute = function() {
106 this.enter('lib1-f1');
107 this.enter('lib1-f2');
108 this.enter('T: F1');
109 this.enter('T: F2');
110 this.leave();
111 this.stay();
112 this.enter('lib2-f1');
113 this.enter('lib2-f1');
114 this.leave();
115 this.stay();
116 this.leave();
117 this.enter('T: F3');
118 this.enter('T: F3');
119 this.enter('T: F3');
120 this.leave();
121 this.enter('T: F2');
122 this.stay();
123 this.leave();
124 this.leave();
125 this.leave();
126 this.leave();
127 this.stay();
128 this.leave();
129 };
130
131
132 function Inherits(childCtor, parentCtor) {
133 function tempCtor() {};
134 tempCtor.prototype = parentCtor.prototype;
135 childCtor.superClass_ = parentCtor.prototype;
136 childCtor.prototype = new tempCtor();
137 childCtor.prototype.constructor = childCtor;
138 };
139
140
141 (function testCallTreeBuilding() {
142 function Driver() {
143 ProfileTestDriver.call(this);
144 this.namesTopDown = [];
145 this.namesBottomUp = [];
146 };
147 Inherits(Driver, ProfileTestDriver);
148
149 Driver.prototype.enter = function(func) {
150 this.namesTopDown.push(func);
151 this.namesBottomUp.unshift(func);
152 assertNoPathExists(this.profile.getTopDownTreeRoot(), this.namesTopDown,
153 'pre enter/topDown');
154 assertNoPathExists(this.profile.getBottomUpTreeRoot(), this.namesBottomUp,
155 'pre enter/bottomUp');
156 Driver.superClass_.enter.call(this, func);
157 assertPathExists(this.profile.getTopDownTreeRoot(), this.namesTopDown,
158 'post enter/topDown');
159 assertPathExists(this.profile.getBottomUpTreeRoot(), this.namesBottomUp,
160 'post enter/bottomUp');
161 };
162
163 Driver.prototype.stay = function() {
164 var preTopDownNodes = countNodes(this.profile, this.profile.traverseTopDownT ree);
165 var preBottomUpNodes = countNodes(this.profile, this.profile.traverseBottomU pTree);
166 Driver.superClass_.stay.call(this);
167 var postTopDownNodes = countNodes(this.profile, this.profile.traverseTopDown Tree);
168 var postBottomUpNodes = countNodes(this.profile, this.profile.traverseBottom UpTree);
169 // Must be no changes in tree layout.
170 assertEquals(preTopDownNodes, postTopDownNodes, 'stay/topDown');
171 assertEquals(preBottomUpNodes, postBottomUpNodes, 'stay/bottomUp');
172 };
173
174 Driver.prototype.leave = function() {
175 Driver.superClass_.leave.call(this);
176 this.namesTopDown.pop();
177 this.namesBottomUp.shift();
178 };
179
180 var testDriver = new Driver();
181 testDriver.execute();
182 })();
183
184
185 function assertNodeWeights(root, path, selfTicks, totalTicks) {
186 var node = root.descendToChild(path);
187 var stack = stackToString(path);
188 assertNotNull(node, 'node not found: ' + stack);
189 assertEquals(selfTicks, node.selfWeight, 'self of ' + stack);
190 assertEquals(totalTicks, node.totalWeight, 'total of ' + stack);
191 };
192
193
194 (function testTopDownRootProfileTicks() {
195 var testDriver = new ProfileTestDriver();
196 testDriver.execute();
197
198 var pathWeights = [
199 [['lib1-f1'], 1, 14],
200 [['lib1-f1', 'lib1-f2'], 2, 13],
201 [['lib1-f1', 'lib1-f2', 'T: F1'], 2, 11],
202 [['lib1-f1', 'lib1-f2', 'T: F1', 'T: F2'], 1, 1],
203 [['lib1-f1', 'lib1-f2', 'T: F1', 'lib2-f1'], 2, 3],
204 [['lib1-f1', 'lib1-f2', 'T: F1', 'lib2-f1', 'lib2-f1'], 1, 1],
205 [['lib1-f1', 'lib1-f2', 'T: F1', 'T: F3'], 1, 5],
206 [['lib1-f1', 'lib1-f2', 'T: F1', 'T: F3', 'T: F3'], 1, 4],
207 [['lib1-f1', 'lib1-f2', 'T: F1', 'T: F3', 'T: F3', 'T: F3'], 1, 1],
208 [['lib1-f1', 'lib1-f2', 'T: F1', 'T: F3', 'T: F3', 'T: F2'], 2, 2]
209 ];
210
211 var root = testDriver.profile.getTopDownTreeRoot();
212 for (var i = 0; i < pathWeights.length; ++i) {
213 var data = pathWeights[i];
214 assertNodeWeights(root, data[0], data[1], data[2]);
215 }
216 })();
217
218
219 (function testRootFlatProfileTicks() {
220 function Driver() {
221 ProfileTestDriver.call(this);
222 this.namesTopDown = [''];
223 this.counters = {};
224 };
225 Inherits(Driver, ProfileTestDriver);
226
227 Driver.prototype.increment = function(func, self, total) {
228 if (!(func in this.counters)) {
229 this.counters[func] = { self: 0, total: 0 };
230 }
231 this.counters[func].self += self;
232 this.counters[func].total += total;
233 };
234
235 Driver.prototype.incrementTotals = function() {
236 // Only count each function in the stack once.
237 var met = {};
238 for (var i = 0; i < this.namesTopDown.length; ++i) {
239 var name = this.namesTopDown[i];
240 if (!(name in met)) {
241 this.increment(name, 0, 1);
242 }
243 met[name] = true;
244 }
245 };
246
247 Driver.prototype.enter = function(func) {
248 Driver.superClass_.enter.call(this, func);
249 this.namesTopDown.push(func);
250 this.increment(func, 1, 0);
251 this.incrementTotals();
252 };
253
254 Driver.prototype.stay = function() {
255 Driver.superClass_.stay.call(this);
256 this.increment(this.namesTopDown[this.namesTopDown.length - 1], 1, 0);
257 this.incrementTotals();
258 };
259
260 Driver.prototype.leave = function() {
261 Driver.superClass_.leave.call(this);
262 this.namesTopDown.pop();
263 };
264
265 var testDriver = new Driver();
266 testDriver.execute();
267
268 var counted = 0;
269 for (var c in testDriver.counters) {
270 counted++;
271 }
272
273 var flatProfile = testDriver.profile.getFlatProfile();
274 assertEquals(counted, flatProfile.length, 'counted vs. flatProfile');
275 for (var i = 0; i < flatProfile.length; ++i) {
276 var rec = flatProfile[i];
277 assertTrue(rec.label in testDriver.counters, 'uncounted: ' + rec.label);
278 var reference = testDriver.counters[rec.label];
279 assertEquals(reference.self, rec.selfWeight, 'self of ' + rec.label);
280 assertEquals(reference.total, rec.totalWeight, 'total of ' + rec.label);
281 }
282
283 })();
OLDNEW
« no previous file with comments | « no previous file | tools/codemap.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698