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 |