| 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 |