aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui/browsers/annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r--tools/perf/ui/browsers/annotate.c94
1 files changed, 80 insertions, 14 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 06367c1df720..6e0ef79be169 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -16,7 +16,7 @@ struct browser_disasm_line {
16 double percent; 16 double percent;
17 u32 idx; 17 u32 idx;
18 int idx_asm; 18 int idx_asm;
19 bool jump_target; 19 int jump_sources;
20}; 20};
21 21
22struct annotate_browser { 22struct annotate_browser {
@@ -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
63static 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
75static 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
58static void annotate_browser__write(struct ui_browser *self, void *entry, int row) 82static 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);
@@ -98,9 +122,20 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
98 if (!ab->use_offset) { 122 if (!ab->use_offset) {
99 printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); 123 printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
100 } else { 124 } else {
101 if (bdl->jump_target) { 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, " ");
@@ -546,10 +581,7 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
546 struct rb_node *nd = NULL; 581 struct rb_node *nd = NULL;
547 struct map_symbol *ms = self->b.priv; 582 struct map_symbol *ms = self->b.priv;
548 struct symbol *sym = ms->sym; 583 struct symbol *sym = ms->sym;
549 const char *help = "<-/ESC: Exit, TAB/shift+TAB: Cycle hot lines, " 584 const char *help = "Press 'h' for help on key bindings";
550 "H: Hottest line, ->/ENTER: Line action, "
551 "O: Offset view, "
552 "S: Source view";
553 int key; 585 int key;
554 586
555 if (ui_browser__show(&self->b, sym->name, help) < 0) 587 if (ui_browser__show(&self->b, sym->name, help) < 0)
@@ -602,26 +634,47 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
602 else 634 else
603 nd = self->curr_hot; 635 nd = self->curr_hot;
604 break; 636 break;
605 case 'H': 637 case K_F1:
606 case 'h': 638 case 'h':
639 ui_browser__help_window(&self->b,
640 "UP/DOWN/PGUP\n"
641 "PGDN/SPACE Navigate\n"
642 "q/ESC/CTRL+C Exit\n\n"
643 "-> Go to target\n"
644 "<- Exit\n"
645 "h Cycle thru hottest instructions\n"
646 "j Toggle showing jump to target arrows\n"
647 "J Toggle showing number of jump sources on targets\n"
648 "n Search next string\n"
649 "o Toggle disassembler output/simplified view\n"
650 "s Toggle source code view\n"
651 "/ Search string\n"
652 "? Search previous string\n");
653 continue;
654 case 'H':
607 nd = self->curr_hot; 655 nd = self->curr_hot;
608 break; 656 break;
609 case 'S':
610 case 's': 657 case 's':
611 if (annotate_browser__toggle_source(self)) 658 if (annotate_browser__toggle_source(self))
612 ui_helpline__puts(help); 659 ui_helpline__puts(help);
613 continue; 660 continue;
614 case 'O':
615 case 'o': 661 case 'o':
616 self->use_offset = !self->use_offset; 662 self->use_offset = !self->use_offset;
617 if (self->use_offset) 663 if (self->use_offset)
618 self->addr_width = self->min_addr_width; 664 self->target_width = self->min_addr_width;
619 else 665 else
620 self->addr_width = self->max_addr_width; 666 self->target_width = self->max_addr_width;
667update_addr_width:
668 self->addr_width = self->target_width;
669 if (self->show_nr_jumps)
670 self->addr_width += self->jumps_width + 1;
621 continue; 671 continue;
622 case 'j': 672 case 'j':
623 self->jump_arrows = !self->jump_arrows; 673 self->jump_arrows = !self->jump_arrows;
624 continue; 674 continue;
675 case 'J':
676 self->show_nr_jumps = !self->show_nr_jumps;
677 goto update_addr_width;
625 case '/': 678 case '/':
626 if (annotate_browser__search(self, delay_secs)) { 679 if (annotate_browser__search(self, delay_secs)) {
627show_help: 680show_help:
@@ -707,11 +760,23 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser
707 continue; 760 continue;
708 761
709 bdlt = disasm_line__browser(dlt); 762 bdlt = disasm_line__browser(dlt);
710 bdlt->jump_target = true; 763 if (++bdlt->jump_sources > browser->max_jump_sources)
764 browser->max_jump_sources = bdlt->jump_sources;
765
766 ++browser->nr_jumps;
711 } 767 }
712 768
713} 769}
714 770
771static inline int width_jumps(int n)
772{
773 if (n >= 100)
774 return 5;
775 if (n / 10)
776 return 2;
777 return 1;
778}
779
715int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, 780int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
716 void(*timer)(void *arg), void *arg, 781 void(*timer)(void *arg), void *arg,
717 int delay_secs) 782 int delay_secs)
@@ -784,8 +849,9 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
784 849
785 annotate_browser__mark_jump_targets(&browser, size); 850 annotate_browser__mark_jump_targets(&browser, size);
786 851
787 browser.addr_width = browser.min_addr_width = hex_width(size); 852 browser.addr_width = browser.target_width = browser.min_addr_width = hex_width(size);
788 browser.max_addr_width = hex_width(sym->end); 853 browser.max_addr_width = hex_width(sym->end);
854 browser.jumps_width = width_jumps(browser.max_jump_sources);
789 browser.b.nr_entries = browser.nr_entries; 855 browser.b.nr_entries = browser.nr_entries;
790 browser.b.entries = &notes->src->source, 856 browser.b.entries = &notes->src->source,
791 browser.b.width += 18; /* Percentage */ 857 browser.b.width += 18; /* Percentage */