diff options
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
| -rw-r--r-- | tools/perf/ui/browsers/annotate.c | 399 | 
1 files changed, 197 insertions, 202 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 8f7f59d1a2b5..286427975112 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -25,16 +25,10 @@ struct disasm_line_samples {  #define IPC_WIDTH 6  #define CYCLES_WIDTH 6 -struct browser_disasm_line { -	struct rb_node			rb_node; -	u32				idx; -	int				idx_asm; -	int				jump_sources; -	/* -	 * actual length of this array is saved on the nr_events field -	 * of the struct annotate_browser -	 */ -	struct disasm_line_samples	samples[1]; +struct browser_line { +	u32	idx; +	int	idx_asm; +	int	jump_sources;  };  static struct annotate_browser_opt { @@ -53,39 +47,43 @@ static struct annotate_browser_opt {  struct arch;  struct annotate_browser { -	struct ui_browser b; -	struct rb_root	  entries; -	struct rb_node	  *curr_hot; -	struct disasm_line  *selection; -	struct disasm_line  **offsets; -	struct arch	    *arch; -	int		    nr_events; -	u64		    start; -	int		    nr_asm_entries; -	int		    nr_entries; -	int		    max_jump_sources; -	int		    nr_jumps; -	bool		    searching_backwards; -	bool		    have_cycles; -	u8		    addr_width; -	u8		    jumps_width; -	u8		    target_width; -	u8		    min_addr_width; -	u8		    max_addr_width; -	char		    search_bf[128]; +	struct ui_browser	    b; +	struct rb_root		    entries; +	struct rb_node		   *curr_hot; +	struct annotation_line	   *selection; +	struct annotation_line	  **offsets; +	struct arch		   *arch; +	int			    nr_events; +	u64			    start; +	int			    nr_asm_entries; +	int			    nr_entries; +	int			    max_jump_sources; +	int			    nr_jumps; +	bool			    searching_backwards; +	bool			    have_cycles; +	u8			    addr_width; +	u8			    jumps_width; +	u8			    target_width; +	u8			    min_addr_width; +	u8			    max_addr_width; +	char			    search_bf[128];  }; -static inline struct browser_disasm_line *disasm_line__browser(struct disasm_line *dl) +static inline struct browser_line *browser_line(struct annotation_line *al)  { -	return (struct browser_disasm_line *)(dl + 1); +	void *ptr = al; + +	ptr = container_of(al, struct disasm_line, al); +	return ptr - sizeof(struct browser_line);  }  static bool disasm_line__filter(struct ui_browser *browser __maybe_unused,  				void *entry)  {  	if (annotate_browser__opts.hide_src_code) { -		struct disasm_line *dl = list_entry(entry, struct disasm_line, node); -		return dl->offset == -1; +		struct annotation_line *al = list_entry(entry, struct annotation_line, node); + +		return al->offset == -1;  	}  	return false; @@ -120,11 +118,37 @@ static int annotate_browser__cycles_width(struct annotate_browser *ab)  	return ab->have_cycles ? IPC_WIDTH + CYCLES_WIDTH : 0;  } +static void disasm_line__write(struct disasm_line *dl, struct ui_browser *browser, +			       char *bf, size_t size) +{ +	if (dl->ins.ops && dl->ins.ops->scnprintf) { +		if (ins__is_jump(&dl->ins)) { +			bool fwd = dl->ops.target.offset > dl->al.offset; + +			ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR : +							    SLSMG_UARROW_CHAR); +			SLsmg_write_char(' '); +		} 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)) { +			ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); +			SLsmg_write_char(' '); +		} else { +			ui_browser__write_nstring(browser, " ", 2); +		} +	} else { +		ui_browser__write_nstring(browser, " ", 2); +	} + +	disasm_line__scnprintf(dl, bf, size, !annotate_browser__opts.use_offset); +} +  static void annotate_browser__write(struct ui_browser *browser, void *entry, int row)  {  	struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); -	struct disasm_line *dl = list_entry(entry, struct disasm_line, node); -	struct browser_disasm_line *bdl = disasm_line__browser(dl); +	struct annotation_line *al = list_entry(entry, struct annotation_line, node); +	struct browser_line *bl = browser_line(al);  	bool current_entry = ui_browser__is_current_entry(browser, row);  	bool change_color = (!annotate_browser__opts.hide_src_code &&  			     (!current_entry || (browser->use_navkeypressed && @@ -137,32 +161,32 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  	bool show_title = false;  	for (i = 0; i < ab->nr_events; i++) { -		if (bdl->samples[i].percent > percent_max) -			percent_max = bdl->samples[i].percent; +		if (al->samples[i].percent > percent_max) +			percent_max = al->samples[i].percent;  	} -	if ((row == 0) && (dl->offset == -1 || percent_max == 0.0)) { +	if ((row == 0) && (al->offset == -1 || percent_max == 0.0)) {  		if (ab->have_cycles) { -			if (dl->ipc == 0.0 && dl->cycles == 0) +			if (al->ipc == 0.0 && al->cycles == 0)  				show_title = true;  		} else  			show_title = true;  	} -	if (dl->offset != -1 && percent_max != 0.0) { +	if (al->offset != -1 && percent_max != 0.0) {  		for (i = 0; i < ab->nr_events; i++) {  			ui_browser__set_percent_color(browser, -						bdl->samples[i].percent, +						al->samples[i].percent,  						current_entry);  			if (annotate_browser__opts.show_total_period) {  				ui_browser__printf(browser, "%11" PRIu64 " ", -						   bdl->samples[i].he.period); +						   al->samples[i].he.period);  			} else if (annotate_browser__opts.show_nr_samples) {  				ui_browser__printf(browser, "%6" PRIu64 " ", -						   bdl->samples[i].he.nr_samples); +						   al->samples[i].he.nr_samples);  			} else {  				ui_browser__printf(browser, "%6.2f ", -						   bdl->samples[i].percent); +						   al->samples[i].percent);  			}  		}  	} else { @@ -177,16 +201,16 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  		}  	}  	if (ab->have_cycles) { -		if (dl->ipc) -			ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, dl->ipc); +		if (al->ipc) +			ui_browser__printf(browser, "%*.2f ", IPC_WIDTH - 1, al->ipc);  		else if (!show_title)  			ui_browser__write_nstring(browser, " ", IPC_WIDTH);  		else  			ui_browser__printf(browser, "%*s ", IPC_WIDTH - 1, "IPC"); -		if (dl->cycles) +		if (al->cycles)  			ui_browser__printf(browser, "%*" PRIu64 " ", -					   CYCLES_WIDTH - 1, dl->cycles); +					   CYCLES_WIDTH - 1, al->cycles);  		else if (!show_title)  			ui_browser__write_nstring(browser, " ", CYCLES_WIDTH);  		else @@ -199,19 +223,19 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  	if (!browser->navkeypressed)  		width += 1; -	if (!*dl->line) +	if (!*al->line)  		ui_browser__write_nstring(browser, " ", width - pcnt_width - cycles_width); -	else if (dl->offset == -1) { -		if (dl->line_nr && annotate_browser__opts.show_linenr) +	else if (al->offset == -1) { +		if (al->line_nr && annotate_browser__opts.show_linenr)  			printed = scnprintf(bf, sizeof(bf), "%-*d ", -					ab->addr_width + 1, dl->line_nr); +					ab->addr_width + 1, al->line_nr);  		else  			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 - cycles_width + 1); +		ui_browser__write_nstring(browser, al->line, width - printed - pcnt_width - cycles_width + 1);  	} else { -		u64 addr = dl->offset; +		u64 addr = al->offset;  		int color = -1;  		if (!annotate_browser__opts.use_offset) @@ -220,13 +244,13 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int  		if (!annotate_browser__opts.use_offset) {  			printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);  		} else { -			if (bdl->jump_sources) { +			if (bl->jump_sources) {  				if (annotate_browser__opts.show_nr_jumps) {  					int prev;  					printed = scnprintf(bf, sizeof(bf), "%*d ",  							    ab->jumps_width, -							    bdl->jump_sources); -					prev = annotate_browser__set_jumps_percent_color(ab, bdl->jump_sources, +							    bl->jump_sources); +					prev = annotate_browser__set_jumps_percent_color(ab, bl->jump_sources,  											 current_entry);  					ui_browser__write_nstring(browser, bf, printed);  					ui_browser__set_color(browser, prev); @@ -245,32 +269,14 @@ 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.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)) { -				ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); -				SLsmg_write_char(' '); -			} else if (ins__is_ret(&dl->ins)) { -				ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); -				SLsmg_write_char(' '); -			} else { -				ui_browser__write_nstring(browser, " ", 2); -			} -		} else { -			ui_browser__write_nstring(browser, " ", 2); -		} -		disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); +		disasm_line__write(disasm_line(al), browser, bf, sizeof(bf)); +  		ui_browser__write_nstring(browser, bf, width - pcnt_width - cycles_width - 3 - printed);  	}  	if (current_entry) -		ab->selection = dl; +		ab->selection = al;  }  static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym) @@ -286,7 +292,7 @@ static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sy  static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor)  { -	struct disasm_line *pos = list_prev_entry(cursor, node); +	struct disasm_line *pos = list_prev_entry(cursor, al.node);  	const char *name;  	if (!pos) @@ -306,8 +312,9 @@ static bool is_fused(struct annotate_browser *ab, struct disasm_line *cursor)  static void annotate_browser__draw_current_jump(struct ui_browser *browser)  {  	struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); -	struct disasm_line *cursor = ab->selection, *target; -	struct browser_disasm_line *btarget, *bcursor; +	struct disasm_line *cursor = disasm_line(ab->selection); +	struct annotation_line *target; +	struct browser_line *btarget, *bcursor;  	unsigned int from, to;  	struct map_symbol *ms = ab->b.priv;  	struct symbol *sym = ms->sym; @@ -321,11 +328,9 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)  		return;  	target = ab->offsets[cursor->ops.target.offset]; -	if (!target) -		return; -	bcursor = disasm_line__browser(cursor); -	btarget = disasm_line__browser(target); +	bcursor = browser_line(&cursor->al); +	btarget = browser_line(target);  	if (annotate_browser__opts.hide_src_code) {  		from = bcursor->idx_asm; @@ -361,12 +366,11 @@ static unsigned int annotate_browser__refresh(struct ui_browser *browser)  	return ret;  } -static int disasm__cmp(struct browser_disasm_line *a, -		       struct browser_disasm_line *b, int nr_pcnt) +static int disasm__cmp(struct annotation_line *a, struct annotation_line *b)  {  	int i; -	for (i = 0; i < nr_pcnt; i++) { +	for (i = 0; i < a->samples_nr; i++) {  		if (a->samples[i].percent == b->samples[i].percent)  			continue;  		return a->samples[i].percent < b->samples[i].percent; @@ -374,28 +378,27 @@ static int disasm__cmp(struct browser_disasm_line *a,  	return 0;  } -static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_line *bdl, -				   int nr_events) +static void disasm_rb_tree__insert(struct rb_root *root, struct annotation_line *al)  {  	struct rb_node **p = &root->rb_node;  	struct rb_node *parent = NULL; -	struct browser_disasm_line *l; +	struct annotation_line *l;  	while (*p != NULL) {  		parent = *p; -		l = rb_entry(parent, struct browser_disasm_line, rb_node); +		l = rb_entry(parent, struct annotation_line, rb_node); -		if (disasm__cmp(bdl, l, nr_events)) +		if (disasm__cmp(al, l))  			p = &(*p)->rb_left;  		else  			p = &(*p)->rb_right;  	} -	rb_link_node(&bdl->rb_node, parent, p); -	rb_insert_color(&bdl->rb_node, root); +	rb_link_node(&al->rb_node, parent, p); +	rb_insert_color(&al->rb_node, root);  }  static void annotate_browser__set_top(struct annotate_browser *browser, -				      struct disasm_line *pos, u32 idx) +				      struct annotation_line *pos, u32 idx)  {  	unsigned back; @@ -404,7 +407,7 @@ static void annotate_browser__set_top(struct annotate_browser *browser,  	browser->b.top_idx = browser->b.index = idx;  	while (browser->b.top_idx != 0 && back != 0) { -		pos = list_entry(pos->node.prev, struct disasm_line, node); +		pos = list_entry(pos->node.prev, struct annotation_line, node);  		if (disasm_line__filter(&browser->b, &pos->node))  			continue; @@ -420,12 +423,13 @@ static void annotate_browser__set_top(struct annotate_browser *browser,  static void annotate_browser__set_rb_top(struct annotate_browser *browser,  					 struct rb_node *nd)  { -	struct browser_disasm_line *bpos; -	struct disasm_line *pos; +	struct browser_line *bpos; +	struct annotation_line *pos;  	u32 idx; -	bpos = rb_entry(nd, struct browser_disasm_line, rb_node); -	pos = ((struct disasm_line *)bpos) - 1; +	pos = rb_entry(nd, struct annotation_line, rb_node); +	bpos = browser_line(pos); +  	idx = bpos->idx;  	if (annotate_browser__opts.hide_src_code)  		idx = bpos->idx_asm; @@ -439,46 +443,35 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,  	struct map_symbol *ms = browser->b.priv;  	struct symbol *sym = ms->sym;  	struct annotation *notes = symbol__annotation(sym); -	struct disasm_line *pos, *next; -	s64 len = symbol__size(sym); +	struct disasm_line *pos;  	browser->entries = RB_ROOT;  	pthread_mutex_lock(¬es->lock); -	list_for_each_entry(pos, ¬es->src->source, node) { -		struct browser_disasm_line *bpos = disasm_line__browser(pos); -		const char *path = NULL; +	symbol__calc_percent(sym, evsel); + +	list_for_each_entry(pos, ¬es->src->source, al.node) {  		double max_percent = 0.0;  		int i; -		if (pos->offset == -1) { -			RB_CLEAR_NODE(&bpos->rb_node); +		if (pos->al.offset == -1) { +			RB_CLEAR_NODE(&pos->al.rb_node);  			continue;  		} -		next = disasm__get_next_ip_line(¬es->src->source, pos); - -		for (i = 0; i < browser->nr_events; i++) { -			struct sym_hist_entry sample; - -			bpos->samples[i].percent = disasm__calc_percent(notes, -						evsel->idx + i, -						pos->offset, -						next ? next->offset : len, -						&path, &sample); -			bpos->samples[i].he = sample; +		for (i = 0; i < pos->al.samples_nr; i++) { +			struct annotation_data *sample = &pos->al.samples[i]; -			if (max_percent < bpos->samples[i].percent) -				max_percent = bpos->samples[i].percent; +			if (max_percent < sample->percent) +				max_percent = sample->percent;  		} -		if (max_percent < 0.01 && pos->ipc == 0) { -			RB_CLEAR_NODE(&bpos->rb_node); +		if (max_percent < 0.01 && pos->al.ipc == 0) { +			RB_CLEAR_NODE(&pos->al.rb_node);  			continue;  		} -		disasm_rb_tree__insert(&browser->entries, bpos, -				       browser->nr_events); +		disasm_rb_tree__insert(&browser->entries, &pos->al);  	}  	pthread_mutex_unlock(¬es->lock); @@ -487,38 +480,38 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,  static bool annotate_browser__toggle_source(struct annotate_browser *browser)  { -	struct disasm_line *dl; -	struct browser_disasm_line *bdl; +	struct annotation_line *al; +	struct browser_line *bl;  	off_t offset = browser->b.index - browser->b.top_idx;  	browser->b.seek(&browser->b, offset, SEEK_CUR); -	dl = list_entry(browser->b.top, struct disasm_line, node); -	bdl = disasm_line__browser(dl); +	al = list_entry(browser->b.top, struct annotation_line, node); +	bl = browser_line(al);  	if (annotate_browser__opts.hide_src_code) { -		if (bdl->idx_asm < offset) -			offset = bdl->idx; +		if (bl->idx_asm < offset) +			offset = bl->idx;  		browser->b.nr_entries = browser->nr_entries;  		annotate_browser__opts.hide_src_code = false;  		browser->b.seek(&browser->b, -offset, SEEK_CUR); -		browser->b.top_idx = bdl->idx - offset; -		browser->b.index = bdl->idx; +		browser->b.top_idx = bl->idx - offset; +		browser->b.index = bl->idx;  	} else { -		if (bdl->idx_asm < 0) { +		if (bl->idx_asm < 0) {  			ui_helpline__puts("Only available for assembly lines.");  			browser->b.seek(&browser->b, -offset, SEEK_CUR);  			return false;  		} -		if (bdl->idx_asm < offset) -			offset = bdl->idx_asm; +		if (bl->idx_asm < offset) +			offset = bl->idx_asm;  		browser->b.nr_entries = browser->nr_asm_entries;  		annotate_browser__opts.hide_src_code = true;  		browser->b.seek(&browser->b, -offset, SEEK_CUR); -		browser->b.top_idx = bdl->idx_asm - offset; -		browser->b.index = bdl->idx_asm; +		browser->b.top_idx = bl->idx_asm - offset; +		browser->b.index = bl->idx_asm;  	}  	return true; @@ -543,7 +536,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser,  				    struct hist_browser_timer *hbt)  {  	struct map_symbol *ms = browser->b.priv; -	struct disasm_line *dl = browser->selection; +	struct disasm_line *dl = disasm_line(browser->selection);  	struct annotation *notes;  	struct addr_map_symbol target = {  		.map = ms->map, @@ -589,10 +582,10 @@ struct disasm_line *annotate_browser__find_offset(struct annotate_browser *brows  	struct disasm_line *pos;  	*idx = 0; -	list_for_each_entry(pos, ¬es->src->source, node) { -		if (pos->offset == offset) +	list_for_each_entry(pos, ¬es->src->source, al.node) { +		if (pos->al.offset == offset)  			return pos; -		if (!disasm_line__filter(&browser->b, &pos->node)) +		if (!disasm_line__filter(&browser->b, &pos->al.node))  			++*idx;  	} @@ -601,7 +594,7 @@ 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; +	struct disasm_line *dl = disasm_line(browser->selection);  	u64 offset;  	s64 idx; @@ -615,29 +608,29 @@ static bool annotate_browser__jump(struct annotate_browser *browser)  		return true;  	} -	annotate_browser__set_top(browser, dl, idx); +	annotate_browser__set_top(browser, &dl->al, idx);  	return true;  }  static -struct disasm_line *annotate_browser__find_string(struct annotate_browser *browser, +struct annotation_line *annotate_browser__find_string(struct annotate_browser *browser,  					  char *s, s64 *idx)  {  	struct map_symbol *ms = browser->b.priv;  	struct symbol *sym = ms->sym;  	struct annotation *notes = symbol__annotation(sym); -	struct disasm_line *pos = browser->selection; +	struct annotation_line *al = browser->selection;  	*idx = browser->b.index; -	list_for_each_entry_continue(pos, ¬es->src->source, node) { -		if (disasm_line__filter(&browser->b, &pos->node)) +	list_for_each_entry_continue(al, ¬es->src->source, node) { +		if (disasm_line__filter(&browser->b, &al->node))  			continue;  		++*idx; -		if (pos->line && strstr(pos->line, s) != NULL) -			return pos; +		if (al->line && strstr(al->line, s) != NULL) +			return al;  	}  	return NULL; @@ -645,38 +638,38 @@ struct disasm_line *annotate_browser__find_string(struct annotate_browser *brows  static bool __annotate_browser__search(struct annotate_browser *browser)  { -	struct disasm_line *dl; +	struct annotation_line *al;  	s64 idx; -	dl = annotate_browser__find_string(browser, browser->search_bf, &idx); -	if (dl == NULL) { +	al = annotate_browser__find_string(browser, browser->search_bf, &idx); +	if (al == NULL) {  		ui_helpline__puts("String not found!");  		return false;  	} -	annotate_browser__set_top(browser, dl, idx); +	annotate_browser__set_top(browser, al, idx);  	browser->searching_backwards = false;  	return true;  }  static -struct disasm_line *annotate_browser__find_string_reverse(struct annotate_browser *browser, +struct annotation_line *annotate_browser__find_string_reverse(struct annotate_browser *browser,  						  char *s, s64 *idx)  {  	struct map_symbol *ms = browser->b.priv;  	struct symbol *sym = ms->sym;  	struct annotation *notes = symbol__annotation(sym); -	struct disasm_line *pos = browser->selection; +	struct annotation_line *al = browser->selection;  	*idx = browser->b.index; -	list_for_each_entry_continue_reverse(pos, ¬es->src->source, node) { -		if (disasm_line__filter(&browser->b, &pos->node)) +	list_for_each_entry_continue_reverse(al, ¬es->src->source, node) { +		if (disasm_line__filter(&browser->b, &al->node))  			continue;  		--*idx; -		if (pos->line && strstr(pos->line, s) != NULL) -			return pos; +		if (al->line && strstr(al->line, s) != NULL) +			return al;  	}  	return NULL; @@ -684,16 +677,16 @@ struct disasm_line *annotate_browser__find_string_reverse(struct annotate_browse  static bool __annotate_browser__search_reverse(struct annotate_browser *browser)  { -	struct disasm_line *dl; +	struct annotation_line *al;  	s64 idx; -	dl = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); -	if (dl == NULL) { +	al = annotate_browser__find_string_reverse(browser, browser->search_bf, &idx); +	if (al == NULL) {  		ui_helpline__puts("String not found!");  		return false;  	} -	annotate_browser__set_top(browser, dl, idx); +	annotate_browser__set_top(browser, al, idx);  	browser->searching_backwards = true;  	return true;  } @@ -899,13 +892,16 @@ show_help:  			continue;  		case K_ENTER:  		case K_RIGHT: +		{ +			struct disasm_line *dl = disasm_line(browser->selection); +  			if (browser->selection == NULL)  				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.ops) +			else if (!dl->ins.ops)  				goto show_sup_ins; -			else if (ins__is_ret(&browser->selection->ins)) +			else if (ins__is_ret(&dl->ins))  				goto out;  			else if (!(annotate_browser__jump(browser) ||  				     annotate_browser__callq(browser, evsel, hbt))) { @@ -913,6 +909,7 @@ show_sup_ins:  				ui_helpline__puts("Actions are only available for function call/return & jump/branch instructions.");  			}  			continue; +		}  		case 't':  			if (annotate_browser__opts.show_total_period) {  				annotate_browser__opts.show_total_period = false; @@ -990,10 +987,10 @@ static void count_and_fill(struct annotate_browser *browser, u64 start, u64 end,  			return;  		for (offset = start; offset <= end; offset++) { -			struct disasm_line *dl = browser->offsets[offset]; +			struct annotation_line *al = browser->offsets[offset]; -			if (dl) -				dl->ipc = ipc; +			if (al) +				al->ipc = ipc;  		}  	}  } @@ -1018,13 +1015,13 @@ static void annotate__compute_ipc(struct annotate_browser *browser, size_t size,  		ch = ¬es->src->cycles_hist[offset];  		if (ch && ch->cycles) { -			struct disasm_line *dl; +			struct annotation_line *al;  			if (ch->have_start)  				count_and_fill(browser, ch->start, offset, ch); -			dl = browser->offsets[offset]; -			if (dl && ch->num_aggr) -				dl->cycles = ch->cycles_aggr / ch->num_aggr; +			al = browser->offsets[offset]; +			if (al && ch->num_aggr) +				al->cycles = ch->cycles_aggr / ch->num_aggr;  			browser->have_cycles = true;  		}  	} @@ -1043,23 +1040,27 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser  		return;  	for (offset = 0; offset < size; ++offset) { -		struct disasm_line *dl = browser->offsets[offset], *dlt; -		struct browser_disasm_line *bdlt; +		struct annotation_line *al = browser->offsets[offset]; +		struct disasm_line *dl; +		struct browser_line *blt; + +		dl = disasm_line(al);  		if (!disasm_line__is_valid_jump(dl, sym))  			continue; -		dlt = browser->offsets[dl->ops.target.offset]; +		al = browser->offsets[dl->ops.target.offset]; +  		/*   		 * FIXME: Oops, no jump target? Buggy disassembler? Or do we   		 * have to adjust to the previous offset?   		 */ -		if (dlt == NULL) +		if (al == NULL)  			continue; -		bdlt = disasm_line__browser(dlt); -		if (++bdlt->jump_sources > browser->max_jump_sources) -			browser->max_jump_sources = bdlt->jump_sources; +		blt = browser_line(al); +		if (++blt->jump_sources > browser->max_jump_sources) +			browser->max_jump_sources = blt->jump_sources;  		++browser->nr_jumps;  	} @@ -1078,7 +1079,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,  			 struct perf_evsel *evsel,  			 struct hist_browser_timer *hbt)  { -	struct disasm_line *pos, *n; +	struct annotation_line *al;  	struct annotation *notes;  	size_t size;  	struct map_symbol ms = { @@ -1097,7 +1098,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,  	};  	int ret = -1, err;  	int nr_pcnt = 1; -	size_t sizeof_bdl = sizeof(struct browser_disasm_line);  	if (sym == NULL)  		return -1; @@ -1107,21 +1107,16 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,  	if (map->dso->annotate_warned)  		return -1; -	browser.offsets = zalloc(size * sizeof(struct disasm_line *)); +	browser.offsets = zalloc(size * sizeof(struct annotation_line *));  	if (browser.offsets == NULL) {  		ui__error("Not enough memory!");  		return -1;  	} -	if (perf_evsel__is_group_event(evsel)) { +	if (perf_evsel__is_group_event(evsel))  		nr_pcnt = evsel->nr_members; -		sizeof_bdl += sizeof(struct disasm_line_samples) * -		  (nr_pcnt - 1); -	} -	err = symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), -				  sizeof_bdl, &browser.arch, -				  perf_evsel__env_cpuid(evsel)); +	err = symbol__annotate(sym, map, evsel, sizeof(struct browser_line), &browser.arch);  	if (err) {  		char msg[BUFSIZ];  		symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg)); @@ -1129,20 +1124,22 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,  		goto out_free_offsets;  	} +	symbol__calc_percent(sym, evsel); +  	ui_helpline__push("Press ESC to exit");  	notes = symbol__annotation(sym);  	browser.start = map__rip_2objdump(map, sym->start); -	list_for_each_entry(pos, ¬es->src->source, node) { -		struct browser_disasm_line *bpos; -		size_t line_len = strlen(pos->line); +	list_for_each_entry(al, ¬es->src->source, node) { +		struct browser_line *bpos; +		size_t line_len = strlen(al->line);  		if (browser.b.width < line_len)  			browser.b.width = line_len; -		bpos = disasm_line__browser(pos); +		bpos = browser_line(al);  		bpos->idx = browser.nr_entries++; -		if (pos->offset != -1) { +		if (al->offset != -1) {  			bpos->idx_asm = browser.nr_asm_entries++;  			/*  			 * FIXME: short term bandaid to cope with assembly @@ -1151,8 +1148,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,  			 *  			 * E.g. copy_user_generic_unrolled   			 */ -			if (pos->offset < (s64)size) -				browser.offsets[pos->offset] = pos; +			if (al->offset < (s64)size) +				browser.offsets[al->offset] = al;  		} else  			bpos->idx_asm = -1;  	} @@ -1174,10 +1171,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,  	annotate_browser__update_addr_width(&browser);  	ret = annotate_browser__run(&browser, evsel, hbt); -	list_for_each_entry_safe(pos, n, ¬es->src->source, node) { -		list_del(&pos->node); -		disasm_line__free(pos); -	} + +	annotated_source__purge(notes->src);  out_free_offsets:  	free(browser.offsets);  | 
