diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-05-12 15:21:53 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-05-12 15:21:53 -0400 |
commit | 2402e4a936a02a24772c9823e1fd2085f0e8ec93 (patch) | |
tree | 1f703f105de2fe958d2467dcc78e25d64ee8ccae /tools/perf/ui | |
parent | 7d5b12f5a01d338d23874c7c242a74813a8848b2 (diff) |
perf annotate browser: Show 'jumpy' functions
Just press 'J' and see how many places jump to jump targets.
The hottest jump target appears in red, targets with more than one
source have a different color than single source jump targets.
Suggested-by: Arjan van de Ven <arjan@infradead.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-7452y0dmc02a20ooins7rn79@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui')
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 446362677840..547bd352118d 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -28,11 +28,16 @@ struct annotate_browser { | |||
28 | u64 start; | 28 | u64 start; |
29 | int nr_asm_entries; | 29 | int nr_asm_entries; |
30 | int nr_entries; | 30 | int nr_entries; |
31 | int max_jump_sources; | ||
32 | int nr_jumps; | ||
31 | bool hide_src_code; | 33 | bool hide_src_code; |
32 | bool use_offset; | 34 | bool use_offset; |
33 | bool jump_arrows; | 35 | bool jump_arrows; |
36 | bool show_nr_jumps; | ||
34 | bool searching_backwards; | 37 | bool searching_backwards; |
35 | u8 addr_width; | 38 | u8 addr_width; |
39 | u8 jumps_width; | ||
40 | u8 target_width; | ||
36 | u8 min_addr_width; | 41 | u8 min_addr_width; |
37 | u8 max_addr_width; | 42 | u8 max_addr_width; |
38 | char search_bf[128]; | 43 | char search_bf[128]; |
@@ -55,6 +60,25 @@ static bool disasm_line__filter(struct ui_browser *browser, void *entry) | |||
55 | return false; | 60 | return false; |
56 | } | 61 | } |
57 | 62 | ||
63 | static int annotate_browser__jumps_percent_color(struct annotate_browser *browser, | ||
64 | int nr, bool current) | ||
65 | { | ||
66 | if (current && (!browser->b.use_navkeypressed || browser->b.navkeypressed)) | ||
67 | return HE_COLORSET_SELECTED; | ||
68 | if (nr == browser->max_jump_sources) | ||
69 | return HE_COLORSET_TOP; | ||
70 | if (nr > 1) | ||
71 | return HE_COLORSET_MEDIUM; | ||
72 | return HE_COLORSET_NORMAL; | ||
73 | } | ||
74 | |||
75 | static int annotate_browser__set_jumps_percent_color(struct annotate_browser *browser, | ||
76 | int nr, bool current) | ||
77 | { | ||
78 | int color = annotate_browser__jumps_percent_color(browser, nr, current); | ||
79 | return ui_browser__set_color(&browser->b, color); | ||
80 | } | ||
81 | |||
58 | static void annotate_browser__write(struct ui_browser *self, void *entry, int row) | 82 | static void annotate_browser__write(struct ui_browser *self, void *entry, int row) |
59 | { | 83 | { |
60 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); | 84 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); |
@@ -99,8 +123,19 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro | |||
99 | printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); | 123 | printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); |
100 | } else { | 124 | } else { |
101 | if (bdl->jump_sources) { | 125 | if (bdl->jump_sources) { |
126 | if (ab->show_nr_jumps) { | ||
127 | int prev; | ||
128 | printed = scnprintf(bf, sizeof(bf), "%*d ", | ||
129 | ab->jumps_width, | ||
130 | bdl->jump_sources); | ||
131 | prev = annotate_browser__set_jumps_percent_color(ab, bdl->jump_sources, | ||
132 | current_entry); | ||
133 | slsmg_write_nstring(bf, printed); | ||
134 | ui_browser__set_color(self, prev); | ||
135 | } | ||
136 | |||
102 | printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ", | 137 | printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ", |
103 | ab->addr_width, addr); | 138 | ab->target_width, addr); |
104 | } else { | 139 | } else { |
105 | printed = scnprintf(bf, sizeof(bf), "%*s ", | 140 | printed = scnprintf(bf, sizeof(bf), "%*s ", |
106 | ab->addr_width, " "); | 141 | ab->addr_width, " "); |
@@ -615,13 +650,20 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, | |||
615 | case 'o': | 650 | case 'o': |
616 | self->use_offset = !self->use_offset; | 651 | self->use_offset = !self->use_offset; |
617 | if (self->use_offset) | 652 | if (self->use_offset) |
618 | self->addr_width = self->min_addr_width; | 653 | self->target_width = self->min_addr_width; |
619 | else | 654 | else |
620 | self->addr_width = self->max_addr_width; | 655 | self->target_width = self->max_addr_width; |
656 | update_addr_width: | ||
657 | self->addr_width = self->target_width; | ||
658 | if (self->show_nr_jumps) | ||
659 | self->addr_width += self->jumps_width + 1; | ||
621 | continue; | 660 | continue; |
622 | case 'j': | 661 | case 'j': |
623 | self->jump_arrows = !self->jump_arrows; | 662 | self->jump_arrows = !self->jump_arrows; |
624 | continue; | 663 | continue; |
664 | case 'J': | ||
665 | self->show_nr_jumps = !self->show_nr_jumps; | ||
666 | goto update_addr_width; | ||
625 | case '/': | 667 | case '/': |
626 | if (annotate_browser__search(self, delay_secs)) { | 668 | if (annotate_browser__search(self, delay_secs)) { |
627 | show_help: | 669 | show_help: |
@@ -707,11 +749,23 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser | |||
707 | continue; | 749 | continue; |
708 | 750 | ||
709 | bdlt = disasm_line__browser(dlt); | 751 | bdlt = disasm_line__browser(dlt); |
710 | ++bdlt->jump_sources; | 752 | if (++bdlt->jump_sources > browser->max_jump_sources) |
753 | browser->max_jump_sources = bdlt->jump_sources; | ||
754 | |||
755 | ++browser->nr_jumps; | ||
711 | } | 756 | } |
712 | 757 | ||
713 | } | 758 | } |
714 | 759 | ||
760 | static inline int width_jumps(int n) | ||
761 | { | ||
762 | if (n >= 100) | ||
763 | return 5; | ||
764 | if (n / 10) | ||
765 | return 2; | ||
766 | return 1; | ||
767 | } | ||
768 | |||
715 | int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | 769 | int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, |
716 | void(*timer)(void *arg), void *arg, | 770 | void(*timer)(void *arg), void *arg, |
717 | int delay_secs) | 771 | int delay_secs) |
@@ -784,8 +838,9 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
784 | 838 | ||
785 | annotate_browser__mark_jump_targets(&browser, size); | 839 | annotate_browser__mark_jump_targets(&browser, size); |
786 | 840 | ||
787 | browser.addr_width = browser.min_addr_width = hex_width(size); | 841 | browser.addr_width = browser.target_width = browser.min_addr_width = hex_width(size); |
788 | browser.max_addr_width = hex_width(sym->end); | 842 | browser.max_addr_width = hex_width(sym->end); |
843 | browser.jumps_width = width_jumps(browser.max_jump_sources); | ||
789 | browser.b.nr_entries = browser.nr_entries; | 844 | browser.b.nr_entries = browser.nr_entries; |
790 | browser.b.entries = ¬es->src->source, | 845 | browser.b.entries = ¬es->src->source, |
791 | browser.b.width += 18; /* Percentage */ | 846 | browser.b.width += 18; /* Percentage */ |