diff options
Diffstat (limited to 'tools/perf/ui')
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 2 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 106 | ||||
-rw-r--r-- | tools/perf/ui/browsers/map.c | 4 | ||||
-rw-r--r-- | tools/perf/ui/gtk/hists.c | 2 | ||||
-rw-r--r-- | tools/perf/ui/hist.c | 21 | ||||
-rw-r--r-- | tools/perf/ui/stdio/hist.c | 82 |
6 files changed, 144 insertions, 73 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 2e2d10022355..4c18271c71c9 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -495,7 +495,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, if (!ins__is_call(dl->ins)) return false; - if (map_groups__find_ams(&target, NULL) || + if (map_groups__find_ams(&target) || map__rip_2objdump(target.map, target.map->map_ip(target.map, target.addr)) != dl->ops.target.addr) { diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 13d414384739..a53fef0c673b 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -69,8 +69,11 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb) static void hist_browser__update_rows(struct hist_browser *hb) { struct ui_browser *browser = &hb->b; - u16 header_offset = hb->show_headers ? 1 : 0, index_row; + struct hists *hists = hb->hists; + struct perf_hpp_list *hpp_list = hists->hpp_list; + u16 header_offset, index_row; + header_offset = hb->show_headers ? hpp_list->nr_header_lines : 0; browser->rows = browser->height - header_offset; /* * Verify if we were at the last line and that line isn't @@ -99,8 +102,11 @@ static void hist_browser__refresh_dimensions(struct ui_browser *browser) static void hist_browser__gotorc(struct hist_browser *browser, int row, int column) { - u16 header_offset = browser->show_headers ? 1 : 0; + struct hists *hists = browser->hists; + struct perf_hpp_list *hpp_list = hists->hpp_list; + u16 header_offset; + header_offset = browser->show_headers ? hpp_list->nr_header_lines : 0; ui_browser__gotorc(&browser->b, row + header_offset, column); } @@ -595,7 +601,8 @@ int hist_browser__run(struct hist_browser *browser, const char *help) u64 nr_entries; hbt->timer(hbt->arg); - if (hist_browser__has_filter(browser)) + if (hist_browser__has_filter(browser) || + symbol_conf.report_hierarchy) hist_browser__update_nr_entries(browser); nr_entries = hist_browser__nr_entries(browser); @@ -1074,7 +1081,7 @@ struct hpp_arg { bool current_entry; }; -static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) +int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) { struct hpp_arg *arg = hpp->ptr; int ret, len; @@ -1091,7 +1098,6 @@ static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) ret = scnprintf(hpp->buf, hpp->size, fmt, len, percent); ui_browser__printf(arg->b, "%s", hpp->buf); - advance_hpp(hpp, ret); return ret; } @@ -1331,8 +1337,8 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser, } if (first) { - ui_browser__printf(&browser->b, "%c", folded_sign); - width--; + ui_browser__printf(&browser->b, "%c ", folded_sign); + width -= 2; first = false; } else { ui_browser__printf(&browser->b, " "); @@ -1355,8 +1361,10 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser, width -= hpp.buf - s; } - ui_browser__write_nstring(&browser->b, "", hierarchy_indent); - width -= hierarchy_indent; + if (!first) { + ui_browser__write_nstring(&browser->b, "", hierarchy_indent); + width -= hierarchy_indent; + } if (column >= browser->b.horiz_scroll) { char s[2048]; @@ -1375,7 +1383,13 @@ static int hist_browser__show_hierarchy_entry(struct hist_browser *browser, } perf_hpp_list__for_each_format(entry->hpp_list, fmt) { - ui_browser__write_nstring(&browser->b, "", 2); + if (first) { + ui_browser__printf(&browser->b, "%c ", folded_sign); + first = false; + } else { + ui_browser__write_nstring(&browser->b, "", 2); + } + width -= 2; /* @@ -1496,7 +1510,9 @@ static int advance_hpp_check(struct perf_hpp *hpp, int inc) return hpp->size <= 0; } -static int hists_browser__scnprintf_headers(struct hist_browser *browser, char *buf, size_t size) +static int +hists_browser__scnprintf_headers(struct hist_browser *browser, char *buf, + size_t size, int line) { struct hists *hists = browser->hists; struct perf_hpp dummy_hpp = { @@ -1506,6 +1522,7 @@ static int hists_browser__scnprintf_headers(struct hist_browser *browser, char * struct perf_hpp_fmt *fmt; size_t ret = 0; int column = 0; + int span = 0; if (symbol_conf.use_callchain) { ret = scnprintf(buf, size, " "); @@ -1517,10 +1534,13 @@ static int hists_browser__scnprintf_headers(struct hist_browser *browser, char * if (perf_hpp__should_skip(fmt, hists) || column++ < browser->b.horiz_scroll) continue; - ret = fmt->header(fmt, &dummy_hpp, hists); + ret = fmt->header(fmt, &dummy_hpp, hists, line, &span); if (advance_hpp_check(&dummy_hpp, ret)) break; + if (span) + continue; + ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, " "); if (advance_hpp_check(&dummy_hpp, ret)) break; @@ -1543,10 +1563,11 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows int indent = hists->nr_hpp_node - 2; bool first_node, first_col; - ret = scnprintf(buf, size, " "); + ret = scnprintf(buf, size, " "); if (advance_hpp_check(&dummy_hpp, ret)) return ret; + first_node = true; /* the first hpp_list_node is for overhead columns */ fmt_node = list_first_entry(&hists->hpp_formats, struct perf_hpp_list_node, list); @@ -1554,19 +1575,23 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows if (column++ < browser->b.horiz_scroll) continue; - ret = fmt->header(fmt, &dummy_hpp, hists); + ret = fmt->header(fmt, &dummy_hpp, hists, 0, NULL); if (advance_hpp_check(&dummy_hpp, ret)) break; ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, " "); if (advance_hpp_check(&dummy_hpp, ret)) break; + + first_node = false; } - ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, "%*s", - indent * HIERARCHY_INDENT, ""); - if (advance_hpp_check(&dummy_hpp, ret)) - return ret; + if (!first_node) { + ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, "%*s", + indent * HIERARCHY_INDENT, ""); + if (advance_hpp_check(&dummy_hpp, ret)) + return ret; + } first_node = true; list_for_each_entry_continue(fmt_node, &hists->hpp_formats, list) { @@ -1591,7 +1616,7 @@ static int hists_browser__scnprintf_hierarchy_headers(struct hist_browser *brows } first_col = false; - ret = fmt->header(fmt, &dummy_hpp, hists); + ret = fmt->header(fmt, &dummy_hpp, hists, 0, NULL); dummy_hpp.buf[ret] = '\0'; start = trim(dummy_hpp.buf); @@ -1622,14 +1647,21 @@ static void hists_browser__hierarchy_headers(struct hist_browser *browser) static void hists_browser__headers(struct hist_browser *browser) { - char headers[1024]; + struct hists *hists = browser->hists; + struct perf_hpp_list *hpp_list = hists->hpp_list; - hists_browser__scnprintf_headers(browser, headers, - sizeof(headers)); + int line; - ui_browser__gotorc(&browser->b, 0, 0); - ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); - ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); + for (line = 0; line < hpp_list->nr_header_lines; line++) { + char headers[1024]; + + hists_browser__scnprintf_headers(browser, headers, + sizeof(headers), line); + + ui_browser__gotorc(&browser->b, line, 0); + ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); + ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); + } } static void hist_browser__show_headers(struct hist_browser *browser) @@ -1656,10 +1688,13 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) u16 header_offset = 0; struct rb_node *nd; struct hist_browser *hb = container_of(browser, struct hist_browser, b); + struct hists *hists = hb->hists; if (hb->show_headers) { + struct perf_hpp_list *hpp_list = hists->hpp_list; + hist_browser__show_headers(hb); - header_offset = 1; + header_offset = hpp_list->nr_header_lines; } ui_browser__hists_init_top(browser); @@ -2054,10 +2089,23 @@ void hist_browser__init(struct hist_browser *browser, browser->b.use_navkeypressed = true; browser->show_headers = symbol_conf.show_hist_headers; - hists__for_each_format(hists, fmt) { - perf_hpp__reset_width(fmt, hists); + if (symbol_conf.report_hierarchy) { + struct perf_hpp_list_node *fmt_node; + + /* count overhead columns (in the first node) */ + fmt_node = list_first_entry(&hists->hpp_formats, + struct perf_hpp_list_node, list); + perf_hpp_list__for_each_format(&fmt_node->hpp, fmt) + ++browser->b.columns; + + /* add a single column for whole hierarchy sort keys*/ ++browser->b.columns; + } else { + hists__for_each_format(hists, fmt) + ++browser->b.columns; } + + hists__reset_column_width(hists); } struct hist_browser *hist_browser__new(struct hists *hists) @@ -2418,8 +2466,6 @@ do_zoom_dso(struct hist_browser *browser, struct popup_action *act) browser->hists->dso_filter = NULL; ui_helpline__pop(); } else { - if (map == NULL) - return 0; ui_helpline__fpush("To zoom out press ESC or ENTER + \"Zoom out of %s DSO\"", __map__is_kernel(map) ? "the Kernel" : map->dso->short_name); browser->hists->dso_filter = map->dso; diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c index 80912778bb6d..98a34664bb7e 100644 --- a/tools/perf/ui/browsers/map.c +++ b/tools/perf/ui/browsers/map.c @@ -52,9 +52,9 @@ static int map_browser__search(struct map_browser *browser) if (target[0] == '0' && tolower(target[1]) == 'x') { u64 addr = strtoull(target, NULL, 16); - sym = map__find_symbol(browser->map, addr, NULL); + sym = map__find_symbol(browser->map, addr); } else - sym = map__find_symbol_by_name(browser->map, target, NULL); + sym = map__find_symbol_by_name(browser->map, target); if (sym != NULL) { u32 *idx = symbol__browser_index(sym); diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index c5f3677f6679..a4f02de7c1b5 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -549,7 +549,7 @@ static void perf_gtk__show_hierarchy(GtkWidget *window, struct hists *hists, strcat(buf, "+"); first_col = false; - fmt->header(fmt, &hpp, hists); + fmt->header(fmt, &hpp, hists, 0, NULL); strcat(buf, ltrim(rtrim(hpp.buf))); } } diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 4274969ddc89..37388397b5bc 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -230,13 +230,14 @@ static int hpp__width_fn(struct perf_hpp_fmt *fmt, } static int hpp__header_fn(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, - struct hists *hists) + struct hists *hists, int line __maybe_unused, + int *span __maybe_unused) { int len = hpp__width_fn(fmt, hpp, hists); return scnprintf(hpp->buf, hpp->size, "%*s", len, fmt->name); } -static int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...) +int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...) { va_list args; ssize_t ssize = hpp->size; @@ -441,6 +442,7 @@ struct perf_hpp_fmt perf_hpp__format[] = { struct perf_hpp_list perf_hpp_list = { .fields = LIST_HEAD_INIT(perf_hpp_list.fields), .sorts = LIST_HEAD_INIT(perf_hpp_list.sorts), + .nr_header_lines = 1, }; #undef HPP__COLOR_PRINT_FNS @@ -697,6 +699,21 @@ void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists) } } +void hists__reset_column_width(struct hists *hists) +{ + struct perf_hpp_fmt *fmt; + struct perf_hpp_list_node *node; + + hists__for_each_format(hists, fmt) + perf_hpp__reset_width(fmt, hists); + + /* hierarchy entries have their own hpp list */ + list_for_each_entry(node, &hists->hpp_formats, list) { + perf_hpp_list__for_each_format(&node->hpp, fmt) + perf_hpp__reset_width(fmt, hists); + } +} + void perf_hpp__set_user_width(const char *width_list_str) { struct perf_hpp_fmt *fmt; diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index f04a63112079..89d8441f9890 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -373,7 +373,8 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he, return 0; } -static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp) +int __hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp, + struct perf_hpp_list *hpp_list) { const char *sep = symbol_conf.field_sep; struct perf_hpp_fmt *fmt; @@ -384,7 +385,7 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp) if (symbol_conf.exclude_other && !he->parent) return 0; - hists__for_each_format(he->hists, fmt) { + perf_hpp_list__for_each_format(hpp_list, fmt) { if (perf_hpp__should_skip(fmt, he->hists)) continue; @@ -410,6 +411,11 @@ static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp) return hpp->buf - start; } +static int hist_entry__snprintf(struct hist_entry *he, struct perf_hpp *hpp) +{ + return __hist_entry__snprintf(he, hpp, he->hists->hpp_list); +} + static int hist_entry__hierarchy_fprintf(struct hist_entry *he, struct perf_hpp *hpp, struct hists *hists, @@ -528,8 +534,8 @@ static int print_hierarchy_indent(const char *sep, int indent, return fprintf(fp, "%-.*s", (indent - 2) * HIERARCHY_INDENT, line); } -static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, - const char *sep, FILE *fp) +static int hists__fprintf_hierarchy_headers(struct hists *hists, + struct perf_hpp *hpp, FILE *fp) { bool first_node, first_col; int indent; @@ -538,6 +544,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, unsigned header_width = 0; struct perf_hpp_fmt *fmt; struct perf_hpp_list_node *fmt_node; + const char *sep = symbol_conf.field_sep; indent = hists->nr_hpp_node; @@ -549,7 +556,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, struct perf_hpp_list_node, list); perf_hpp_list__for_each_format(&fmt_node->hpp, fmt) { - fmt->header(fmt, hpp, hists); + fmt->header(fmt, hpp, hists, 0, NULL); fprintf(fp, "%s%s", hpp->buf, sep ?: " "); } @@ -569,7 +576,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, header_width += fprintf(fp, "+"); first_col = false; - fmt->header(fmt, hpp, hists); + fmt->header(fmt, hpp, hists, 0, NULL); header_width += fprintf(fp, "%s", trim(hpp->buf)); } @@ -623,20 +630,28 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, return 2; } -static int -hists__fprintf_hierarchy_headers(struct hists *hists, - struct perf_hpp *hpp, - FILE *fp) +static void fprintf_line(struct hists *hists, struct perf_hpp *hpp, + int line, FILE *fp) { - struct perf_hpp_list_node *fmt_node; struct perf_hpp_fmt *fmt; + const char *sep = symbol_conf.field_sep; + bool first = true; + int span = 0; - list_for_each_entry(fmt_node, &hists->hpp_formats, list) { - perf_hpp_list__for_each_format(&fmt_node->hpp, fmt) - perf_hpp__reset_width(fmt, hists); - } + hists__for_each_format(hists, fmt) { + if (perf_hpp__should_skip(fmt, hists)) + continue; + + if (!first && !span) + fprintf(fp, "%s", sep ?: " "); + else + first = false; + + fmt->header(fmt, hpp, hists, line, &span); - return print_hierarchy_header(hists, hpp, symbol_conf.field_sep, fp); + if (!span) + fprintf(fp, "%s", hpp->buf); + } } static int @@ -644,28 +659,23 @@ hists__fprintf_standard_headers(struct hists *hists, struct perf_hpp *hpp, FILE *fp) { + struct perf_hpp_list *hpp_list = hists->hpp_list; struct perf_hpp_fmt *fmt; unsigned int width; const char *sep = symbol_conf.field_sep; bool first = true; - - hists__for_each_format(hists, fmt) { - if (perf_hpp__should_skip(fmt, hists)) - continue; - - if (!first) - fprintf(fp, "%s", sep ?: " "); - else - first = false; - - fmt->header(fmt, hpp, hists); - fprintf(fp, "%s", hpp->buf); + int line; + + for (line = 0; line < hpp_list->nr_header_lines; line++) { + /* first # is displayed one level up */ + if (line) + fprintf(fp, "# "); + fprintf_line(hists, hpp, line, fp); + fprintf(fp, "\n"); } - fprintf(fp, "\n"); - if (sep) - return 1; + return hpp_list->nr_header_lines; first = true; @@ -689,12 +699,12 @@ hists__fprintf_standard_headers(struct hists *hists, fprintf(fp, "\n"); fprintf(fp, "#\n"); - return 3; + return hpp_list->nr_header_lines + 2; } -static int hists__fprintf_headers(struct hists *hists, FILE *fp) +int hists__fprintf_headers(struct hists *hists, FILE *fp) { - char bf[96]; + char bf[1024]; struct perf_hpp dummy_hpp = { .buf = bf, .size = sizeof(bf), @@ -713,7 +723,6 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, int max_cols, float min_pcnt, FILE *fp, bool use_callchain) { - struct perf_hpp_fmt *fmt; struct rb_node *nd; size_t ret = 0; const char *sep = symbol_conf.field_sep; @@ -724,8 +733,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, init_rem_hits(); - hists__for_each_format(hists, fmt) - perf_hpp__reset_width(fmt, hists); + hists__reset_column_width(hists); if (symbol_conf.col_width_list_str) perf_hpp__set_user_width(symbol_conf.col_width_list_str); |