OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2012 the V8 project authors. All rights reserved. | 3 # Copyright 2012 the V8 project authors. All rights reserved. |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 | 561 |
562 | 562 |
563 # Reference: /usr/include/linux/perf_event.h | 563 # Reference: /usr/include/linux/perf_event.h |
564 PERF_EVENT_HEADER_DESC = Descriptor([ | 564 PERF_EVENT_HEADER_DESC = Descriptor([ |
565 ("type", "u32"), | 565 ("type", "u32"), |
566 ("misc", "u16"), | 566 ("misc", "u16"), |
567 ("size", "u16") | 567 ("size", "u16") |
568 ]) | 568 ]) |
569 | 569 |
570 | 570 |
571 # Reference: kernel/events/core.c | 571 # Reference: kernel/tools/perf/util/event.h |
572 PERF_MMAP_EVENT_BODY_DESC = Descriptor([ | 572 PERF_MMAP_EVENT_BODY_DESC = Descriptor([ |
573 ("pid", "u32"), | 573 ("pid", "u32"), |
574 ("tid", "u32"), | 574 ("tid", "u32"), |
575 ("addr", "u64"), | 575 ("addr", "u64"), |
576 ("len", "u64"), | 576 ("len", "u64"), |
577 ("pgoff", "u64") | 577 ("pgoff", "u64") |
578 ]) | 578 ]) |
579 | 579 |
| 580 # Reference: kernel/tools/perf/util/event.h |
| 581 PERF_MMAP2_EVENT_BODY_DESC = Descriptor([ |
| 582 ("pid", "u32"), |
| 583 ("tid", "u32"), |
| 584 ("addr", "u64"), |
| 585 ("len", "u64"), |
| 586 ("pgoff", "u64"), |
| 587 ("maj", "u32"), |
| 588 ("min", "u32"), |
| 589 ("ino", "u64"), |
| 590 ("ino_generation", "u64"), |
| 591 ("prot", "u32"), |
| 592 ("flags","u32") |
| 593 ]) |
580 | 594 |
581 # perf_event_attr.sample_type bits control the set of | 595 # perf_event_attr.sample_type bits control the set of |
582 # perf_sample_event fields. | 596 # perf_sample_event fields. |
583 PERF_SAMPLE_IP = 1 << 0 | 597 PERF_SAMPLE_IP = 1 << 0 |
584 PERF_SAMPLE_TID = 1 << 1 | 598 PERF_SAMPLE_TID = 1 << 1 |
585 PERF_SAMPLE_TIME = 1 << 2 | 599 PERF_SAMPLE_TIME = 1 << 2 |
586 PERF_SAMPLE_ADDR = 1 << 3 | 600 PERF_SAMPLE_ADDR = 1 << 3 |
587 PERF_SAMPLE_READ = 1 << 4 | 601 PERF_SAMPLE_READ = 1 << 4 |
588 PERF_SAMPLE_CALLCHAIN = 1 << 5 | 602 PERF_SAMPLE_CALLCHAIN = 1 << 5 |
589 PERF_SAMPLE_ID = 1 << 6 | 603 PERF_SAMPLE_ID = 1 << 6 |
(...skipping 19 matching lines...) Expand all Loading... |
609 # before the callchain and has variable size. | 623 # before the callchain and has variable size. |
610 ("nr", "u64", PERF_SAMPLE_CALLCHAIN) | 624 ("nr", "u64", PERF_SAMPLE_CALLCHAIN) |
611 # Raw data follows the callchain and is ignored. | 625 # Raw data follows the callchain and is ignored. |
612 ] | 626 ] |
613 | 627 |
614 | 628 |
615 PERF_SAMPLE_EVENT_IP_FORMAT = "u64" | 629 PERF_SAMPLE_EVENT_IP_FORMAT = "u64" |
616 | 630 |
617 | 631 |
618 PERF_RECORD_MMAP = 1 | 632 PERF_RECORD_MMAP = 1 |
| 633 PERF_RECORD_MMAP2 = 10 |
619 PERF_RECORD_SAMPLE = 9 | 634 PERF_RECORD_SAMPLE = 9 |
620 | 635 |
621 | 636 |
622 class TraceReader(object): | 637 class TraceReader(object): |
623 """Perf (linux-2.6/tools/perf) trace file reader.""" | 638 """Perf (linux-2.6/tools/perf) trace file reader.""" |
624 | 639 |
625 _TRACE_HEADER_MAGIC = 4993446653023372624 | 640 _TRACE_HEADER_MAGIC = 4993446653023372624 |
626 | 641 |
627 def __init__(self, trace_name): | 642 def __init__(self, trace_name): |
628 self.trace_file = open(trace_name, "r") | 643 self.trace_file = open(trace_name, "r") |
(...skipping 28 matching lines...) Expand all Loading... |
657 | 672 |
658 def ReadMmap(self, header, offset): | 673 def ReadMmap(self, header, offset): |
659 mmap_info = PERF_MMAP_EVENT_BODY_DESC.Read(self.trace, | 674 mmap_info = PERF_MMAP_EVENT_BODY_DESC.Read(self.trace, |
660 offset + self.header_size) | 675 offset + self.header_size) |
661 # Read null-terminated filename. | 676 # Read null-terminated filename. |
662 filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info): | 677 filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info): |
663 offset + header.size] | 678 offset + header.size] |
664 mmap_info.filename = HOST_ROOT + filename[:filename.find(chr(0))] | 679 mmap_info.filename = HOST_ROOT + filename[:filename.find(chr(0))] |
665 return mmap_info | 680 return mmap_info |
666 | 681 |
| 682 def ReadMmap2(self, header, offset): |
| 683 mmap_info = PERF_MMAP2_EVENT_BODY_DESC.Read(self.trace, |
| 684 offset + self.header_size) |
| 685 # Read null-terminated filename. |
| 686 filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info): |
| 687 offset + header.size] |
| 688 mmap_info.filename = HOST_ROOT + filename[:filename.find(chr(0))] |
| 689 return mmap_info |
| 690 |
667 def ReadSample(self, header, offset): | 691 def ReadSample(self, header, offset): |
668 sample = self.sample_event_body_desc.Read(self.trace, | 692 sample = self.sample_event_body_desc.Read(self.trace, |
669 offset + self.header_size) | 693 offset + self.header_size) |
670 if not self.callchain_supported: | 694 if not self.callchain_supported: |
671 return sample | 695 return sample |
672 sample.ips = [] | 696 sample.ips = [] |
673 offset += self.header_size + ctypes.sizeof(sample) | 697 offset += self.header_size + ctypes.sizeof(sample) |
674 for _ in xrange(sample.nr): | 698 for _ in xrange(sample.nr): |
675 sample.ips.append( | 699 sample.ips.append( |
676 self.ip_struct.from_buffer(self.trace, offset).value) | 700 self.ip_struct.from_buffer(self.trace, offset).value) |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 break | 990 break |
967 events += 1 | 991 events += 1 |
968 if header.type == PERF_RECORD_MMAP: | 992 if header.type == PERF_RECORD_MMAP: |
969 start = time.time() | 993 start = time.time() |
970 mmap_info = trace_reader.ReadMmap(header, offset) | 994 mmap_info = trace_reader.ReadMmap(header, offset) |
971 if mmap_info.filename == HOST_ROOT + V8_GC_FAKE_MMAP: | 995 if mmap_info.filename == HOST_ROOT + V8_GC_FAKE_MMAP: |
972 log_reader.ReadUpToGC() | 996 log_reader.ReadUpToGC() |
973 else: | 997 else: |
974 library_repo.Load(mmap_info, code_map, options) | 998 library_repo.Load(mmap_info, code_map, options) |
975 mmap_time += time.time() - start | 999 mmap_time += time.time() - start |
| 1000 elif header.type == PERF_RECORD_MMAP2: |
| 1001 start = time.time() |
| 1002 mmap_info = trace_reader.ReadMmap2(header, offset) |
| 1003 if mmap_info.filename == HOST_ROOT + V8_GC_FAKE_MMAP: |
| 1004 log_reader.ReadUpToGC() |
| 1005 else: |
| 1006 library_repo.Load(mmap_info, code_map, options) |
| 1007 mmap_time += time.time() - start |
976 elif header.type == PERF_RECORD_SAMPLE: | 1008 elif header.type == PERF_RECORD_SAMPLE: |
977 ticks += 1 | 1009 ticks += 1 |
978 start = time.time() | 1010 start = time.time() |
979 sample = trace_reader.ReadSample(header, offset) | 1011 sample = trace_reader.ReadSample(header, offset) |
980 code = code_map.Find(sample.ip) | 1012 code = code_map.Find(sample.ip) |
981 if code: | 1013 if code: |
982 code.Tick(sample.ip) | 1014 code.Tick(sample.ip) |
983 if code.codetype == Code.OPTIMIZED: | 1015 if code.codetype == Code.OPTIMIZED: |
984 optimized_ticks += 1 | 1016 optimized_ticks += 1 |
985 elif code.codetype == Code.FULL_CODEGEN: | 1017 elif code.codetype == Code.FULL_CODEGEN: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 PrintTicks(optimized_ticks, ticks, "ticks in optimized code") | 1052 PrintTicks(optimized_ticks, ticks, "ticks in optimized code") |
1021 PrintTicks(generated_ticks, ticks, "ticks in other lazily compiled code") | 1053 PrintTicks(generated_ticks, ticks, "ticks in other lazily compiled code") |
1022 PrintTicks(v8_internal_ticks, ticks, "ticks in v8::internal::*") | 1054 PrintTicks(v8_internal_ticks, ticks, "ticks in v8::internal::*") |
1023 print "%10d total symbols" % len([c for c in code_map.AllCode()]) | 1055 print "%10d total symbols" % len([c for c in code_map.AllCode()]) |
1024 print "%10d used symbols" % len([c for c in code_map.UsedCode()]) | 1056 print "%10d used symbols" % len([c for c in code_map.UsedCode()]) |
1025 print "%9.2fs library processing time" % mmap_time | 1057 print "%9.2fs library processing time" % mmap_time |
1026 print "%9.2fs tick processing time" % sample_time | 1058 print "%9.2fs tick processing time" % sample_time |
1027 | 1059 |
1028 log_reader.Dispose() | 1060 log_reader.Dispose() |
1029 trace_reader.Dispose() | 1061 trace_reader.Dispose() |
OLD | NEW |