aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui/browsers/annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
-rw-r--r--tools/perf/ui/browsers/annotate.c98
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
17struct disasm_line_samples { 20struct 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
109static int annotate_browser__pcnt_width(struct annotate_browser *ab) 113static 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) 118static 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
118static void annotate_browser__write(struct ui_browser *browser, void *entry, int row) 123static 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
287static 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
275static void annotate_browser__draw_current_jump(struct ui_browser *browser) 306static 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
312static unsigned int annotate_browser__refresh(struct ui_browser *browser) 350static 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(&notes->src->source, pos); 460 next = disasm__get_next_ip_line(&notes->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:
899int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel, 943int 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;