diff options
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 399 |
1 files changed, 197 insertions, 202 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 8f7f59d1a2b5..286427975112 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -25,16 +25,10 @@ struct disasm_line_samples { #define IPC_WIDTH 6 #define CYCLES_WIDTH 6 -struct browser_disasm_line { - struct rb_node rb_node; - u32 idx; - int idx_asm; - int jump_sources; - /* - * actual length of this array is saved on the nr_events field - * of the struct annotate_browser - */ - struct disasm_line_samples samples[1]; +struct browser_line { + u32 idx; + int idx_asm; + int jump_sources; }; static struct annotate_browser_opt { @@ -53,39 +47,43 @@ static struct annotate_browser_opt { struct arch; struct annotate_browser { - struct ui_browser b; - struct rb_root entries; - struct rb_node *curr_hot; - struct disasm_line *selection; - struct disasm_line **offsets; - struct arch *arch; - int nr_events; - u64 start; - int nr_asm_entries; - int nr_entries; - int max_jump_sources; - int nr_jumps; - bool searching_backwards; - bool have_cycles; - u8 addr_width; - u8 jumps_width; - u8 target_width; - u8 min_addr_width; - u8 max_addr_width; - char search_bf[128]; + struct ui_browser b; + struct rb_root entries; + struct rb_node *curr_hot; + struct annotation_line *selection; + struct annotation_line **offsets; + struct arch *arch; + int nr_events; + u64 start; + int nr_asm_entries; + int nr_entries; + int max_jump_sources; + int nr_jumps; + bool searching_backwards; + bool have_cycles; + u8 addr_width; + u8 jumps_width; + u8 target_width; + u8 min_addr_width; + u8 max_addr_width; + char search_bf[128]; }; -static inline struct browser_disasm_line *disasm_line__browser(struct disasm_line *dl) +static inline struct browser_line *browser_line(struct annotation_line *al) { - return (struct browser_disasm_line *)(dl + 1); + void *ptr = al; + + ptr = container_of(al, struct disasm_line, al); + return ptr - sizeof(struct browser_line); } static bool disasm_line__filter(struct ui_browser *browser __maybe_unused, void *entry) { if (annotate_browser__opts.hide_src_code) { - struct disasm_line *dl = list_entry(entry, struct disasm_line, node); - return dl->offset == -1; + struct annotation_line *al = list_entry(entry, struct annotation_line, node); + + return al->offset == -1; } return false; @@ -120,11 +118,37 @@ static int annotate_browser__cycles_width(struct annotate_browser *ab) return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0; } +static void disasm_line__write(struct disasm_line *dl, struct ui_browser *browser, + char *bf, size_t size) +{ + if (dl->ins.ops && dl->ins.ops->scnprintf) { + if (ins__is_jump(&dl->ins)) { + bool fwd = dl->ops.target.offset > dl->al.offset; + + ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR : + SLSMG_UARROW_CHAR); + SLsmg_write_char(' '); + } else if (ins__is_call(&dl->ins)) { + ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); + SLsmg_write_char(' '); + } else if (ins__is_ret(&dl->ins)) { + ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); + SLsmg_write_char(' '); + } else { + ui_browser__write_nstring(browser, " ", 2); + } + } else { + ui_browser__write_nstring(browser, " ", 2); + } + + disasm_line__scnprintf(dl, bf, size, !annotate_browser__opts.use_offset); +} + static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) { struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); - struct disasm_line *dl = list_entry(entry, struct disasm_line, node); - struct browser_disasm_line *bdl = disasm_line__browser(dl); + struct annotation_line *al = list_entry(entry, struct annotation_line, node); + struct browser_line *bl = browser_line(al); bool current_entry = ui_browser__is_current_entry(browser, row); bool change_color = (!annotate_browser__opts.hide_src_code && (!current_entry || (browser->use_navkeypressed && @@ -137,32 +161,32 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int bool show_title = false; for (i = 0; i < ab->nr_events; i++) { - if (bdl->samples[i].percent > percent_max) - percent_max = bdl->samples[i].percent; + if (al->samples[i].percent > percent_max) + percent_max = al->samples[i].percent; } - if ((row == 0) && (dl->offset == -1 || percent_max == 0.0)) { + if ((row == 0) && (al->offset == -1 || percent_max == 0.0)) { if (ab->have_cycles) { - if (dl->ipc == 0.0 && dl->cycles == 0) + if (al->ipc == 0.0 && al->cycles == 0) show_title = true; } else show_title = true; } - if (dl->offset != -1 && percent_max != 0.0) { + if (al->offset != -1 && percent_max != 0.0) { for (i = 0; i < ab->nr_events; i++) { ui_browser__set_percent_color(browser, - bdl->samples[i].percent, + al->samples[i].percent, current_entry); if (annotate_browser__opts.show_total_period) { ui_browser__printf(browser, "%11" PRIu64 " ", - bdl->samples[i].he.period); + al->samples[i].he.period); } else if (annotate_browser__opts.show_nr_samples) { ui_browser__printf(browser, "%6" PRIu64 " ", - bdl->samples[i].he.nr_samples); + al->samples[i].he.nr_samples); } else { ui_browser__printf(browser, "%6.2f ", - bdl->samples[i].percent); + al->samples[i].percent); } } } else { @@ -177,16 +201,16 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int } } if (ab->have_cycles) { - if (dl->ipc) - ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc); + if (al->ipc) + ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, al->ipc); else if (!show_title) ui_browser__write_nstring(browser, " ", IPC_WIDTH); else ui_browser__printf(browser, "%*s ", IPC_WIDTH - 1, "IPC"); - if (dl->cycles) + if (al->cycles) ui_browser__printf(browser, "%*" PRIu64 " ", - CYCLES_WIDTH - 1, dl->cycles); + CYCLES_WIDTH - 1, al->cycles); else if (!show_title) ui_browser__write_nstring(browser, " ", CYCLES_WIDTH); else @@ -199,19 +223,19 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int if (!browser->navkeypressed) width += 1; - if (!*dl->line) + if (!*al->line) ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width); - else if (dl->offset == -1) { - if (dl->line_nr && annotate_browser__opts.show_linenr) + else if (al->offset == -1) { + if (al->line_nr && annotate_browser__opts.show_linenr) printed = scnprintf(bf, sizeof(bf), "%-*d ", - ab->addr_width + 1, dl->line_nr); + ab->addr_width + 1, al->line_nr); else printed = scnprintf(bf, sizeof(bf), "%*s ", ab->addr_width, " "); ui_browser__write_nstring(browser, bf, printed); - ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width - cycles_width + 1); + ui_browser__write_nstring(browser, al->line, width - printed - pcnt_width - cycles_width + 1); } else { - u64 addr = dl->offset; + u64 addr = al->offset; int color = -1; if (!annotate_browser__opts.use_offset) @@ -220,13 +244,13 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int if (!annotate_browser__opts.use_offset) { printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); } else { - if (bdl->jump_sources) { + if (bl->jump_sources) { if (annotate_browser__opts.show_nr_jumps) { int prev; printed = scnprintf(bf, sizeof(bf), "%*d ", ab->jumps_width, - bdl->jump_sources); - prev = annotate_browser__set_jumps_percent_color(ab, bdl->jump_sources, + bl->jump_sources); + prev = annotate_browser__set_jumps_percent_color(ab, bl->jump_sources, current_entry); ui_browser__write_nstring(browser, bf, printed); ui_browser__set_color(browser, prev); @@ -245,32 +269,14 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int ui_browser__write_nstring(browser, bf, printed); if (change_color) ui_browser__set_color(browser, color); - if (dl->ins.ops && dl->ins.ops->scnprintf) { - if (ins__is_jump(&dl->ins)) { - bool fwd = dl->ops.target.offset > dl->offset; - - ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR : - SLSMG_UARROW_CHAR); - SLsmg_write_char(' '); - } else if (ins__is_call(&dl->ins)) { - ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); - SLsmg_write_char(' '); - } else if (ins__is_ret(&dl->ins)) { - ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); - SLsmg_write_char(' '); - } else { - ui_browser__write_nstring(browser, " ", 2); - } - } else { - ui_browser__write_nstring(browser, " ", 2); - } - disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); + disasm_line__write(disasm_line(al), browser, bf, sizeof(bf)); + ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed); } if (current_entry) - ab->selection = dl; + ab->selection = al; } static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym) @@ -286,7 +292,7 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) { - struct disasm_line *pos = list_prev_entry(cursor, node); + struct disasm_line *pos = list_prev_entry(cursor, al.node); const char *name; if (!pos) @@ -306,8 +312,9 @@ static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) static void annotate_browser__draw_current_jump(struct ui_browser *browser) { struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); - struct disasm_line *cursor = ab->selection, *target; - struct browser_disasm_line *btarget, *bcursor; + struct disasm_line *cursor = disasm_line(ab->selection); + struct annotation_line *target; + struct browser_line *btarget, *bcursor; unsigned int from, to; struct map_symbol *ms = ab->b.priv; struct symbol *sym = ms->sym; @@ -321,11 +328,9 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) return; target = ab->offsets[cursor->ops.target.offset]; - if (!target) - return; - bcursor = disasm_line__browser(cursor); - btarget = disasm_line__browser(target); + bcursor = browser_line(&cursor->al); + btarget = browser_line(target); if (annotate_browser__opts.hide_src_code) { from = bcursor->idx_asm; @@ -361,12 +366,11 @@ static unsigned int annotate_browser__refresh(struct ui_browser *browser) return ret; } -static int disasm__cmp(struct browser_disasm_line *a, - struct browser_disasm_line *b, int nr_pcnt) +static int disasm__cmp(struct annotation_line *a, struct annotation_line *b) { int i; - for (i = 0; i < nr_pcnt; i++) { + for (i = 0; i < a->samples_nr; i++) { if (a->samples[i].percent == b->samples[i].percent) continue; return a->samples[i].percent < b->samples[i].percent; @@ -374,28 +378,27 @@ static int disasm__cmp(struct browser_disasm_line *a, return 0; } -static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_line *bdl, - int nr_events) +static void disasm_rb_tree__insert(struct rb_root *root, struct annotation_line *al) { struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; - struct browser_disasm_line *l; + struct annotation_line *l; while (*p != NULL) { parent = *p; - l = rb_entry(parent, struct browser_disasm_line, rb_node); + l = rb_entry(parent, struct annotation_line, rb_node); - if (disasm__cmp(bdl, l, nr_events)) + if (disasm__cmp(al, l)) p = &(*p)->rb_left; else p = &(*p)->rb_right; } - rb_link_node(&bdl->rb_node, parent, p); - rb_insert_color(&bdl->rb_node, root); + rb_link_node(&al->rb_node, parent, p); + rb_insert_color(&al->rb_node, root); } static void annotate_browser__set_top(struct annotate_browser *browser, - struct disasm_line *pos, u32 idx) + struct annotation_line *pos, u32 idx) { unsigned back; @@ -404,7 +407,7 @@ static void annotate_browser__set_top(struct annotate_browser *browser, browser->b.top_idx = browser->b.index = idx; while (browser->b.top_idx != 0 && back != 0) { - pos = list_entry(pos->node.prev, struct disasm_line, node); + pos = list_entry(pos->node.prev, struct annotation_line, node); if (disasm_line__filter(&browser->b, &pos->node)) continue; @@ -420,12 +423,13 @@ static void annotate_browser__set_top(struct annotate_browser *browser, static void annotate_browser__set_rb_top(struct annotate_browser *browser, struct rb_node *nd) { - struct browser_disasm_line *bpos; - struct disasm_line *pos; + struct browser_line *bpos; + struct annotation_line *pos; u32 idx; - bpos = rb_entry(nd, struct browser_disasm_line, rb_node); - pos = ((struct disasm_line *)bpos) - 1; + pos = rb_entry(nd, struct annotation_line, rb_node); + bpos = browser_line(pos); + idx = bpos->idx; if (annotate_browser__opts.hide_src_code) idx = bpos->idx_asm; @@ -439,46 +443,35 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, struct map_symbol *ms = browser->b.priv; struct symbol *sym = ms->sym; struct annotation *notes = symbol__annotation(sym); - struct disasm_line *pos, *next; - s64 len = symbol__size(sym); + struct disasm_line *pos; browser->entries = RB_ROOT; pthread_mutex_lock(¬es->lock); - list_for_each_entry(pos, ¬es->src->source, node) { - struct browser_disasm_line *bpos = disasm_line__browser(pos); - const char *path = NULL; + symbol__calc_percent(sym, evsel); + + list_for_each_entry(pos, ¬es->src->source, al.node) { double max_percent = 0.0; int i; - if (pos->offset == -1) { - RB_CLEAR_NODE(&bpos->rb_node); + if (pos->al.offset == -1) { + RB_CLEAR_NODE(&pos->al.rb_node); continue; } - next = disasm__get_next_ip_line(¬es->src->source, pos); - - for (i = 0; i < browser->nr_events; i++) { - struct sym_hist_entry sample; - - bpos->samples[i].percent = disasm__calc_percent(notes, - evsel->idx + i, - pos->offset, - next ? next->offset : len, - &path, &sample); - bpos->samples[i].he = sample; + for (i = 0; i < pos->al.samples_nr; i++) { + struct annotation_data *sample = &pos->al.samples[i]; - if (max_percent < bpos->samples[i].percent) - max_percent = bpos->samples[i].percent; + if (max_percent < sample->percent) + max_percent = sample->percent; } - if (max_percent < 0.01 && pos->ipc == 0) { - RB_CLEAR_NODE(&bpos->rb_node); + if (max_percent < 0.01 && pos->al.ipc == 0) { + RB_CLEAR_NODE(&pos->al.rb_node); continue; } - disasm_rb_tree__insert(&browser->entries, bpos, - browser->nr_events); + disasm_rb_tree__insert(&browser->entries, &pos->al); } pthread_mutex_unlock(¬es->lock); @@ -487,38 +480,38 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, static bool annotate_browser__toggle_source(struct annotate_browser *browser) { - struct disasm_line *dl; - struct browser_disasm_line *bdl; + struct annotation_line *al; + struct browser_line *bl; 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); + al = list_entry(browser->b.top, struct annotation_line, node); + bl = browser_line(al); if (annotate_browser__opts.hide_src_code) { - if (bdl->idx_asm < offset) - offset = bdl->idx; + if (bl->idx_asm < offset) + offset = bl->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; + browser->b.top_idx = bl->idx - offset; + browser->b.index = bl->idx; } else { - if (bdl->idx_asm < 0) { + if (bl->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; + if (bl->idx_asm < offset) + offset = bl->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; + browser->b.top_idx = bl->idx_asm - offset; + browser->b.index = bl->idx_asm; } return true; @@ -543,7 +536,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, struct hist_browser_timer *hbt) { struct map_symbol *ms = browser->b.priv; - struct disasm_line *dl = browser->selection; + struct disasm_line *dl = disasm_line(browser->selection); struct annotation *notes; struct addr_map_symbol target = { .map = ms->map, @@ -589,10 +582,10 @@ struct disasm_line *annotate_browser__find_offset(struct annotate_browser *brows struct disasm_line *pos; *idx = 0; - list_for_each_entry(pos, ¬es->src->source, node) { - if (pos->offset == offset) + list_for_each_entry(pos, ¬es->src->source, al.node) { + if (pos->al.offset == offset) return pos; - if (!disasm_line__filter(&browser->b, &pos->node)) + if (!disasm_line__filter(&browser->b, &pos->al.node)) ++*idx; } @@ -601,7 +594,7 @@ struct disasm_line *annotate_browser__find_offset(struct annotate_browser *brows static bool annotate_browser__jump(struct annotate_browser *browser) { - struct disasm_line *dl = browser->selection; + struct disasm_line *dl = disasm_line(browser->selection); u64 offset; s64 idx; @@ -615,29 +608,29 @@ static bool annotate_browser__jump(struct annotate_browser *browser) return true; } - annotate_browser__set_top(browser, dl, idx); + annotate_browser__set_top(browser, &dl->al, idx); return true; } static -struct disasm_line *annotate_browser__find_string(struct annotate_browser *browser, +struct annotation_line *annotate_browser__find_string(struct annotate_browser *browser, char *s, s64 *idx) { struct map_symbol *ms = browser->b.priv; struct symbol *sym = ms->sym; struct annotation *notes = symbol__annotation(sym); - struct disasm_line *pos = browser->selection; + struct annotation_line *al = browser->selection; *idx = browser->b.index; - list_for_each_entry_continue(pos, ¬es->src->source, node) { - if (disasm_line__filter(&browser->b, &pos->node)) + list_for_each_entry_continue(al, ¬es->src->source, node) { + if (disasm_line__filter(&browser->b, &al->node)) continue; ++*idx; - if (pos->line && strstr(pos->line, s) != NULL) - return pos; + if (al->line && strstr(al->line, s) != NULL) + return al; } return NULL; @@ -645,38 +638,38 @@ struct disasm_line *annotate_browser__find_string(struct annotate_browser *brows static bool __annotate_browser__search(struct annotate_browser *browser) { - struct disasm_line *dl; + struct annotation_line *al; s64 idx; - dl = annotate_browser__find_string(browser, browser->search_bf, &idx); - if (dl == NULL) { + al = annotate_browser__find_string(browser, browser->search_bf, &idx); + if (al == NULL) { ui_helpline__puts("String not found!"); return false; } - annotate_browser__set_top(browser, dl, idx); + annotate_browser__set_top(browser, al, idx); browser->searching_backwards = false; return true; } static -struct disasm_line *annotate_browser__find_string_reverse(struct annotate_browser *browser, +struct annotation_line *annotate_browser__find_string_reverse(struct annotate_browser *browser, char *s, s64 *idx) { struct map_symbol *ms = browser->b.priv; struct symbol *sym = ms->sym; struct annotation *notes = symbol__annotation(sym); - struct disasm_line *pos = browser->selection; + struct annotation_line *al = browser->selection; *idx = browser->b.index; - list_for_each_entry_continue_reverse(pos, ¬es->src->source, node) { - if (disasm_line__filter(&browser->b, &pos->node)) + list_for_each_entry_continue_reverse(al, ¬es->src->source, node) { + if (disasm_line__filter(&browser->b, &al->node)) continue; --*idx; - if (pos->line && strstr(pos->line, s) != NULL) - return pos; + if (al->line && strstr(al->line, s) != NULL) + return al; } return NULL; @@ -684,16 +677,16 @@ struct disasm_line *annotate_browser__find_string_reverse(struct annotate_browse static bool __annotate_browser__search_reverse(struct annotate_browser *browser) { - struct disasm_line *dl; + struct annotation_line *al; s64 idx; - dl = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); - if (dl == NULL) { + al = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); + if (al == NULL) { ui_helpline__puts("String not found!"); return false; } - annotate_browser__set_top(browser, dl, idx); + annotate_browser__set_top(browser, al, idx); browser->searching_backwards = true; return true; } @@ -899,13 +892,16 @@ show_help: continue; case K_ENTER: case K_RIGHT: + { + struct disasm_line *dl = disasm_line(browser->selection); + if (browser->selection == NULL) ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); else if (browser->selection->offset == -1) ui_helpline__puts("Actions are only available for assembly lines."); - else if (!browser->selection->ins.ops) + else if (!dl->ins.ops) goto show_sup_ins; - else if (ins__is_ret(&browser->selection->ins)) + else if (ins__is_ret(&dl->ins)) goto out; else if (!(annotate_browser__jump(browser) || annotate_browser__callq(browser, evsel, hbt))) { @@ -913,6 +909,7 @@ show_sup_ins: ui_helpline__puts("Actions are only available for function call/return & jump/branch instructions."); } continue; + } case 't': if (annotate_browser__opts.show_total_period) { annotate_browser__opts.show_total_period = false; @@ -990,10 +987,10 @@ static void count_and_fill(struct annotate_browser *browser, u64 start, u64 end, return; for (offset = start; offset <= end; offset++) { - struct disasm_line *dl = browser->offsets[offset]; + struct annotation_line *al = browser->offsets[offset]; - if (dl) - dl->ipc = ipc; + if (al) + al->ipc = ipc; } } } @@ -1018,13 +1015,13 @@ static void annotate__compute_ipc(struct annotate_browser *browser, size_t size, ch = ¬es->src->cycles_hist[offset]; if (ch && ch->cycles) { - struct disasm_line *dl; + struct annotation_line *al; if (ch->have_start) count_and_fill(browser, ch->start, offset, ch); - dl = browser->offsets[offset]; - if (dl && ch->num_aggr) - dl->cycles = ch->cycles_aggr / ch->num_aggr; + al = browser->offsets[offset]; + if (al && ch->num_aggr) + al->cycles = ch->cycles_aggr / ch->num_aggr; browser->have_cycles = true; } } @@ -1043,23 +1040,27 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser return; for (offset = 0; offset < size; ++offset) { - struct disasm_line *dl = browser->offsets[offset], *dlt; - struct browser_disasm_line *bdlt; + struct annotation_line *al = browser->offsets[offset]; + struct disasm_line *dl; + struct browser_line *blt; + + dl = disasm_line(al); if (!disasm_line__is_valid_jump(dl, sym)) continue; - dlt = browser->offsets[dl->ops.target.offset]; + al = browser->offsets[dl->ops.target.offset]; + /* * FIXME: Oops, no jump target? Buggy disassembler? Or do we * have to adjust to the previous offset? */ - if (dlt == NULL) + if (al == NULL) continue; - bdlt = disasm_line__browser(dlt); - if (++bdlt->jump_sources > browser->max_jump_sources) - browser->max_jump_sources = bdlt->jump_sources; + blt = browser_line(al); + if (++blt->jump_sources > browser->max_jump_sources) + browser->max_jump_sources = blt->jump_sources; ++browser->nr_jumps; } @@ -1078,7 +1079,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct hist_browser_timer *hbt) { - struct disasm_line *pos, *n; + struct annotation_line *al; struct annotation *notes; size_t size; struct map_symbol ms = { @@ -1097,7 +1098,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, }; int ret = -1, err; int nr_pcnt = 1; - size_t sizeof_bdl = sizeof(struct browser_disasm_line); if (sym == NULL) return -1; @@ -1107,21 +1107,16 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, if (map->dso->annotate_warned) return -1; - browser.offsets = zalloc(size * sizeof(struct disasm_line *)); + browser.offsets = zalloc(size * sizeof(struct annotation_line *)); if (browser.offsets == NULL) { ui__error("Not enough memory!"); return -1; } - if (perf_evsel__is_group_event(evsel)) { + if (perf_evsel__is_group_event(evsel)) nr_pcnt = evsel->nr_members; - sizeof_bdl += sizeof(struct disasm_line_samples) * - (nr_pcnt - 1); - } - err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), - sizeof_bdl, &browser.arch, - perf_evsel__env_cpuid(evsel)); + err = symbol__annotate(sym, map, evsel, sizeof(struct browser_line), &browser.arch); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); @@ -1129,20 +1124,22 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, goto out_free_offsets; } + symbol__calc_percent(sym, evsel); + ui_helpline__push("Press ESC to exit"); notes = symbol__annotation(sym); browser.start = map__rip_2objdump(map, sym->start); - list_for_each_entry(pos, ¬es->src->source, node) { - struct browser_disasm_line *bpos; - size_t line_len = strlen(pos->line); + list_for_each_entry(al, ¬es->src->source, node) { + struct browser_line *bpos; + size_t line_len = strlen(al->line); if (browser.b.width < line_len) browser.b.width = line_len; - bpos = disasm_line__browser(pos); + bpos = browser_line(al); bpos->idx = browser.nr_entries++; - if (pos->offset != -1) { + if (al->offset != -1) { bpos->idx_asm = browser.nr_asm_entries++; /* * FIXME: short term bandaid to cope with assembly @@ -1151,8 +1148,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, * * E.g. copy_user_generic_unrolled */ - if (pos->offset < (s64)size) - browser.offsets[pos->offset] = pos; + if (al->offset < (s64)size) + browser.offsets[al->offset] = al; } else bpos->idx_asm = -1; } @@ -1174,10 +1171,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, annotate_browser__update_addr_width(&browser); ret = annotate_browser__run(&browser, evsel, hbt); - list_for_each_entry_safe(pos, n, ¬es->src->source, node) { - list_del(&pos->node); - disasm_line__free(pos); - } + + annotated_source__purge(notes->src); out_free_offsets: free(browser.offsets); |