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 @@ +// SPDX-License-Identifier: GPL-2.0  #include "../../util/util.h"  #include "../browser.h"  #include "../helpline.h" @@ -9,14 +10,16 @@  #include "../../util/symbol.h"  #include "../../util/evsel.h"  #include "../../util/config.h" +#include "../../util/evlist.h"  #include <inttypes.h>  #include <pthread.h>  #include <linux/kernel.h> +#include <linux/string.h>  #include <sys/ttydefaults.h>  struct disasm_line_samples { -	double		percent; -	u64		nr; +	double		      percent; +	struct sym_hist_entry he;  };  #define IPC_WIDTH 6 @@ -40,6 +43,7 @@ static struct annotate_browser_opt {  	     jump_arrows,  	     show_linenr,  	     show_nr_jumps, +	     show_nr_samples,  	     show_total_period;  } annotate_browser__opts = {  	.use_offset	= true, @@ -108,11 +112,12 @@ static int annotate_browser__set_jumps_percent_color(struct annotate_browser *br  static int annotate_browser__pcnt_width(struct annotate_browser *ab)  { -	int w = 7 * ab->nr_events; +	return (annotate_browser__opts.show_total_period ? 12 : 7) * ab->nr_events; +} -	if (ab->have_cycles) -		w += IPC_WIDTH + CYCLES_WIDTH; -	return w; +static int annotate_browser__cycles_width(struct annotate_browser *ab) +{ +	return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0;  }  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  			     (!current_entry || (browser->use_navkeypressed &&  					         !browser->navkeypressed)));  	int width = browser->width, printed; -	int i, pcnt_width = annotate_browser__pcnt_width(ab); +	int i, pcnt_width = annotate_browser__pcnt_width(ab), +	       cycles_width = annotate_browser__cycles_width(ab);  	double percent_max = 0.0;  	char bf[256];  	bool show_title = false; @@ -149,8 +155,11 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  						bdl->samples[i].percent,  						current_entry);  			if (annotate_browser__opts.show_total_period) { +				ui_browser__printf(browser, "%11" PRIu64 " ", +						   bdl->samples[i].he.period); +			} else if (annotate_browser__opts.show_nr_samples) {  				ui_browser__printf(browser, "%6" PRIu64 " ", -						   bdl->samples[i].nr); +						   bdl->samples[i].he.nr_samples);  			} else {  				ui_browser__printf(browser, "%6.2f ",  						   bdl->samples[i].percent); @@ -160,9 +169,12 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  		ui_browser__set_percent_color(browser, 0, current_entry);  		if (!show_title) -			ui_browser__write_nstring(browser, " ", 7 * ab->nr_events); -		else -			ui_browser__printf(browser, "%*s", 7, "Percent"); +			ui_browser__write_nstring(browser, " ", pcnt_width); +		else { +			ui_browser__printf(browser, "%*s", pcnt_width, +					   annotate_browser__opts.show_total_period ? "Period" : +					   annotate_browser__opts.show_nr_samples ? "Samples" : "Percent"); +		}  	}  	if (ab->have_cycles) {  		if (dl->ipc) @@ -188,7 +200,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  		width += 1;  	if (!*dl->line) -		ui_browser__write_nstring(browser, " ", width - pcnt_width); +		ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width);  	else if (dl->offset == -1) {  		if (dl->line_nr && annotate_browser__opts.show_linenr)  			printed = scnprintf(bf, sizeof(bf), "%-*d ", @@ -197,7 +209,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  			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 + 1); +		ui_browser__write_nstring(browser, dl->line, width - printed - pcnt_width - cycles_width + 1);  	} else {  		u64 addr = dl->offset;  		int color = -1; @@ -254,7 +266,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  		}  		disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); -		ui_browser__write_nstring(browser, bf, width - pcnt_width - 3 - printed); +		ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed);  	}  	if (current_entry) @@ -272,6 +284,25 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy  	return true;  } +static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor) +{ +	struct disasm_line *pos = list_prev_entry(cursor, node); +	const char *name; + +	if (!pos) +		return false; + +	if (ins__is_lock(&pos->ins)) +		name = pos->ops.locked.ins.name; +	else +		name = pos->ins.name; + +	if (!name || !cursor->ins.name) +		return false; + +	return ins__is_fused(ab->arch, name, cursor->ins.name); +} +  static void annotate_browser__draw_current_jump(struct ui_browser *browser)  {  	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)  	ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS);  	__ui_browser__line_arrow(browser, pcnt_width + 2 + ab->addr_width,  				 from, to); + +	if (is_fused(ab, cursor)) { +		ui_browser__mark_fused(browser, +				       pcnt_width + 3 + ab->addr_width, +				       from - 1, +				       to > from ? true : false); +	}  }  static unsigned int annotate_browser__refresh(struct ui_browser *browser) @@ -422,14 +460,14 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,  		next = disasm__get_next_ip_line(¬es->src->source, pos);  		for (i = 0; i < browser->nr_events; i++) { -			u64 nr_samples; +			struct sym_hist_entry sample;  			bpos->samples[i].percent = disasm__calc_percent(notes,  						evsel->idx + i,  						pos->offset,  						next ? next->offset : len, -						&path, &nr_samples); -			bpos->samples[i].nr = nr_samples; +						&path, &sample); +			bpos->samples[i].he = sample;  			if (max_percent < bpos->samples[i].percent)  				max_percent = bpos->samples[i].percent; @@ -792,13 +830,14 @@ static int annotate_browser__run(struct annotate_browser *browser,  		"q/ESC/CTRL+C  Exit\n\n"  		"ENTER         Go to target\n"  		"ESC           Exit\n" -		"H             Cycle thru hottest instructions\n" +		"H             Go to hottest instruction\n" +		"TAB/shift+TAB Cycle thru hottest instructions\n"  		"j             Toggle showing jump to target arrows\n"  		"J             Toggle showing number of jump sources on targets\n"  		"n             Search next string\n"  		"o             Toggle disassembler output/simplified view\n"  		"s             Toggle source code view\n" -		"t             Toggle total period view\n" +		"t             Circulate percent, total period, samples view\n"  		"/             Search string\n"  		"k             Toggle line numbers\n"  		"r             Run available scripts\n" @@ -875,8 +914,13 @@ show_sup_ins:  			}  			continue;  		case 't': -			annotate_browser__opts.show_total_period = -			  !annotate_browser__opts.show_total_period; +			if (annotate_browser__opts.show_total_period) { +				annotate_browser__opts.show_total_period = false; +				annotate_browser__opts.show_nr_samples = true; +			} else if (annotate_browser__opts.show_nr_samples) +				annotate_browser__opts.show_nr_samples = false; +			else +				annotate_browser__opts.show_total_period = true;  			annotate_browser__update_addr_width(browser);  			continue;  		case K_LEFT: @@ -899,9 +943,11 @@ out:  int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel,  			     struct hist_browser_timer *hbt)  { -	/* Set default value for show_total_period.  */ +	/* Set default value for show_total_period and show_nr_samples  */  	annotate_browser__opts.show_total_period = -	  symbol_conf.show_total_period; +		symbol_conf.show_total_period; +	annotate_browser__opts.show_nr_samples = +		symbol_conf.show_nr_samples;  	return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt);  } @@ -1074,7 +1120,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,  	}  	err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), -				  sizeof_bdl, &browser.arch); +				  sizeof_bdl, &browser.arch, +				  perf_evsel__env_cpuid(evsel));  	if (err) {  		char msg[BUFSIZ];  		symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); @@ -1151,6 +1198,7 @@ static struct annotate_config {  	ANNOTATE_CFG(jump_arrows),  	ANNOTATE_CFG(show_linenr),  	ANNOTATE_CFG(show_nr_jumps), +	ANNOTATE_CFG(show_nr_samples),  	ANNOTATE_CFG(show_total_period),  	ANNOTATE_CFG(use_offset),  }; @@ -1170,7 +1218,7 @@ static int annotate__config(const char *var, const char *value,  	struct annotate_config *cfg;  	const char *name; -	if (prefixcmp(var, "annotate.") != 0) +	if (!strstarts(var, "annotate."))  		return 0;  	name = var + 9; |