diff options
Diffstat (limited to 'tools/perf/ui/browsers')
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 31 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 87 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.h | 1 | ||||
-rw-r--r-- | tools/perf/ui/browsers/map.c | 6 |
4 files changed, 86 insertions, 39 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 4c18271c71c9..ba36aac340bc 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -213,17 +213,17 @@ 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 && dl->ins->ops->scnprintf) { - if (ins__is_jump(dl->ins)) { - bool fwd = dl->ops.target.offset > (u64)dl->offset; + 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)) { + } 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)) { + } else if (ins__is_ret(&dl->ins)) { ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); SLsmg_write_char(' '); } else { @@ -243,9 +243,10 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym) { - if (!dl || !dl->ins || !ins__is_jump(dl->ins) + if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins) || !disasm_line__has_offset(dl) - || dl->ops.target.offset >= symbol__size(sym)) + || dl->ops.target.offset < 0 + || dl->ops.target.offset >= (s64)symbol__size(sym)) return false; return true; @@ -492,7 +493,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, }; char title[SYM_TITLE_MAX_SIZE]; - if (!ins__is_call(dl->ins)) + if (!ins__is_call(&dl->ins)) return false; if (map_groups__find_ams(&target) || @@ -543,14 +544,16 @@ 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; + u64 offset; s64 idx; - if (!ins__is_jump(dl->ins)) + if (!ins__is_jump(&dl->ins)) return false; - dl = annotate_browser__find_offset(browser, dl->ops.target.offset, &idx); + offset = dl->ops.target.offset; + dl = annotate_browser__find_offset(browser, offset, &idx); if (dl == NULL) { - ui_helpline__puts("Invalid jump offset"); + ui_helpline__printf("Invalid jump offset: %" PRIx64, offset); return true; } @@ -841,9 +844,9 @@ show_help: 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) + else if (!browser->selection->ins.ops) goto show_sup_ins; - else if (ins__is_ret(browser->selection->ins)) + else if (ins__is_ret(&browser->selection->ins)) goto out; else if (!(annotate_browser__jump(browser) || annotate_browser__callq(browser, evsel, hbt))) { @@ -1050,7 +1053,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, (nr_pcnt - 1); } - err = symbol__disassemble(sym, map, sizeof_bdl); + err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), sizeof_bdl); if (err) { char msg[BUFSIZ]; symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index a53fef0c673b..fc4fb669ceee 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -30,7 +30,7 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd, static bool hist_browser__has_filter(struct hist_browser *hb) { - return hists__has_filter(hb->hists) || hb->min_pcnt || symbol_conf.has_filter; + return hists__has_filter(hb->hists) || hb->min_pcnt || symbol_conf.has_filter || hb->c2c_filter; } static int hist_browser__get_folding(struct hist_browser *browser) @@ -501,8 +501,8 @@ static int hierarchy_set_folding(struct hist_browser *hb, struct hist_entry *he, return n; } -static void hist_entry__set_folding(struct hist_entry *he, - struct hist_browser *hb, bool unfold) +static void __hist_entry__set_folding(struct hist_entry *he, + struct hist_browser *hb, bool unfold) { hist_entry__init_have_children(he); he->unfolded = unfold ? he->has_children : false; @@ -520,12 +520,34 @@ static void hist_entry__set_folding(struct hist_entry *he, he->nr_rows = 0; } +static void hist_entry__set_folding(struct hist_entry *he, + struct hist_browser *browser, bool unfold) +{ + double percent; + + percent = hist_entry__get_percent_limit(he); + if (he->filtered || percent < browser->min_pcnt) + return; + + __hist_entry__set_folding(he, browser, unfold); + + if (!he->depth || unfold) + browser->nr_hierarchy_entries++; + if (he->leaf) + browser->nr_callchain_rows += he->nr_rows; + else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { + browser->nr_hierarchy_entries++; + he->has_no_entry = true; + he->nr_rows = 1; + } else + he->has_no_entry = false; +} + static void __hist_browser__set_folding(struct hist_browser *browser, bool unfold) { struct rb_node *nd; struct hist_entry *he; - double percent; nd = rb_first(&browser->hists->entries); while (nd) { @@ -535,21 +557,6 @@ __hist_browser__set_folding(struct hist_browser *browser, bool unfold) nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD); hist_entry__set_folding(he, browser, unfold); - - percent = hist_entry__get_percent_limit(he); - if (he->filtered || percent < browser->min_pcnt) - continue; - - if (!he->depth || unfold) - browser->nr_hierarchy_entries++; - if (he->leaf) - browser->nr_callchain_rows += he->nr_rows; - else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { - browser->nr_hierarchy_entries++; - he->has_no_entry = true; - he->nr_rows = 1; - } else - he->has_no_entry = false; } } @@ -564,6 +571,15 @@ static void hist_browser__set_folding(struct hist_browser *browser, bool unfold) ui_browser__reset_index(&browser->b); } +static void hist_browser__set_folding_selected(struct hist_browser *browser, bool unfold) +{ + if (!browser->he_selection) + return; + + hist_entry__set_folding(browser->he_selection, browser, unfold); + browser->b.nr_entries = hist_browser__nr_entries(browser); +} + static void ui_browser__warn_lost_events(struct ui_browser *browser) { ui_browser__warning(browser, 4, @@ -637,10 +653,18 @@ int hist_browser__run(struct hist_browser *browser, const char *help) /* Collapse the whole world. */ hist_browser__set_folding(browser, false); break; + case 'c': + /* Collapse the selected entry. */ + hist_browser__set_folding_selected(browser, false); + break; case 'E': /* Expand the whole world. */ hist_browser__set_folding(browser, true); break; + case 'e': + /* Expand the selected entry. */ + hist_browser__set_folding_selected(browser, true); + break; case 'H': browser->show_headers = !browser->show_headers; hist_browser__update_rows(browser); @@ -738,6 +762,7 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser, struct callchain_print_arg *arg) { char bf[1024], *alloc_str; + char buf[64], *alloc_str2; const char *str; if (arg->row_offset != 0) { @@ -746,12 +771,26 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser, } alloc_str = NULL; + alloc_str2 = NULL; + str = callchain_list__sym_name(chain, bf, sizeof(bf), browser->show_dso); - if (need_percent) { - char buf[64]; + if (symbol_conf.show_branchflag_count) { + if (need_percent) + callchain_list_counts__printf_value(node, chain, NULL, + buf, sizeof(buf)); + else + callchain_list_counts__printf_value(NULL, chain, NULL, + buf, sizeof(buf)); + if (asprintf(&alloc_str2, "%s%s", str, buf) < 0) + str = "Not enough memory!"; + else + str = alloc_str2; + } + + if (need_percent) { callchain_node__scnprintf_value(node, buf, sizeof(buf), total); @@ -764,6 +803,7 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser, print(browser, chain, str, offset, row, arg); free(alloc_str); + free(alloc_str2); return 1; } @@ -2833,7 +2873,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, do_zoom_dso(browser, actions); continue; case 'V': - browser->show_dso = !browser->show_dso; + verbose = (verbose + 1) % 4; + browser->show_dso = verbose > 0; + ui_helpline__fpush("Verbosity level set to %d\n", + verbose); continue; case 't': actions->thread = thread; diff --git a/tools/perf/ui/browsers/hists.h b/tools/perf/ui/browsers/hists.h index 39bd0f28f211..23d6acb84800 100644 --- a/tools/perf/ui/browsers/hists.h +++ b/tools/perf/ui/browsers/hists.h @@ -18,6 +18,7 @@ struct hist_browser { u64 nr_non_filtered_entries; u64 nr_hierarchy_entries; u64 nr_callchain_rows; + bool c2c_filter; /* Get title string. */ int (*title)(struct hist_browser *browser, diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 98a34664bb7e..9ce142de536d 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -73,7 +73,7 @@ static int map_browser__run(struct map_browser *browser) if (ui_browser__show(&browser->b, browser->map->dso->long_name, "Press ESC to exit, %s / to search", - verbose ? "" : "restart with -v to use") < 0) + verbose > 0 ? "" : "restart with -v to use") < 0) return -1; while (1) { @@ -81,7 +81,7 @@ static int map_browser__run(struct map_browser *browser) switch (key) { case '/': - if (verbose) + if (verbose > 0) map_browser__search(browser); default: break; @@ -117,7 +117,7 @@ int map__browse(struct map *map) if (maxaddr < pos->end) maxaddr = pos->end; - if (verbose) { + if (verbose > 0) { u32 *idx = symbol__browser_index(pos); *idx = mb.b.nr_entries; } |