Current source code view in TUI also has problems showing wrong line number and confusing mixed source code & dissambly view.
So fix it with the new source code view. We can toggle the new source code view by a 's' key. Before: │11 void pack_knapsack(struct jewelry *jewelry) │12 { │ push %rbp │ mov %rsp,%rbp │ sub $0x18,%rsp │ mov %rdi,-0x18(%rbp) │17 * price per limited weight. │18 */ │19 int wgt; │20 unsigned int maxprice; │ │22 if (limited_wgt < jewelry->wgt) │ mov -0x18(%rbp),%rax │ mov (%rax),%edx │ mov limited_wgt,%eax │ cmp %eax,%edx │ ↓ ja 8d │28 return; │ │30 for (wgt = 0; wgt <= limited_wgt; wgt++) { │ movl $0x0,-0x8(%rbp) │ ↓ jmp 7e │33 if (jewelry->wgt <= wgt) { 4.88 │25: mov -0x18(%rbp),%rax │ mov (%rax),%edx 1.22 │ mov -0x8(%rbp),%eax 1.22 │ cmp %eax,%edx 2.44 │ ↓ ja 7a │39 maxprice = get_cond_maxprice(wgt, jewelry); After: │46 void pack_knapsack(struct jewelry *jewelry) │47 { │48 /* Case by case pack knapsack following maximum │49 * price per limited weight. │50 */ │51 int wgt; │52 unsigned int maxprice; │53 │54 if (limited_wgt < jewelry->wgt) │55 return; │56 52.44 │57 for (wgt = 0; wgt <= limited_wgt; wgt++) { 9.76 │58 if (jewelry->wgt <= wgt) { 25.61 │59 maxprice = get_cond_maxprice(wgt, jewelry); Cc: Namhyung Kim <namhy...@kernel.org> Cc: Jiri Olsa <jo...@redhat.com> Signed-off-by: Taeung Song <treeze.tae...@gmail.com> --- tools/perf/ui/browsers/annotate.c | 170 ++++++++++++++++++++++++++++---------- tools/perf/util/annotate.h | 1 + 2 files changed, 128 insertions(+), 43 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 03b2012..d6d072b 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -39,7 +39,7 @@ static struct annotate_browser_opt { }; struct annotate_browser { - struct ui_browser b; + struct ui_browser b, cb; struct rb_root entries; struct rb_node *curr_hot; struct disasm_line *selection; @@ -52,6 +52,7 @@ struct annotate_browser { int nr_jumps; bool searching_backwards; bool have_cycles; + bool has_src_code; u8 addr_width; u8 jumps_width; u8 target_width; @@ -104,6 +105,47 @@ static int annotate_browser__pcnt_width(struct annotate_browser *ab) return w; } +static void annotate_code_browser__write(struct ui_browser *browser, void *entry, int row) +{ + struct annotate_browser *ab = container_of(browser, struct annotate_browser, cb); + struct code_line *cl = list_entry(entry, struct code_line, node); + bool current_entry = ui_browser__is_current_entry(browser, row); + int i, printed; + double percent, max_percent = 0.0; + char line[256]; + + for (i = 0; i < ab->nr_events; i++) { + percent = cl->samples_sum[i].percent; + ui_browser__set_percent_color(browser, percent, current_entry); + if (percent == 0.0) { + ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); + continue; + } + + if (annotate_browser__opts.show_total_period) + ui_browser__printf(browser, "%6" PRIu64 " ", + cl->samples_sum[i].nr); + else + ui_browser__printf(browser, "%6.2f ", percent); + + if (max_percent < percent) + max_percent = percent; + } + + SLsmg_write_char(' '); + + if (annotate_browser__opts.show_linenr) + printed = scnprintf(line, sizeof(line), "%-*d ", + ab->addr_width + 2, cl->line_nr); + else + printed = scnprintf(line, sizeof(line), "%*s ", + ab->addr_width, " "); + + ui_browser__set_percent_color(browser, percent, current_entry); + ui_browser__write_nstring(browser, line, printed); + ui_browser__write_nstring(browser, cl->line, browser->width); +} + static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) { struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); @@ -284,6 +326,17 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) from, to); } +static unsigned int annotate_code_browser__refresh(struct ui_browser *browser) +{ + struct annotate_browser *ab = container_of(browser, struct annotate_browser, cb); + int ret = ui_browser__list_head_refresh(browser); + int pcnt_width = annotate_browser__pcnt_width(ab); + + ui_browser__set_color(browser, HE_COLORSET_NORMAL); + __ui_browser__vline(browser, pcnt_width, 0, browser->height - 1); + return ret; +} + static unsigned int annotate_browser__refresh(struct ui_browser *browser) { struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); @@ -394,6 +447,9 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, continue; } + if (browser->has_src_code) + source_code__set_samples(pos, notes, evsel); + next = disasm__get_next_ip_line(¬es->src->source, pos); for (i = 0; i < browser->nr_events; i++) { @@ -422,45 +478,6 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, browser->curr_hot = rb_last(&browser->entries); } -static bool annotate_browser__toggle_source(struct annotate_browser *browser) -{ - struct disasm_line *dl; - struct browser_disasm_line *bdl; - off_t offset = browser->b.index - browser->b.top_idx; - - browser->b.seek(&browser->b, offset, SEEK_CUR); - dl = list_entry(browser->b.top, struct disasm_line, node); - bdl = disasm_line__browser(dl); - - if (annotate_browser__opts.hide_src_code) { - if (bdl->idx_asm < offset) - offset = bdl->idx; - - browser->b.nr_entries = browser->nr_entries; - annotate_browser__opts.hide_src_code = false; - browser->b.seek(&browser->b, -offset, SEEK_CUR); - browser->b.top_idx = bdl->idx - offset; - browser->b.index = bdl->idx; - } else { - if (bdl->idx_asm < 0) { - ui_helpline__puts("Only available for assembly lines."); - browser->b.seek(&browser->b, -offset, SEEK_CUR); - return false; - } - - if (bdl->idx_asm < offset) - offset = bdl->idx_asm; - - browser->b.nr_entries = browser->nr_asm_entries; - annotate_browser__opts.hide_src_code = true; - browser->b.seek(&browser->b, -offset, SEEK_CUR); - browser->b.top_idx = bdl->idx_asm - offset; - browser->b.index = bdl->idx_asm; - } - - return true; -} - static void annotate_browser__init_asm_mode(struct annotate_browser *browser) { ui_browser__reset_index(&browser->b); @@ -696,6 +713,50 @@ static void annotate_browser__update_addr_width(struct annotate_browser *browser browser->addr_width += browser->jumps_width + 1; } +static int annotate_code_browser__run(struct annotate_browser *browser, + char *title, const char *help) +{ + int key; + + if (ui_browser__show(&browser->cb, title, help) < 0) + return -1; + + while (1) { + key = ui_browser__run(&browser->cb, 0); + + switch (key) { + case K_F1: + case 'h': + ui_browser__help_window(&browser->cb, + "UP/DOWN/PGUP\n" + "PGDN/SPACE Navigate\n" + "q/ESC/CTRL+C Return to dissembly view\n\n" + "ENTER Show \n" + "s Toggle source code view\n" + "t Toggle total period view\n" + "k Toggle line numbers\n"); + continue; + case 't': + annotate_browser__opts.show_total_period = + !annotate_browser__opts.show_total_period; + continue; + case 'k': + annotate_browser__opts.show_linenr = + !annotate_browser__opts.show_linenr; + continue; + case 's': + case K_LEFT: + case K_ESC: + case 'q': + case CTRL('c'): + return 0; + default: + continue; + } + } + return 0; +} + static int annotate_browser__run(struct annotate_browser *browser, struct perf_evsel *evsel, struct hist_browser_timer *hbt) @@ -775,7 +836,6 @@ static int annotate_browser__run(struct annotate_browser *browser, "s Toggle source code view\n" "t Toggle total period view\n" "/ Search string\n" - "k Toggle line numbers\n" "r Run available scripts\n" "? Search string backwards\n"); continue; @@ -792,8 +852,10 @@ static int annotate_browser__run(struct annotate_browser *browser, nd = browser->curr_hot; break; case 's': - if (annotate_browser__toggle_source(browser)) - ui_helpline__puts(help); + if (browser->has_src_code) + annotate_code_browser__run(browser, title, help); + else + ui_helpline__puts("No source code for the symbol"); continue; case 'o': annotate_browser__opts.use_offset = !annotate_browser__opts.use_offset; @@ -1095,6 +1157,27 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, browser.b.entries = ¬es->src->source, browser.b.width += 18; /* Percentage */ + browser.has_src_code = symbol__has_source_code(sym, map); + if (browser.has_src_code && + symbol__get_source_code(sym, map, evsel) != -1) { + struct source_code *code = notes->src->code; + struct code_line *cl; + + browser.cb.refresh = annotate_code_browser__refresh; + browser.cb.seek = ui_browser__list_head_seek; + browser.cb.write = annotate_code_browser__write; + browser.cb.use_navkeypressed = true; + browser.cb.entries = &code->lines; + + list_for_each_entry(cl, &code->lines, node) { + size_t line_len = strlen(cl->line); + + if (browser.cb.width < line_len) + browser.cb.width = line_len; + browser.cb.nr_entries++; + } + } + if (annotate_browser__opts.hide_src_code) annotate_browser__init_asm_mode(&browser); @@ -1105,6 +1188,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, list_del(&pos->node); disasm_line__free(pos); } + symbol__free_source_code(sym); out_free_offsets: free(browser.offsets); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 6375012..c4e4c08 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -146,6 +146,7 @@ struct annotated_source { struct list_head source; struct source_code *code; struct source_line *lines; + bool has_src_code; int nr_histograms; size_t sizeof_sym_hist; struct cyc_hist *cycles_hist; -- 2.7.4