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

Side by Side Diff: tools/tickprocessor.js

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 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 | Annotate | Revision Log
« no previous file with comments | « tools/splaytree.py ('k') | tools/tickprocessor.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 28
29 function Profile(separateIc) { 29 function inherits(childCtor, parentCtor) {
30 devtools.profiler.Profile.call(this); 30 childCtor.prototype.__proto__ = parentCtor.prototype;
31 };
32
33
34 function V8Profile(separateIc) {
35 Profile.call(this);
31 if (!separateIc) { 36 if (!separateIc) {
32 this.skipThisFunction = function(name) { return Profile.IC_RE.test(name); }; 37 this.skipThisFunction = function(name) { return V8Profile.IC_RE.test(name); };
33 } 38 }
34 }; 39 };
35 Profile.prototype = devtools.profiler.Profile.prototype; 40 inherits(V8Profile, Profile);
36 41
37 42
38 Profile.IC_RE = 43 V8Profile.IC_RE =
39 /^(?:CallIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Call|Load|Store)IC_)/; 44 /^(?:CallIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Call|Load|Store)IC_)/;
40 45
41 46
42 /** 47 /**
43 * A thin wrapper around shell's 'read' function showing a file name on error. 48 * A thin wrapper around shell's 'read' function showing a file name on error.
44 */ 49 */
45 function readFile(fileName) { 50 function readFile(fileName) {
46 try { 51 try {
47 return read(fileName); 52 return read(fileName);
48 } catch (e) { 53 } catch (e) {
49 print(fileName + ': ' + (e.message || e)); 54 print(fileName + ': ' + (e.message || e));
50 throw e; 55 throw e;
51 } 56 }
52 } 57 }
53 58
54 59
55 function inherits(childCtor, parentCtor) { 60 /**
56 childCtor.prototype.__proto__ = parentCtor.prototype; 61 * Parser for dynamic code optimization state.
57 }; 62 */
63 function parseState(s) {
64 switch (s) {
65 case "": return Profile.CodeState.COMPILED;
66 case "~": return Profile.CodeState.OPTIMIZABLE;
67 case "*": return Profile.CodeState.OPTIMIZED;
68 }
69 throw new Error("unknown code state: " + s);
70 }
58 71
59 72
60 function SnapshotLogProcessor() { 73 function SnapshotLogProcessor() {
61 devtools.profiler.LogReader.call(this, { 74 LogReader.call(this, {
62 'code-creation': { 75 'code-creation': {
63 parsers: [null, parseInt, parseInt, null], 76 parsers: [null, parseInt, parseInt, null, 'var-args'],
64 processor: this.processCodeCreation }, 77 processor: this.processCodeCreation },
65 'code-move': { parsers: [parseInt, parseInt], 78 'code-move': { parsers: [parseInt, parseInt],
66 processor: this.processCodeMove }, 79 processor: this.processCodeMove },
67 'code-delete': { parsers: [parseInt], 80 'code-delete': { parsers: [parseInt],
68 processor: this.processCodeDelete }, 81 processor: this.processCodeDelete },
69 'function-creation': null, 82 'function-creation': null,
70 'function-move': null, 83 'function-move': null,
71 'function-delete': null, 84 'function-delete': null,
85 'sfi-move': null,
72 'snapshot-pos': { parsers: [parseInt, parseInt], 86 'snapshot-pos': { parsers: [parseInt, parseInt],
73 processor: this.processSnapshotPosition }}); 87 processor: this.processSnapshotPosition }});
74 88
75 Profile.prototype.handleUnknownCode = function(operation, addr) { 89 V8Profile.prototype.handleUnknownCode = function(operation, addr) {
76 var op = devtools.profiler.Profile.Operation; 90 var op = Profile.Operation;
77 switch (operation) { 91 switch (operation) {
78 case op.MOVE: 92 case op.MOVE:
79 print('Snapshot: Code move event for unknown code: 0x' + 93 print('Snapshot: Code move event for unknown code: 0x' +
80 addr.toString(16)); 94 addr.toString(16));
81 break; 95 break;
82 case op.DELETE: 96 case op.DELETE:
83 print('Snapshot: Code delete event for unknown code: 0x' + 97 print('Snapshot: Code delete event for unknown code: 0x' +
84 addr.toString(16)); 98 addr.toString(16));
85 break; 99 break;
86 } 100 }
87 }; 101 };
88 102
89 this.profile_ = new Profile(); 103 this.profile_ = new V8Profile();
90 this.serializedEntries_ = []; 104 this.serializedEntries_ = [];
91 } 105 }
92 inherits(SnapshotLogProcessor, devtools.profiler.LogReader); 106 inherits(SnapshotLogProcessor, LogReader);
93 107
94 108
95 SnapshotLogProcessor.prototype.processCodeCreation = function( 109 SnapshotLogProcessor.prototype.processCodeCreation = function(
96 type, start, size, name) { 110 type, start, size, name, maybe_func) {
97 var entry = this.profile_.addCode(type, name, start, size); 111 if (maybe_func.length) {
112 var funcAddr = parseInt(maybe_func[0]);
113 var state = parseState(maybe_func[1]);
114 this.profile_.addFuncCode(type, name, start, size, funcAddr, state);
115 } else {
116 this.profile_.addCode(type, name, start, size);
117 }
98 }; 118 };
99 119
100 120
101 SnapshotLogProcessor.prototype.processCodeMove = function(from, to) { 121 SnapshotLogProcessor.prototype.processCodeMove = function(from, to) {
102 this.profile_.moveCode(from, to); 122 this.profile_.moveCode(from, to);
103 }; 123 };
104 124
105 125
106 SnapshotLogProcessor.prototype.processCodeDelete = function(start) { 126 SnapshotLogProcessor.prototype.processCodeDelete = function(start) {
107 this.profile_.deleteCode(start); 127 this.profile_.deleteCode(start);
(...skipping 12 matching lines...) Expand all
120 140
121 141
122 SnapshotLogProcessor.prototype.getSerializedEntryName = function(pos) { 142 SnapshotLogProcessor.prototype.getSerializedEntryName = function(pos) {
123 var entry = this.serializedEntries_[pos]; 143 var entry = this.serializedEntries_[pos];
124 return entry ? entry.getRawName() : null; 144 return entry ? entry.getRawName() : null;
125 }; 145 };
126 146
127 147
128 function TickProcessor( 148 function TickProcessor(
129 cppEntriesProvider, separateIc, ignoreUnknown, stateFilter, snapshotLogProce ssor) { 149 cppEntriesProvider, separateIc, ignoreUnknown, stateFilter, snapshotLogProce ssor) {
130 devtools.profiler.LogReader.call(this, { 150 LogReader.call(this, {
131 'shared-library': { parsers: [null, parseInt, parseInt], 151 'shared-library': { parsers: [null, parseInt, parseInt],
132 processor: this.processSharedLibrary }, 152 processor: this.processSharedLibrary },
133 'code-creation': { 153 'code-creation': {
134 parsers: [null, parseInt, parseInt, null], 154 parsers: [null, parseInt, parseInt, null, 'var-args'],
135 processor: this.processCodeCreation }, 155 processor: this.processCodeCreation },
136 'code-move': { parsers: [parseInt, parseInt], 156 'code-move': { parsers: [parseInt, parseInt],
137 processor: this.processCodeMove }, 157 processor: this.processCodeMove },
138 'code-delete': { parsers: [parseInt], 158 'code-delete': { parsers: [parseInt],
139 processor: this.processCodeDelete }, 159 processor: this.processCodeDelete },
140 'function-creation': { parsers: [parseInt, parseInt], 160 'sfi-move': { parsers: [parseInt, parseInt],
141 processor: this.processFunctionCreation },
142 'function-move': { parsers: [parseInt, parseInt],
143 processor: this.processFunctionMove }, 161 processor: this.processFunctionMove },
144 'function-delete': { parsers: [parseInt],
145 processor: this.processFunctionDelete },
146 'snapshot-pos': { parsers: [parseInt, parseInt], 162 'snapshot-pos': { parsers: [parseInt, parseInt],
147 processor: this.processSnapshotPosition }, 163 processor: this.processSnapshotPosition },
148 'tick': { parsers: [parseInt, parseInt, parseInt, parseInt, 'var-args'], 164 'tick': { parsers: [parseInt, parseInt, parseInt, parseInt, 'var-args'],
149 processor: this.processTick }, 165 processor: this.processTick },
150 'heap-sample-begin': { parsers: [null, null, parseInt], 166 'heap-sample-begin': { parsers: [null, null, parseInt],
151 processor: this.processHeapSampleBegin }, 167 processor: this.processHeapSampleBegin },
152 'heap-sample-end': { parsers: [null, null], 168 'heap-sample-end': { parsers: [null, null],
153 processor: this.processHeapSampleEnd }, 169 processor: this.processHeapSampleEnd },
154 'heap-js-prod-item': { parsers: [null, 'var-args'], 170 'heap-js-prod-item': { parsers: [null, 'var-args'],
155 processor: this.processJSProducer }, 171 processor: this.processJSProducer },
156 // Ignored events. 172 // Ignored events.
157 'profiler': null, 173 'profiler': null,
174 'function-creation': null,
175 'function-move': null,
176 'function-delete': null,
158 'heap-sample-stats': null, 177 'heap-sample-stats': null,
159 'heap-sample-item': null, 178 'heap-sample-item': null,
160 'heap-js-cons-item': null, 179 'heap-js-cons-item': null,
161 'heap-js-ret-item': null, 180 'heap-js-ret-item': null,
162 // Obsolete row types. 181 // Obsolete row types.
163 'code-allocate': null, 182 'code-allocate': null,
164 'begin-code-region': null, 183 'begin-code-region': null,
165 'end-code-region': null }); 184 'end-code-region': null });
166 185
167 this.cppEntriesProvider_ = cppEntriesProvider; 186 this.cppEntriesProvider_ = cppEntriesProvider;
168 this.ignoreUnknown_ = ignoreUnknown; 187 this.ignoreUnknown_ = ignoreUnknown;
169 this.stateFilter_ = stateFilter; 188 this.stateFilter_ = stateFilter;
170 this.snapshotLogProcessor_ = snapshotLogProcessor; 189 this.snapshotLogProcessor_ = snapshotLogProcessor;
171 this.deserializedEntriesNames_ = []; 190 this.deserializedEntriesNames_ = [];
172 var ticks = this.ticks_ = 191 var ticks = this.ticks_ =
173 { total: 0, unaccounted: 0, excluded: 0, gc: 0 }; 192 { total: 0, unaccounted: 0, excluded: 0, gc: 0 };
174 193
175 Profile.prototype.handleUnknownCode = function( 194 V8Profile.prototype.handleUnknownCode = function(
176 operation, addr, opt_stackPos) { 195 operation, addr, opt_stackPos) {
177 var op = devtools.profiler.Profile.Operation; 196 var op = Profile.Operation;
178 switch (operation) { 197 switch (operation) {
179 case op.MOVE: 198 case op.MOVE:
180 print('Code move event for unknown code: 0x' + addr.toString(16)); 199 print('Code move event for unknown code: 0x' + addr.toString(16));
181 break; 200 break;
182 case op.DELETE: 201 case op.DELETE:
183 print('Code delete event for unknown code: 0x' + addr.toString(16)); 202 print('Code delete event for unknown code: 0x' + addr.toString(16));
184 break; 203 break;
185 case op.TICK: 204 case op.TICK:
186 // Only unknown PCs (the first frame) are reported as unaccounted, 205 // Only unknown PCs (the first frame) are reported as unaccounted,
187 // otherwise tick balance will be corrupted (this behavior is compatible 206 // otherwise tick balance will be corrupted (this behavior is compatible
188 // with the original tickprocessor.py script.) 207 // with the original tickprocessor.py script.)
189 if (opt_stackPos == 0) { 208 if (opt_stackPos == 0) {
190 ticks.unaccounted++; 209 ticks.unaccounted++;
191 } 210 }
192 break; 211 break;
193 } 212 }
194 }; 213 };
195 214
196 this.profile_ = new Profile(separateIc); 215 this.profile_ = new V8Profile(separateIc);
197 this.codeTypes_ = {}; 216 this.codeTypes_ = {};
198 // Count each tick as a time unit. 217 // Count each tick as a time unit.
199 this.viewBuilder_ = new devtools.profiler.ViewBuilder(1); 218 this.viewBuilder_ = new ViewBuilder(1);
200 this.lastLogFileName_ = null; 219 this.lastLogFileName_ = null;
201 220
202 this.generation_ = 1; 221 this.generation_ = 1;
203 this.currentProducerProfile_ = null; 222 this.currentProducerProfile_ = null;
204 }; 223 };
205 inherits(TickProcessor, devtools.profiler.LogReader); 224 inherits(TickProcessor, LogReader);
206 225
207 226
208 TickProcessor.VmStates = { 227 TickProcessor.VmStates = {
209 JS: 0, 228 JS: 0,
210 GC: 1, 229 GC: 1,
211 COMPILER: 2, 230 COMPILER: 2,
212 OTHER: 3, 231 OTHER: 3,
213 EXTERNAL: 4 232 EXTERNAL: 4
214 }; 233 };
215 234
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 var self = this; 297 var self = this;
279 var libFuncs = this.cppEntriesProvider_.parseVmSymbols( 298 var libFuncs = this.cppEntriesProvider_.parseVmSymbols(
280 name, startAddr, endAddr, function(fName, fStart, fEnd) { 299 name, startAddr, endAddr, function(fName, fStart, fEnd) {
281 self.profile_.addStaticCode(fName, fStart, fEnd); 300 self.profile_.addStaticCode(fName, fStart, fEnd);
282 self.setCodeType(fName, 'CPP'); 301 self.setCodeType(fName, 'CPP');
283 }); 302 });
284 }; 303 };
285 304
286 305
287 TickProcessor.prototype.processCodeCreation = function( 306 TickProcessor.prototype.processCodeCreation = function(
288 type, start, size, name) { 307 type, start, size, name, maybe_func) {
289 name = this.deserializedEntriesNames_[start] || name; 308 name = this.deserializedEntriesNames_[start] || name;
290 var entry = this.profile_.addCode(type, name, start, size); 309 if (maybe_func.length) {
310 var funcAddr = parseInt(maybe_func[0]);
311 var state = parseState(maybe_func[1]);
312 this.profile_.addFuncCode(type, name, start, size, funcAddr, state);
313 } else {
314 this.profile_.addCode(type, name, start, size);
315 }
291 }; 316 };
292 317
293 318
294 TickProcessor.prototype.processCodeMove = function(from, to) { 319 TickProcessor.prototype.processCodeMove = function(from, to) {
295 this.profile_.moveCode(from, to); 320 this.profile_.moveCode(from, to);
296 }; 321 };
297 322
298 323
299 TickProcessor.prototype.processCodeDelete = function(start) { 324 TickProcessor.prototype.processCodeDelete = function(start) {
300 this.profile_.deleteCode(start); 325 this.profile_.deleteCode(start);
301 }; 326 };
302 327
303 328
304 TickProcessor.prototype.processFunctionCreation = function(
305 functionAddr, codeAddr) {
306 this.profile_.addCodeAlias(functionAddr, codeAddr);
307 };
308
309
310 TickProcessor.prototype.processFunctionMove = function(from, to) { 329 TickProcessor.prototype.processFunctionMove = function(from, to) {
311 this.profile_.safeMoveDynamicCode(from, to); 330 this.profile_.moveFunc(from, to);
312 };
313
314
315 TickProcessor.prototype.processFunctionDelete = function(start) {
316 this.profile_.safeDeleteDynamicCode(start);
317 }; 331 };
318 332
319 333
320 TickProcessor.prototype.processSnapshotPosition = function(addr, pos) { 334 TickProcessor.prototype.processSnapshotPosition = function(addr, pos) {
321 if (this.snapshotLogProcessor_) { 335 if (this.snapshotLogProcessor_) {
322 this.deserializedEntriesNames_[addr] = 336 this.deserializedEntriesNames_[addr] =
323 this.snapshotLogProcessor_.getSerializedEntryName(pos); 337 this.snapshotLogProcessor_.getSerializedEntryName(pos);
324 } 338 }
325 }; 339 };
326 340
327 341
328 TickProcessor.prototype.includeTick = function(vmState) { 342 TickProcessor.prototype.includeTick = function(vmState) {
329 return this.stateFilter_ == null || this.stateFilter_ == vmState; 343 return this.stateFilter_ == null || this.stateFilter_ == vmState;
330 }; 344 };
331 345
332 346
333 TickProcessor.prototype.processTick = function(pc, sp, func, vmState, stack) { 347 TickProcessor.prototype.processTick = function(pc, sp, tos, vmState, stack) {
334 this.ticks_.total++; 348 this.ticks_.total++;
335 if (vmState == TickProcessor.VmStates.GC) this.ticks_.gc++; 349 if (vmState == TickProcessor.VmStates.GC) this.ticks_.gc++;
336 if (!this.includeTick(vmState)) { 350 if (!this.includeTick(vmState)) {
337 this.ticks_.excluded++; 351 this.ticks_.excluded++;
338 return; 352 return;
339 } 353 }
340 354
341 if (func) { 355 if (tos) {
342 var funcEntry = this.profile_.findEntry(func); 356 var funcEntry = this.profile_.findEntry(tos);
343 if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction()) { 357 if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction()) {
344 func = 0; 358 tos = 0;
345 } else {
346 var currEntry = this.profile_.findEntry(pc);
347 if (!currEntry || !currEntry.isJSFunction || currEntry.isJSFunction()) {
348 func = 0;
349 }
350 } 359 }
351 } 360 }
352 361
353 this.profile_.recordTick(this.processStack(pc, func, stack)); 362 this.profile_.recordTick(this.processStack(pc, tos, stack));
354 }; 363 };
355 364
356 365
357 TickProcessor.prototype.processHeapSampleBegin = function(space, state, ticks) { 366 TickProcessor.prototype.processHeapSampleBegin = function(space, state, ticks) {
358 if (space != 'Heap') return; 367 if (space != 'Heap') return;
359 this.currentProducerProfile_ = new devtools.profiler.CallTree(); 368 this.currentProducerProfile_ = new CallTree();
360 }; 369 };
361 370
362 371
363 TickProcessor.prototype.processHeapSampleEnd = function(space, state) { 372 TickProcessor.prototype.processHeapSampleEnd = function(space, state) {
364 if (space != 'Heap' || !this.currentProducerProfile_) return; 373 if (space != 'Heap' || !this.currentProducerProfile_) return;
365 374
366 print('Generation ' + this.generation_ + ':'); 375 print('Generation ' + this.generation_ + ':');
367 var tree = this.currentProducerProfile_; 376 var tree = this.currentProducerProfile_;
368 tree.computeTotalWeights(); 377 tree.computeTotalWeights();
369 var producersView = this.viewBuilder_.buildView(tree); 378 var producersView = this.viewBuilder_.buildView(tree);
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 if (arg !== synArg && dispatch === this.argsDispatch_[synArg]) { 854 if (arg !== synArg && dispatch === this.argsDispatch_[synArg]) {
846 synonims.push(synArg); 855 synonims.push(synArg);
847 delete this.argsDispatch_[synArg]; 856 delete this.argsDispatch_[synArg];
848 } 857 }
849 } 858 }
850 print(' ' + padRight(synonims.join(', '), 20) + dispatch[2]); 859 print(' ' + padRight(synonims.join(', '), 20) + dispatch[2]);
851 } 860 }
852 quit(2); 861 quit(2);
853 }; 862 };
854 863
OLDNEW
« no previous file with comments | « tools/splaytree.py ('k') | tools/tickprocessor.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698