| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 | 52 |
| 53 def ToString(self): | 53 def ToString(self): |
| 54 return self.name | 54 return self.name |
| 55 | 55 |
| 56 def IsSharedLibraryEntry(self): | 56 def IsSharedLibraryEntry(self): |
| 57 return False | 57 return False |
| 58 | 58 |
| 59 def IsICEntry(self): | 59 def IsICEntry(self): |
| 60 return False | 60 return False |
| 61 | 61 |
| 62 def IsJSFunction(self): |
| 63 return False |
| 62 | 64 |
| 63 class SharedLibraryEntry(CodeEntry): | 65 class SharedLibraryEntry(CodeEntry): |
| 64 | 66 |
| 65 def __init__(self, start_addr, name): | 67 def __init__(self, start_addr, name): |
| 66 CodeEntry.__init__(self, start_addr, name) | 68 CodeEntry.__init__(self, start_addr, name) |
| 67 | 69 |
| 68 def IsSharedLibraryEntry(self): | 70 def IsSharedLibraryEntry(self): |
| 69 return True | 71 return True |
| 70 | 72 |
| 71 | 73 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 if name == '': | 119 if name == '': |
| 118 name = '<anonymous>' | 120 name = '<anonymous>' |
| 119 elif name.startswith(' '): | 121 elif name.startswith(' '): |
| 120 name = '<anonymous>' + name | 122 name = '<anonymous>' + name |
| 121 return self.type + ': ' + name | 123 return self.type + ': ' + name |
| 122 | 124 |
| 123 def IsICEntry(self): | 125 def IsICEntry(self): |
| 124 return self.type in ('CallIC', 'LoadIC', 'StoreIC') or \ | 126 return self.type in ('CallIC', 'LoadIC', 'StoreIC') or \ |
| 125 (self.type == 'Builtin' and self.builtin_ic_re.match(self.name)) | 127 (self.type == 'Builtin' and self.builtin_ic_re.match(self.name)) |
| 126 | 128 |
| 129 def IsJSFunction(self): |
| 130 return self.type in ('Function', 'LazyCompile', 'Script') |
| 127 | 131 |
| 128 class CodeRegion(object): | 132 class CodeRegion(object): |
| 129 | 133 |
| 130 def __init__(self, start_offset, name): | 134 def __init__(self, start_offset, name): |
| 131 self.start_offset = start_offset | 135 self.start_offset = start_offset |
| 132 self.name = name | 136 self.name = name |
| 133 self.end_offset = None | 137 self.end_offset = None |
| 134 | 138 |
| 135 def Contains(self, pc): | 139 def Contains(self, pc): |
| 136 return (self.start_offset <= pc) and (pc <= self.end_offset) | 140 return (self.start_offset <= pc) and (pc <= self.end_offset) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 logfile = open(filename, 'rb') | 209 logfile = open(filename, 'rb') |
| 206 except IOError: | 210 except IOError: |
| 207 sys.exit("Could not open logfile: " + filename) | 211 sys.exit("Could not open logfile: " + filename) |
| 208 try: | 212 try: |
| 209 try: | 213 try: |
| 210 logreader = csv.reader(logfile) | 214 logreader = csv.reader(logfile) |
| 211 row_num = 1 | 215 row_num = 1 |
| 212 for row in logreader: | 216 for row in logreader: |
| 213 row_num += 1 | 217 row_num += 1 |
| 214 if row[0] == 'tick': | 218 if row[0] == 'tick': |
| 215 self.ProcessTick(int(row[1], 16), int(row[2], 16), int(row[3]), self
.PreprocessStack(row[4:])) | 219 self.ProcessTick(int(row[1], 16), int(row[2], 16), int(row[3], 16),
int(row[4]), self.PreprocessStack(row[5:])) |
| 216 elif row[0] == 'code-creation': | 220 elif row[0] == 'code-creation': |
| 217 self.ProcessCodeCreation(row[1], int(row[2], 16), int(row[3]), row[4
]) | 221 self.ProcessCodeCreation(row[1], int(row[2], 16), int(row[3]), row[4
]) |
| 218 elif row[0] == 'code-move': | 222 elif row[0] == 'code-move': |
| 219 self.ProcessCodeMove(int(row[1], 16), int(row[2], 16)) | 223 self.ProcessCodeMove(int(row[1], 16), int(row[2], 16)) |
| 220 elif row[0] == 'code-delete': | 224 elif row[0] == 'code-delete': |
| 221 self.ProcessCodeDelete(int(row[1], 16)) | 225 self.ProcessCodeDelete(int(row[1], 16)) |
| 226 elif row[0] == 'function-creation': |
| 227 self.ProcessFunctionCreation(int(row[1], 16), int(row[2], 16)) |
| 228 elif row[0] == 'function-move': |
| 229 self.ProcessFunctionMove(int(row[1], 16), int(row[2], 16)) |
| 230 elif row[0] == 'function-delete': |
| 231 self.ProcessFunctionDelete(int(row[1], 16)) |
| 222 elif row[0] == 'shared-library': | 232 elif row[0] == 'shared-library': |
| 223 self.AddSharedLibraryEntry(row[1], int(row[2], 16), int(row[3], 16)) | 233 self.AddSharedLibraryEntry(row[1], int(row[2], 16), int(row[3], 16)) |
| 224 self.ParseVMSymbols(row[1], int(row[2], 16), int(row[3], 16)) | 234 self.ParseVMSymbols(row[1], int(row[2], 16), int(row[3], 16)) |
| 225 elif row[0] == 'begin-code-region': | 235 elif row[0] == 'begin-code-region': |
| 226 self.ProcessBeginCodeRegion(int(row[1], 16), int(row[2], 16), int(ro
w[3], 16), row[4]) | 236 self.ProcessBeginCodeRegion(int(row[1], 16), int(row[2], 16), int(ro
w[3], 16), row[4]) |
| 227 elif row[0] == 'end-code-region': | 237 elif row[0] == 'end-code-region': |
| 228 self.ProcessEndCodeRegion(int(row[1], 16), int(row[2], 16), int(row[
3], 16)) | 238 self.ProcessEndCodeRegion(int(row[1], 16), int(row[2], 16), int(row[
3], 16)) |
| 229 elif row[0] == 'code-allocate': | 239 elif row[0] == 'code-allocate': |
| 230 self.ProcessCodeAllocate(int(row[1], 16), int(row[2], 16)) | 240 self.ProcessCodeAllocate(int(row[1], 16), int(row[2], 16)) |
| 231 except csv.Error: | 241 except csv.Error: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 except splaytree.KeyNotFoundError: | 278 except splaytree.KeyNotFoundError: |
| 269 print('Code move event for unknown code: 0x%x' % from_addr) | 279 print('Code move event for unknown code: 0x%x' % from_addr) |
| 270 | 280 |
| 271 def ProcessCodeDelete(self, from_addr): | 281 def ProcessCodeDelete(self, from_addr): |
| 272 try: | 282 try: |
| 273 removed_node = self.js_entries.Remove(from_addr) | 283 removed_node = self.js_entries.Remove(from_addr) |
| 274 self.deleted_code.append(removed_node.value) | 284 self.deleted_code.append(removed_node.value) |
| 275 except splaytree.KeyNotFoundError: | 285 except splaytree.KeyNotFoundError: |
| 276 print('Code delete event for unknown code: 0x%x' % from_addr) | 286 print('Code delete event for unknown code: 0x%x' % from_addr) |
| 277 | 287 |
| 288 def ProcessFunctionCreation(self, func_addr, code_addr): |
| 289 js_entry_node = self.js_entries.Find(code_addr) |
| 290 if js_entry_node: |
| 291 js_entry = js_entry_node.value |
| 292 self.js_entries.Insert(func_addr, JSCodeEntry(func_addr, js_entry.name, js
_entry.type, 1, None)) |
| 293 |
| 294 def ProcessFunctionMove(self, from_addr, to_addr): |
| 295 try: |
| 296 removed_node = self.js_entries.Remove(from_addr) |
| 297 removed_node.value.SetStartAddress(to_addr); |
| 298 self.js_entries.Insert(to_addr, removed_node.value) |
| 299 except splaytree.KeyNotFoundError: |
| 300 return |
| 301 |
| 302 def ProcessFunctionDelete(self, from_addr): |
| 303 try: |
| 304 removed_node = self.js_entries.Remove(from_addr) |
| 305 self.deleted_code.append(removed_node.value) |
| 306 except splaytree.KeyNotFoundError: |
| 307 return |
| 308 |
| 278 def ProcessBeginCodeRegion(self, id, assm, start, name): | 309 def ProcessBeginCodeRegion(self, id, assm, start, name): |
| 279 if not assm in self.pending_assemblers: | 310 if not assm in self.pending_assemblers: |
| 280 self.pending_assemblers[assm] = Assembler() | 311 self.pending_assemblers[assm] = Assembler() |
| 281 assembler = self.pending_assemblers[assm] | 312 assembler = self.pending_assemblers[assm] |
| 282 assembler.pending_regions[id] = CodeRegion(start, name) | 313 assembler.pending_regions[id] = CodeRegion(start, name) |
| 283 | 314 |
| 284 def ProcessEndCodeRegion(self, id, assm, end): | 315 def ProcessEndCodeRegion(self, id, assm, end): |
| 285 assm = self.pending_assemblers[assm] | 316 assm = self.pending_assemblers[assm] |
| 286 region = assm.pending_regions.pop(id) | 317 region = assm.pending_regions.pop(id) |
| 287 region.end_offset = end | 318 region.end_offset = end |
| (...skipping 25 matching lines...) Expand all Loading... |
| 313 return result | 344 return result |
| 314 | 345 |
| 315 def ProcessStack(self, stack): | 346 def ProcessStack(self, stack): |
| 316 result = [] | 347 result = [] |
| 317 for frame in stack: | 348 for frame in stack: |
| 318 entry = self.FindEntry(frame) | 349 entry = self.FindEntry(frame) |
| 319 if entry != None: | 350 if entry != None: |
| 320 result.append(entry.ToString()) | 351 result.append(entry.ToString()) |
| 321 return result | 352 return result |
| 322 | 353 |
| 323 def ProcessTick(self, pc, sp, state, stack): | 354 def ProcessTick(self, pc, sp, func, state, stack): |
| 324 if state == VMStates['GC']: | 355 if state == VMStates['GC']: |
| 325 self.number_of_gc_ticks += 1 | 356 self.number_of_gc_ticks += 1 |
| 326 if not self.IncludeTick(pc, sp, state): | 357 if not self.IncludeTick(pc, sp, state): |
| 327 self.excluded_number_of_ticks += 1; | 358 self.excluded_number_of_ticks += 1; |
| 328 return | 359 return |
| 329 self.total_number_of_ticks += 1 | 360 self.total_number_of_ticks += 1 |
| 330 entry = self.FindEntry(pc) | 361 entry = self.FindEntry(pc) |
| 331 if entry == None: | 362 if entry == None: |
| 332 self.unaccounted_number_of_ticks += 1 | 363 self.unaccounted_number_of_ticks += 1 |
| 333 return | 364 return |
| 334 if entry.IsSharedLibraryEntry(): | 365 if entry.IsSharedLibraryEntry(): |
| 335 self.number_of_library_ticks += 1 | 366 self.number_of_library_ticks += 1 |
| 336 if entry.IsICEntry() and not self.separate_ic: | 367 if entry.IsICEntry() and not self.separate_ic: |
| 337 if len(stack) > 0: | 368 if len(stack) > 0: |
| 338 caller_pc = stack.pop(0) | 369 caller_pc = stack.pop(0) |
| 339 self.total_number_of_ticks -= 1 | 370 self.total_number_of_ticks -= 1 |
| 340 self.ProcessTick(caller_pc, sp, state, stack) | 371 self.ProcessTick(caller_pc, sp, func, state, stack) |
| 341 else: | 372 else: |
| 342 self.unaccounted_number_of_ticks += 1 | 373 self.unaccounted_number_of_ticks += 1 |
| 343 else: | 374 else: |
| 344 entry.Tick(pc, self.ProcessStack(stack)) | 375 processed_stack = self.ProcessStack(stack) |
| 376 if not entry.IsSharedLibraryEntry() and not entry.IsJSFunction(): |
| 377 func_entry_node = self.js_entries.Find(func) |
| 378 if func_entry_node and func_entry_node.value.IsJSFunction(): |
| 379 processed_stack.insert(0, func_entry_node.value.ToString()) |
| 380 entry.Tick(pc, processed_stack) |
| 345 if self.call_graph_json: | 381 if self.call_graph_json: |
| 346 self.AddToPackedStacks(pc, stack) | 382 self.AddToPackedStacks(pc, stack) |
| 347 | 383 |
| 348 def AddToPackedStacks(self, pc, stack): | 384 def AddToPackedStacks(self, pc, stack): |
| 349 full_stack = stack | 385 full_stack = stack |
| 350 full_stack.insert(0, pc) | 386 full_stack.insert(0, pc) |
| 351 func_names = self.ProcessStack(full_stack) | 387 func_names = self.ProcessStack(full_stack) |
| 352 func_ids = [] | 388 func_ids = [] |
| 353 for func in func_names: | 389 for func in func_names: |
| 354 func_ids.append(self.func_enum.GetFunctionId(func)) | 390 func_ids.append(self.func_enum.GetFunctionId(func)) |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 }) | 562 }) |
| 527 sys.exit(2) | 563 sys.exit(2) |
| 528 | 564 |
| 529 def RunLogfileProcessing(self, tick_processor): | 565 def RunLogfileProcessing(self, tick_processor): |
| 530 tick_processor.ProcessLogfile(self.log_file, self.state, self.ignore_unknown
, | 566 tick_processor.ProcessLogfile(self.log_file, self.state, self.ignore_unknown
, |
| 531 self.separate_ic, self.call_graph_json) | 567 self.separate_ic, self.call_graph_json) |
| 532 | 568 |
| 533 | 569 |
| 534 if __name__ == '__main__': | 570 if __name__ == '__main__': |
| 535 sys.exit('You probably want to run windows-tick-processor.py or linux-tick-pro
cessor.py.') | 571 sys.exit('You probably want to run windows-tick-processor.py or linux-tick-pro
cessor.py.') |
| OLD | NEW |