diff options
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
| -rw-r--r-- | tools/perf/ui/browsers/annotate.c | 94 |
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 | ||
| 22 | struct annotate_browser { | 22 | struct 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 | ||
| 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); |
| @@ -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; |
| 667 | update_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)) { |
| 627 | show_help: | 680 | show_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 | ||
| 771 | static 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 | |||
| 715 | int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | 780 | int 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 = ¬es->src->source, | 856 | browser.b.entries = ¬es->src->source, |
| 791 | browser.b.width += 18; /* Percentage */ | 857 | browser.b.width += 18; /* Percentage */ |
