diff options
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 98 |
1 files changed, 73 insertions, 25 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 27f41f28dcb4..8f7f59d1a2b5 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | #include "../../util/util.h" | 2 | #include "../../util/util.h" |
2 | #include "../browser.h" | 3 | #include "../browser.h" |
3 | #include "../helpline.h" | 4 | #include "../helpline.h" |
@@ -9,14 +10,16 @@ | |||
9 | #include "../../util/symbol.h" | 10 | #include "../../util/symbol.h" |
10 | #include "../../util/evsel.h" | 11 | #include "../../util/evsel.h" |
11 | #include "../../util/config.h" | 12 | #include "../../util/config.h" |
13 | #include "../../util/evlist.h" | ||
12 | #include <inttypes.h> | 14 | #include <inttypes.h> |
13 | #include <pthread.h> | 15 | #include <pthread.h> |
14 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/string.h> | ||
15 | #include <sys/ttydefaults.h> | 18 | #include <sys/ttydefaults.h> |
16 | 19 | ||
17 | struct disasm_line_samples { | 20 | struct disasm_line_samples { |
18 | double percent; | 21 | double percent; |
19 | u64 nr; | 22 | struct sym_hist_entry he; |
20 | }; | 23 | }; |
21 | 24 | ||
22 | #define IPC_WIDTH 6 | 25 | #define IPC_WIDTH 6 |
@@ -40,6 +43,7 @@ static struct annotate_browser_opt { | |||
40 | jump_arrows, | 43 | jump_arrows, |
41 | show_linenr, | 44 | show_linenr, |
42 | show_nr_jumps, | 45 | show_nr_jumps, |
46 | show_nr_samples, | ||
43 | show_total_period; | 47 | show_total_period; |
44 | } annotate_browser__opts = { | 48 | } annotate_browser__opts = { |
45 | .use_offset = true, | 49 | .use_offset = true, |
@@ -108,11 +112,12 @@ static int annotate_browser__set_jumps_percent_color(struct annotate_browser *br | |||
108 | 112 | ||
109 | static int annotate_browser__pcnt_width(struct annotate_browser *ab) | 113 | static int annotate_browser__pcnt_width(struct annotate_browser *ab) |
110 | { | 114 | { |
111 | int w = 7 * ab->nr_events; | 115 | return (annotate_browser__opts.show_total_period ? 12 : 7) * ab->nr_events; |
116 | } | ||
112 | 117 | ||
113 | if (ab->have_cycles) | 118 | static int annotate_browser__cycles_width(struct annotate_browser *ab) |
114 | w += IPC_WIDTH + CYCLES_WIDTH; | 119 | { |
115 | return w; | 120 | return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0; |
116 | } | 121 | } |
117 | 122 | ||
118 | static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) | 123 | static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) |
@@ -125,7 +130,8 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
125 | (!current_entry || (browser->use_navkeypressed && | 130 | (!current_entry || (browser->use_navkeypressed && |
126 | !browser->navkeypressed))); | 131 | !browser->navkeypressed))); |
127 | int width = browser->width, printed; | 132 | int width = browser->width, printed; |
128 | int i, pcnt_width = annotate_browser__pcnt_width(ab); | 133 | int i, pcnt_width = annotate_browser__pcnt_width(ab), |
134 | cycles_width = annotate_browser__cycles_width(ab); | ||
129 | double percent_max = 0.0; | 135 | double percent_max = 0.0; |
130 | char bf[256]; | 136 | char bf[256]; |
131 | bool show_title = false; | 137 | bool show_title = false; |
@@ -149,8 +155,11 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
149 | bdl->samples[i].percent, | 155 | bdl->samples[i].percent, |
150 | current_entry); | 156 | current_entry); |
151 | if (annotate_browser__opts.show_total_period) { | 157 | if (annotate_browser__opts.show_total_period) { |
158 | ui_browser__printf(browser, "%11" PRIu64 " ", | ||
159 | bdl->samples[i].he.period); | ||
160 | } else if (annotate_browser__opts.show_nr_samples) { | ||
152 | ui_browser__printf(browser, "%6" PRIu64 " ", | 161 | ui_browser__printf(browser, "%6" PRIu64 " ", |
153 | bdl->samples[i].nr); | 162 | bdl->samples[i].he.nr_samples); |
154 | } else { | 163 | } else { |
155 | ui_browser__printf(browser, "%6.2f ", | 164 | ui_browser__printf(browser, "%6.2f ", |
156 | bdl->samples[i].percent); | 165 | bdl->samples[i].percent); |
@@ -160,9 +169,12 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
160 | ui_browser__set_percent_color(browser, 0, current_entry); | 169 | ui_browser__set_percent_color(browser, 0, current_entry); |
161 | 170 | ||
162 | if (!show_title) | 171 | if (!show_title) |
163 | ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); | 172 | ui_browser__write_nstring(browser, " ", pcnt_width); |
164 | else | 173 | else { |
165 | ui_browser__printf(browser, "%*s", 7, "Percent"); | 174 | ui_browser__printf(browser, "%*s", pcnt_width, |
175 | annotate_browser__opts.show_total_period ? "Period" : | ||
176 | annotate_browser__opts.show_nr_samples ? "Samples" : "Percent"); | ||
177 | } | ||
166 | } | 178 | } |
167 | if (ab->have_cycles) { | 179 | if (ab->have_cycles) { |
168 | if (dl->ipc) | 180 | if (dl->ipc) |
@@ -188,7 +200,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
188 | width += 1; | 200 | width += 1; |
189 | 201 | ||
190 | if (!*dl->line) | 202 | if (!*dl->line) |
191 | ui_browser__write_nstring(browser, " ", width - pcnt_width); | 203 | ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width); |
192 | else if (dl->offset == -1) { | 204 | else if (dl->offset == -1) { |
193 | if (dl->line_nr && annotate_browser__opts.show_linenr) | 205 | if (dl->line_nr && annotate_browser__opts.show_linenr) |
194 | printed = scnprintf(bf, sizeof(bf), "%-*d ", | 206 | printed = scnprintf(bf, sizeof(bf), "%-*d ", |
@@ -197,7 +209,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
197 | printed = scnprintf(bf, sizeof(bf), "%*s ", | 209 | printed = scnprintf(bf, sizeof(bf), "%*s ", |
198 | ab->addr_width, " "); | 210 | ab->addr_width, " "); |
199 | ui_browser__write_nstring(browser, bf, printed); | 211 | ui_browser__write_nstring(browser, bf, printed); |
200 | ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width + 1); | 212 | ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width - cycles_width + 1); |
201 | } else { | 213 | } else { |
202 | u64 addr = dl->offset; | 214 | u64 addr = dl->offset; |
203 | int color = -1; | 215 | int color = -1; |
@@ -254,7 +266,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int | |||
254 | } | 266 | } |
255 | 267 | ||
256 | disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); | 268 | disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); |
257 | ui_browser__write_nstring(browser, bf, width - pcnt_width - 3 - printed); | 269 | ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed); |
258 | } | 270 | } |
259 | 271 | ||
260 | if (current_entry) | 272 | if (current_entry) |
@@ -272,6 +284,25 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy | |||
272 | return true; | 284 | return true; |
273 | } | 285 | } |
274 | 286 | ||
287 | static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) | ||
288 | { | ||
289 | struct disasm_line *pos = list_prev_entry(cursor, node); | ||
290 | const char *name; | ||
291 | |||
292 | if (!pos) | ||
293 | return false; | ||
294 | |||
295 | if (ins__is_lock(&pos->ins)) | ||
296 | name = pos->ops.locked.ins.name; | ||
297 | else | ||
298 | name = pos->ins.name; | ||
299 | |||
300 | if (!name || !cursor->ins.name) | ||
301 | return false; | ||
302 | |||
303 | return ins__is_fused(ab->arch, name, cursor->ins.name); | ||
304 | } | ||
305 | |||
275 | static void annotate_browser__draw_current_jump(struct ui_browser *browser) | 306 | static void annotate_browser__draw_current_jump(struct ui_browser *browser) |
276 | { | 307 | { |
277 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); | 308 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); |
@@ -307,6 +338,13 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) | |||
307 | ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS); | 338 | ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS); |
308 | __ui_browser__line_arrow(browser, pcnt_width + 2 + ab->addr_width, | 339 | __ui_browser__line_arrow(browser, pcnt_width + 2 + ab->addr_width, |
309 | from, to); | 340 | from, to); |
341 | |||
342 | if (is_fused(ab, cursor)) { | ||
343 | ui_browser__mark_fused(browser, | ||
344 | pcnt_width + 3 + ab->addr_width, | ||
345 | from - 1, | ||
346 | to > from ? true : false); | ||
347 | } | ||
310 | } | 348 | } |
311 | 349 | ||
312 | static unsigned int annotate_browser__refresh(struct ui_browser *browser) | 350 | static unsigned int annotate_browser__refresh(struct ui_browser *browser) |
@@ -422,14 +460,14 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, | |||
422 | next = disasm__get_next_ip_line(¬es->src->source, pos); | 460 | next = disasm__get_next_ip_line(¬es->src->source, pos); |
423 | 461 | ||
424 | for (i = 0; i < browser->nr_events; i++) { | 462 | for (i = 0; i < browser->nr_events; i++) { |
425 | u64 nr_samples; | 463 | struct sym_hist_entry sample; |
426 | 464 | ||
427 | bpos->samples[i].percent = disasm__calc_percent(notes, | 465 | bpos->samples[i].percent = disasm__calc_percent(notes, |
428 | evsel->idx + i, | 466 | evsel->idx + i, |
429 | pos->offset, | 467 | pos->offset, |
430 | next ? next->offset : len, | 468 | next ? next->offset : len, |
431 | &path, &nr_samples); | 469 | &path, &sample); |
432 | bpos->samples[i].nr = nr_samples; | 470 | bpos->samples[i].he = sample; |
433 | 471 | ||
434 | if (max_percent < bpos->samples[i].percent) | 472 | if (max_percent < bpos->samples[i].percent) |
435 | max_percent = bpos->samples[i].percent; | 473 | max_percent = bpos->samples[i].percent; |
@@ -792,13 +830,14 @@ static int annotate_browser__run(struct annotate_browser *browser, | |||
792 | "q/ESC/CTRL+C Exit\n\n" | 830 | "q/ESC/CTRL+C Exit\n\n" |
793 | "ENTER Go to target\n" | 831 | "ENTER Go to target\n" |
794 | "ESC Exit\n" | 832 | "ESC Exit\n" |
795 | "H Cycle thru hottest instructions\n" | 833 | "H Go to hottest instruction\n" |
834 | "TAB/shift+TAB Cycle thru hottest instructions\n" | ||
796 | "j Toggle showing jump to target arrows\n" | 835 | "j Toggle showing jump to target arrows\n" |
797 | "J Toggle showing number of jump sources on targets\n" | 836 | "J Toggle showing number of jump sources on targets\n" |
798 | "n Search next string\n" | 837 | "n Search next string\n" |
799 | "o Toggle disassembler output/simplified view\n" | 838 | "o Toggle disassembler output/simplified view\n" |
800 | "s Toggle source code view\n" | 839 | "s Toggle source code view\n" |
801 | "t Toggle total period view\n" | 840 | "t Circulate percent, total period, samples view\n" |
802 | "/ Search string\n" | 841 | "/ Search string\n" |
803 | "k Toggle line numbers\n" | 842 | "k Toggle line numbers\n" |
804 | "r Run available scripts\n" | 843 | "r Run available scripts\n" |
@@ -875,8 +914,13 @@ show_sup_ins: | |||
875 | } | 914 | } |
876 | continue; | 915 | continue; |
877 | case 't': | 916 | case 't': |
878 | annotate_browser__opts.show_total_period = | 917 | if (annotate_browser__opts.show_total_period) { |
879 | !annotate_browser__opts.show_total_period; | 918 | annotate_browser__opts.show_total_period = false; |
919 | annotate_browser__opts.show_nr_samples = true; | ||
920 | } else if (annotate_browser__opts.show_nr_samples) | ||
921 | annotate_browser__opts.show_nr_samples = false; | ||
922 | else | ||
923 | annotate_browser__opts.show_total_period = true; | ||
880 | annotate_browser__update_addr_width(browser); | 924 | annotate_browser__update_addr_width(browser); |
881 | continue; | 925 | continue; |
882 | case K_LEFT: | 926 | case K_LEFT: |
@@ -899,9 +943,11 @@ out: | |||
899 | int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, | 943 | int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, |
900 | struct hist_browser_timer *hbt) | 944 | struct hist_browser_timer *hbt) |
901 | { | 945 | { |
902 | /* Set default value for show_total_period. */ | 946 | /* Set default value for show_total_period and show_nr_samples */ |
903 | annotate_browser__opts.show_total_period = | 947 | annotate_browser__opts.show_total_period = |
904 | symbol_conf.show_total_period; | 948 | symbol_conf.show_total_period; |
949 | annotate_browser__opts.show_nr_samples = | ||
950 | symbol_conf.show_nr_samples; | ||
905 | 951 | ||
906 | return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt); | 952 | return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt); |
907 | } | 953 | } |
@@ -1074,7 +1120,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, | |||
1074 | } | 1120 | } |
1075 | 1121 | ||
1076 | err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), | 1122 | err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), |
1077 | sizeof_bdl, &browser.arch); | 1123 | sizeof_bdl, &browser.arch, |
1124 | perf_evsel__env_cpuid(evsel)); | ||
1078 | if (err) { | 1125 | if (err) { |
1079 | char msg[BUFSIZ]; | 1126 | char msg[BUFSIZ]; |
1080 | symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); | 1127 | symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); |
@@ -1151,6 +1198,7 @@ static struct annotate_config { | |||
1151 | ANNOTATE_CFG(jump_arrows), | 1198 | ANNOTATE_CFG(jump_arrows), |
1152 | ANNOTATE_CFG(show_linenr), | 1199 | ANNOTATE_CFG(show_linenr), |
1153 | ANNOTATE_CFG(show_nr_jumps), | 1200 | ANNOTATE_CFG(show_nr_jumps), |
1201 | ANNOTATE_CFG(show_nr_samples), | ||
1154 | ANNOTATE_CFG(show_total_period), | 1202 | ANNOTATE_CFG(show_total_period), |
1155 | ANNOTATE_CFG(use_offset), | 1203 | ANNOTATE_CFG(use_offset), |
1156 | }; | 1204 | }; |
@@ -1170,7 +1218,7 @@ static int annotate__config(const char *var, const char *value, | |||
1170 | struct annotate_config *cfg; | 1218 | struct annotate_config *cfg; |
1171 | const char *name; | 1219 | const char *name; |
1172 | 1220 | ||
1173 | if (prefixcmp(var, "annotate.") != 0) | 1221 | if (!strstarts(var, "annotate.")) |
1174 | return 0; | 1222 | return 0; |
1175 | 1223 | ||
1176 | name = var + 9; | 1224 | name = var + 9; |