diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-04-19 11:19:22 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-04-19 11:19:22 -0400 |
commit | b793a40185b246c2690e06c6d86d12c35f24ab4c (patch) | |
tree | c39d978911642a6bab79982f4cfa77fe76c65535 /tools/perf/ui/browsers/annotate.c | |
parent | 1b2e2df4e395293e65dbda49e58cb4c7abeb7507 (diff) |
perf annotate browser: Hide non jump target addresses in offset mode
This:
0.00 : ffffffff8116bd00: lock btsl $0x0,(%r12)
100.00 : ffffffff8116bd07: sbb %eax,%eax
0.00 : ffffffff8116bd09: test %eax,%eax
0.00 : ffffffff8116bd0b: jne ffffffff8116bf5f <__mem_cgroup_commit_charge+0x28f>
0.00 : ffffffff8116bd11: mov (%r12),%rax
0.00 : ffffffff8116bd15: test $0x2,%al
0.00 : ffffffff8116bd17: jne ffffffff8116bf6e <__mem_cgroup_commit_charge+0x29e>
0.00 : ffffffff8116bd1d: test %r9b,%r9b
0.00 : ffffffff8116bd20: jne ffffffff8116be30 <__mem_cgroup_commit_charge+0x160>
0.00 : ffffffff8116bd26: xor %eax,%eax
0.00 : ffffffff8116bd28: mov %r13,0x8(%r12)
0.00 : ffffffff8116bd2d: lock orb $0x2,(%r12)
0.00 : ffffffff8116bd33: test %r9b,%r9b
0.00 : ffffffff8116bd36: je ffffffff8116bdf3 <__mem_cgroup_commit_charge+0x123>
Becomes:
0.00 : 30: lock btsl $0x0,(%r12)
100.00 : sbb %eax,%eax
0.00 : test %eax,%eax
0.00 : jne 28f
0.00 : mov (%r12),%rax
0.00 : test $0x2,%al
0.00 : jne 29e
0.00 : test %r9b,%r9b
0.00 : jne 160
0.00 : 56: xor %eax,%eax
0.00 : 58: mov %r13,0x8(%r12)
0.00 : lock orb $0x2,(%r12)
0.00 : test %r9b,%r9b
0.00 : je 123
I.e. We trow away all those useless addresses and keep just jump labels.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-r2vmbtgz0l8coluj8flztgrn@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 58ebfd0ac1e8..a1e942bb903b 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -11,11 +11,20 @@ | |||
11 | #include <pthread.h> | 11 | #include <pthread.h> |
12 | #include <newt.h> | 12 | #include <newt.h> |
13 | 13 | ||
14 | struct browser_disasm_line { | ||
15 | struct rb_node rb_node; | ||
16 | double percent; | ||
17 | u32 idx; | ||
18 | int idx_asm; | ||
19 | bool jump_target; | ||
20 | }; | ||
21 | |||
14 | struct annotate_browser { | 22 | struct annotate_browser { |
15 | struct ui_browser b; | 23 | struct ui_browser b; |
16 | struct rb_root entries; | 24 | struct rb_root entries; |
17 | struct rb_node *curr_hot; | 25 | struct rb_node *curr_hot; |
18 | struct disasm_line *selection; | 26 | struct disasm_line *selection; |
27 | struct disasm_line **offsets; | ||
19 | u64 start; | 28 | u64 start; |
20 | int nr_asm_entries; | 29 | int nr_asm_entries; |
21 | int nr_entries; | 30 | int nr_entries; |
@@ -25,13 +34,6 @@ struct annotate_browser { | |||
25 | char search_bf[128]; | 34 | char search_bf[128]; |
26 | }; | 35 | }; |
27 | 36 | ||
28 | struct browser_disasm_line { | ||
29 | struct rb_node rb_node; | ||
30 | double percent; | ||
31 | u32 idx; | ||
32 | int idx_asm; | ||
33 | }; | ||
34 | |||
35 | static inline struct browser_disasm_line *disasm_line__browser(struct disasm_line *dl) | 37 | static inline struct browser_disasm_line *disasm_line__browser(struct disasm_line *dl) |
36 | { | 38 | { |
37 | return (struct browser_disasm_line *)(dl + 1); | 39 | return (struct browser_disasm_line *)(dl + 1); |
@@ -53,6 +55,7 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
53 | { | 55 | { |
54 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); | 56 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); |
55 | struct disasm_line *dl = list_entry(entry, struct disasm_line, node); | 57 | struct disasm_line *dl = list_entry(entry, struct disasm_line, node); |
58 | struct browser_disasm_line *bdl = disasm_line__browser(dl); | ||
56 | bool current_entry = ui_browser__is_current_entry(self, row); | 59 | bool current_entry = ui_browser__is_current_entry(self, row); |
57 | bool change_color = (!ab->hide_src_code && | 60 | bool change_color = (!ab->hide_src_code && |
58 | (!current_entry || (self->use_navkeypressed && | 61 | (!current_entry || (self->use_navkeypressed && |
@@ -60,7 +63,6 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
60 | int width = self->width; | 63 | int width = self->width; |
61 | 64 | ||
62 | if (dl->offset != -1) { | 65 | if (dl->offset != -1) { |
63 | struct browser_disasm_line *bdl = disasm_line__browser(dl); | ||
64 | ui_browser__set_percent_color(self, bdl->percent, current_entry); | 66 | ui_browser__set_percent_color(self, bdl->percent, current_entry); |
65 | slsmg_printf(" %7.2f ", bdl->percent); | 67 | slsmg_printf(" %7.2f ", bdl->percent); |
66 | } else { | 68 | } else { |
@@ -90,7 +92,11 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
90 | if (!ab->use_offset) | 92 | if (!ab->use_offset) |
91 | addr += ab->start; | 93 | addr += ab->start; |
92 | 94 | ||
93 | printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr); | 95 | if (bdl->jump_target || !ab->use_offset) |
96 | printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr); | ||
97 | else | ||
98 | printed = scnprintf(bf, sizeof(bf), " "); | ||
99 | |||
94 | if (change_color) | 100 | if (change_color) |
95 | color = ui_browser__set_color(self, HE_COLORSET_ADDR); | 101 | color = ui_browser__set_color(self, HE_COLORSET_ADDR); |
96 | slsmg_write_nstring(bf, printed); | 102 | slsmg_write_nstring(bf, printed); |
@@ -593,12 +599,39 @@ int hist_entry__tui_annotate(struct hist_entry *he, int evidx, | |||
593 | timer, arg, delay_secs); | 599 | timer, arg, delay_secs); |
594 | } | 600 | } |
595 | 601 | ||
602 | static void annotate_browser__mark_jump_targets(struct annotate_browser *browser, | ||
603 | size_t size) | ||
604 | { | ||
605 | u64 offset; | ||
606 | |||
607 | for (offset = 0; offset < size; ++offset) { | ||
608 | struct disasm_line *dl = browser->offsets[offset], *dlt; | ||
609 | struct browser_disasm_line *bdlt; | ||
610 | |||
611 | if (!dl || !dl->ins || !ins__is_jump(dl->ins)) | ||
612 | continue; | ||
613 | |||
614 | if (dl->target >= size) { | ||
615 | ui__error("jump to after symbol!\n" | ||
616 | "size: %zx, jump target: %" PRIx64, | ||
617 | size, dl->target); | ||
618 | continue; | ||
619 | } | ||
620 | |||
621 | dlt = browser->offsets[dl->target]; | ||
622 | bdlt = disasm_line__browser(dlt); | ||
623 | bdlt->jump_target = true; | ||
624 | } | ||
625 | |||
626 | } | ||
627 | |||
596 | int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | 628 | int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, |
597 | void(*timer)(void *arg), void *arg, | 629 | void(*timer)(void *arg), void *arg, |
598 | int delay_secs) | 630 | int delay_secs) |
599 | { | 631 | { |
600 | struct disasm_line *pos, *n; | 632 | struct disasm_line *pos, *n; |
601 | struct annotation *notes; | 633 | struct annotation *notes; |
634 | const size_t size = symbol__size(sym); | ||
602 | struct map_symbol ms = { | 635 | struct map_symbol ms = { |
603 | .map = map, | 636 | .map = map, |
604 | .sym = sym, | 637 | .sym = sym, |
@@ -613,7 +646,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
613 | .use_navkeypressed = true, | 646 | .use_navkeypressed = true, |
614 | }, | 647 | }, |
615 | }; | 648 | }; |
616 | int ret; | 649 | int ret = -1; |
617 | 650 | ||
618 | if (sym == NULL) | 651 | if (sym == NULL) |
619 | return -1; | 652 | return -1; |
@@ -621,9 +654,15 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
621 | if (map->dso->annotate_warned) | 654 | if (map->dso->annotate_warned) |
622 | return -1; | 655 | return -1; |
623 | 656 | ||
657 | browser.offsets = zalloc(size * sizeof(struct disasm_line *)); | ||
658 | if (browser.offsets == NULL) { | ||
659 | ui__error("Not enough memory!"); | ||
660 | return -1; | ||
661 | } | ||
662 | |||
624 | if (symbol__annotate(sym, map, sizeof(struct browser_disasm_line)) < 0) { | 663 | if (symbol__annotate(sym, map, sizeof(struct browser_disasm_line)) < 0) { |
625 | ui__error("%s", ui_helpline__last_msg); | 664 | ui__error("%s", ui_helpline__last_msg); |
626 | return -1; | 665 | goto out_free_offsets; |
627 | } | 666 | } |
628 | 667 | ||
629 | ui_helpline__push("Press <- or ESC to exit"); | 668 | ui_helpline__push("Press <- or ESC to exit"); |
@@ -639,12 +678,15 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
639 | browser.b.width = line_len; | 678 | browser.b.width = line_len; |
640 | bpos = disasm_line__browser(pos); | 679 | bpos = disasm_line__browser(pos); |
641 | bpos->idx = browser.nr_entries++; | 680 | bpos->idx = browser.nr_entries++; |
642 | if (pos->offset != -1) | 681 | if (pos->offset != -1) { |
643 | bpos->idx_asm = browser.nr_asm_entries++; | 682 | bpos->idx_asm = browser.nr_asm_entries++; |
644 | else | 683 | browser.offsets[pos->offset] = pos; |
684 | } else | ||
645 | bpos->idx_asm = -1; | 685 | bpos->idx_asm = -1; |
646 | } | 686 | } |
647 | 687 | ||
688 | annotate_browser__mark_jump_targets(&browser, size); | ||
689 | |||
648 | browser.b.nr_entries = browser.nr_entries; | 690 | browser.b.nr_entries = browser.nr_entries; |
649 | browser.b.entries = ¬es->src->source, | 691 | browser.b.entries = ¬es->src->source, |
650 | browser.b.width += 18; /* Percentage */ | 692 | browser.b.width += 18; /* Percentage */ |
@@ -653,5 +695,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
653 | list_del(&pos->node); | 695 | list_del(&pos->node); |
654 | disasm_line__free(pos); | 696 | disasm_line__free(pos); |
655 | } | 697 | } |
698 | |||
699 | out_free_offsets: | ||
700 | free(browser.offsets); | ||
656 | return ret; | 701 | return ret; |
657 | } | 702 | } |