OLD | NEW |
1 # Copyright 2008 the V8 project authors. All rights reserved. | 1 # Copyright 2008 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 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 self.pending_assemblers = {} | 149 self.pending_assemblers = {} |
150 # Map from code addresses the have been allocated but not yet officially | 150 # Map from code addresses the have been allocated but not yet officially |
151 # created to their assemblers. | 151 # created to their assemblers. |
152 self.assemblers = {} | 152 self.assemblers = {} |
153 self.js_entries = splaytree.SplayTree() | 153 self.js_entries = splaytree.SplayTree() |
154 self.cpp_entries = splaytree.SplayTree() | 154 self.cpp_entries = splaytree.SplayTree() |
155 self.total_number_of_ticks = 0 | 155 self.total_number_of_ticks = 0 |
156 self.number_of_library_ticks = 0 | 156 self.number_of_library_ticks = 0 |
157 self.unaccounted_number_of_ticks = 0 | 157 self.unaccounted_number_of_ticks = 0 |
158 self.excluded_number_of_ticks = 0 | 158 self.excluded_number_of_ticks = 0 |
| 159 # Flag indicating whether to ignore unaccounted ticks in the report |
| 160 self.ignore_unknown = False |
159 | 161 |
160 def ProcessLogfile(self, filename, included_state = None): | 162 def ProcessLogfile(self, filename, included_state = None, ignore_unknown = Fal
se): |
161 self.log_file = filename | 163 self.log_file = filename |
162 self.included_state = included_state | 164 self.included_state = included_state |
| 165 self.ignore_unknown = ignore_unknown |
| 166 |
163 try: | 167 try: |
164 logfile = open(filename, 'rb') | 168 logfile = open(filename, 'rb') |
165 except IOError: | 169 except IOError: |
166 sys.exit("Could not open logfile: " + filename) | 170 sys.exit("Could not open logfile: " + filename) |
167 try: | 171 try: |
168 logreader = csv.reader(logfile) | 172 logreader = csv.reader(logfile) |
169 for row in logreader: | 173 for row in logreader: |
170 if row[0] == 'tick': | 174 if row[0] == 'tick': |
171 self.ProcessTick(int(row[1], 16), int(row[2], 16), int(row[3]), row[4:
]) | 175 self.ProcessTick(int(row[1], 16), int(row[2], 16), int(row[3]), row[4:
]) |
172 elif row[0] == 'code-creation': | 176 elif row[0] == 'code-creation': |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 def FindEntry(self, pc): | 250 def FindEntry(self, pc): |
247 page = pc >> 12 | 251 page = pc >> 12 |
248 if page in self.vm_extent: | 252 if page in self.vm_extent: |
249 entry = self.cpp_entries.FindGreatestsLessThan(pc) | 253 entry = self.cpp_entries.FindGreatestsLessThan(pc) |
250 if entry != None: | 254 if entry != None: |
251 return entry.value | 255 return entry.value |
252 else: | 256 else: |
253 return entry | 257 return entry |
254 max = self.js_entries.FindMax() | 258 max = self.js_entries.FindMax() |
255 min = self.js_entries.FindMin() | 259 min = self.js_entries.FindMin() |
256 if max != None and pc < max.key and pc > min.key: | 260 if max != None and pc < (max.key + max.value.size) and pc > min.key: |
257 return self.js_entries.FindGreatestsLessThan(pc).value | 261 return self.js_entries.FindGreatestsLessThan(pc).value |
258 return None | 262 return None |
259 | 263 |
260 def ProcessStack(self, stack): | 264 def ProcessStack(self, stack): |
261 result = [] | 265 result = [] |
262 for frame in stack: | 266 for frame in stack: |
263 if frame.startswith('0x'): | 267 if frame.startswith('0x'): |
264 entry = self.FindEntry(int(frame, 16)) | 268 entry = self.FindEntry(int(frame, 16)) |
265 if entry != None: | 269 if entry != None: |
266 result.append(entry.ToString()) | 270 result.append(entry.ToString()) |
(...skipping 15 matching lines...) Expand all Loading... |
282 def PrintResults(self): | 286 def PrintResults(self): |
283 print('Statistical profiling result from %s, (%d ticks, %d unaccounted, %d e
xcluded).' % | 287 print('Statistical profiling result from %s, (%d ticks, %d unaccounted, %d e
xcluded).' % |
284 (self.log_file, | 288 (self.log_file, |
285 self.total_number_of_ticks, | 289 self.total_number_of_ticks, |
286 self.unaccounted_number_of_ticks, | 290 self.unaccounted_number_of_ticks, |
287 self.excluded_number_of_ticks)) | 291 self.excluded_number_of_ticks)) |
288 if self.total_number_of_ticks > 0: | 292 if self.total_number_of_ticks > 0: |
289 js_entries = self.js_entries.ExportValueList() | 293 js_entries = self.js_entries.ExportValueList() |
290 js_entries.extend(self.deleted_code) | 294 js_entries.extend(self.deleted_code) |
291 cpp_entries = self.cpp_entries.ExportValueList() | 295 cpp_entries = self.cpp_entries.ExportValueList() |
| 296 # Print the unknown ticks percentage if they are not ignored. |
| 297 if not self.ignore_unknown and self.unaccounted_number_of_ticks > 0: |
| 298 self.PrintHeader('Unknown') |
| 299 unknown_percentage = self.unaccounted_number_of_ticks * 100.0 / self.tot
al_number_of_ticks |
| 300 print(' %(total)5.1f%%' % { |
| 301 'total' : unknown_percentage, |
| 302 }) |
292 # Print the library ticks. | 303 # Print the library ticks. |
293 self.PrintHeader('Shared libraries') | 304 self.PrintHeader('Shared libraries') |
294 self.PrintEntries(cpp_entries, lambda e:e.IsSharedLibraryEntry()) | 305 self.PrintEntries(cpp_entries, lambda e:e.IsSharedLibraryEntry()) |
295 # Print the JavaScript ticks. | 306 # Print the JavaScript ticks. |
296 self.PrintHeader('JavaScript') | 307 self.PrintHeader('JavaScript') |
297 self.PrintEntries(js_entries, lambda e:not e.IsSharedLibraryEntry()) | 308 self.PrintEntries(js_entries, lambda e:not e.IsSharedLibraryEntry()) |
298 # Print the C++ ticks. | 309 # Print the C++ ticks. |
299 self.PrintHeader('C++') | 310 self.PrintHeader('C++') |
300 self.PrintEntries(cpp_entries, lambda e:not e.IsSharedLibraryEntry()) | 311 self.PrintEntries(cpp_entries, lambda e:not e.IsSharedLibraryEntry()) |
301 # Print call profile. | 312 # Print call profile. |
302 print('\n [Call profile]:') | 313 print('\n [Call profile]:') |
303 print(' total call path') | 314 print(' total call path') |
304 js_entries.extend(cpp_entries) | 315 js_entries.extend(cpp_entries) |
305 self.PrintCallProfile(js_entries) | 316 self.PrintCallProfile(js_entries) |
306 | 317 |
307 def PrintHeader(self, header_title): | 318 def PrintHeader(self, header_title): |
308 print('\n [%s]:' % header_title) | 319 print('\n [%s]:' % header_title) |
309 print(' total nonlib name') | 320 print(' total nonlib name') |
310 | 321 |
311 def PrintEntries(self, entries, condition): | 322 def PrintEntries(self, entries, condition): |
312 number_of_accounted_ticks = self.total_number_of_ticks - self.unaccounted_nu
mber_of_ticks | 323 # If ignoring unaccounted ticks don't include these in percentage |
| 324 # calculations |
| 325 number_of_accounted_ticks = self.total_number_of_ticks |
| 326 if self.ignore_unknown: |
| 327 number_of_accounted_ticks -= self.unaccounted_number_of_ticks |
| 328 |
313 number_of_non_library_ticks = number_of_accounted_ticks - self.number_of_lib
rary_ticks | 329 number_of_non_library_ticks = number_of_accounted_ticks - self.number_of_lib
rary_ticks |
314 entries.sort(key=lambda e:e.tick_count, reverse=True) | 330 entries.sort(key=lambda e:e.tick_count, reverse=True) |
315 for entry in entries: | 331 for entry in entries: |
316 if entry.tick_count > 0 and condition(entry): | 332 if entry.tick_count > 0 and condition(entry): |
317 total_percentage = entry.tick_count * 100.0 / number_of_accounted_ticks | 333 total_percentage = entry.tick_count * 100.0 / number_of_accounted_ticks |
318 if entry.IsSharedLibraryEntry(): | 334 if entry.IsSharedLibraryEntry(): |
319 non_library_percentage = 0 | 335 non_library_percentage = 0 |
320 else: | 336 else: |
321 non_library_percentage = entry.tick_count * 100.0 / number_of_non_libr
ary_ticks | 337 non_library_percentage = entry.tick_count * 100.0 / number_of_non_libr
ary_ticks |
322 print(' %(total)5.1f%% %(nonlib)6.1f%% %(name)s' % { | 338 print(' %(total)5.1f%% %(nonlib)6.1f%% %(name)s' % { |
(...skipping 24 matching lines...) Expand all Loading... |
347 all_stacks_items.sort(key = itemgetter(1), reverse=True) | 363 all_stacks_items.sort(key = itemgetter(1), reverse=True) |
348 for stack, count in all_stacks_items: | 364 for stack, count in all_stacks_items: |
349 total_percentage = count * 100.0 / total_stacks | 365 total_percentage = count * 100.0 / total_stacks |
350 print(' %(total)5.1f%% %(call_path)s' % { | 366 print(' %(total)5.1f%% %(call_path)s' % { |
351 'total' : total_percentage, | 367 'total' : total_percentage, |
352 'call_path' : stack[0] + ' <- ' + stack[1] | 368 'call_path' : stack[0] + ' <- ' + stack[1] |
353 }) | 369 }) |
354 | 370 |
355 if __name__ == '__main__': | 371 if __name__ == '__main__': |
356 sys.exit('You probably want to run windows-tick-processor.py or linux-tick-pro
cessor.py.') | 372 sys.exit('You probably want to run windows-tick-processor.py or linux-tick-pro
cessor.py.') |
OLD | NEW |