diff options
Diffstat (limited to 'tools/perf/ui/browsers/annotate.c')
| -rw-r--r-- | tools/perf/ui/browsers/annotate.c | 86 | 
1 files changed, 83 insertions, 3 deletions
| diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index ab776b1ed2d5..183902dac042 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -345,6 +345,23 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,  	browser->curr_hot = rb_last(&browser->entries);  } +static struct annotation_line *annotate_browser__find_new_asm_line( +					struct annotate_browser *browser, +					int idx_asm) +{ +	struct annotation_line *al; +	struct list_head *head = browser->b.entries; + +	/* find an annotation line in the new list with the same idx_asm */ +	list_for_each_entry(al, head, node) { +		if (al->idx_asm == idx_asm) +			return al; +	} + +	/* There are no asm lines */ +	return NULL; +} +  static struct annotation_line *annotate_browser__find_next_asm_line(  					struct annotate_browser *browser,  					struct annotation_line *al) @@ -368,7 +385,31 @@ static struct annotation_line *annotate_browser__find_next_asm_line(  	return NULL;  } -static bool annotate_browser__toggle_source(struct annotate_browser *browser) +static bool annotation__has_source(struct annotation *notes) +{ +	struct annotation_line *al; +	bool found_asm = false; + +	/* Let's skip the first non-asm lines which present regardless of source. */ +	list_for_each_entry(al, ¬es->src->source, node) { +		if (al->offset >= 0) { +			found_asm = true; +			break; +		} +	} + +	if (found_asm) { +		/* After assembly lines, any line without offset means source. */ +		list_for_each_entry_continue(al, ¬es->src->source, node) { +			if (al->offset == -1) +				return true; +		} +	} +	return false; +} + +static bool annotate_browser__toggle_source(struct annotate_browser *browser, +					    struct evsel *evsel)  {  	struct annotation *notes = browser__annotation(&browser->b);  	struct annotation_line *al; @@ -377,6 +418,39 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)  	browser->b.seek(&browser->b, offset, SEEK_CUR);  	al = list_entry(browser->b.top, struct annotation_line, node); +	if (!annotate_opts.annotate_src) +		annotate_opts.annotate_src = true; + +	/* +	 * It's about to get source code annotation for the first time. +	 * Drop the existing annotation_lines and get the new one with source. +	 * And then move to the original line at the same asm index. +	 */ +	if (annotate_opts.hide_src_code && !notes->src->tried_source) { +		struct map_symbol *ms = browser->b.priv; +		int orig_idx_asm = al->idx_asm; + +		/* annotate again with source code info */ +		annotate_opts.hide_src_code = false; +		annotated_source__purge(notes->src); +		symbol__annotate2(ms, evsel, &browser->arch); +		annotate_opts.hide_src_code = true; + +		/* should be after annotated_source__purge() */ +		notes->src->tried_source = true; + +		if (!annotation__has_source(notes)) +			ui__warning("Annotation has no source code."); + +		browser->b.entries = ¬es->src->source; +		al = annotate_browser__find_new_asm_line(browser, orig_idx_asm); +		if (unlikely(al == NULL)) { +			al = list_first_entry(¬es->src->source, +					      struct annotation_line, node); +		} +		browser->b.seek(&browser->b, al->idx_asm, SEEK_SET); +	} +  	if (annotate_opts.hide_src_code) {  		if (al->idx_asm < offset)  			offset = al->idx; @@ -833,7 +907,7 @@ static int annotate_browser__run(struct annotate_browser *browser,  			nd = browser->curr_hot;  			break;  		case 's': -			if (annotate_browser__toggle_source(browser)) +			if (annotate_browser__toggle_source(browser, evsel))  				ui_helpline__puts(help);  			annotate__scnprintf_title(hists, title, sizeof(title));  			annotate_browser__show(&browser->b, title, help); @@ -1011,6 +1085,12 @@ int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,  			ui__error("Couldn't annotate %s:\n%s", sym->name, msg);  			return -1;  		} + +		if (!annotate_opts.hide_src_code) { +			notes->src->tried_source = true; +			if (!annotation__has_source(notes)) +				ui__warning("Annotation has no source code."); +		}  	}  	ui_helpline__push("Press ESC to exit"); @@ -1025,7 +1105,7 @@ int symbol__tui_annotate(struct map_symbol *ms, struct evsel *evsel,  	ret = annotate_browser__run(&browser, evsel, hbt); -	if(not_annotated) +	if (not_annotated && !notes->src->tried_source)  		annotated_source__purge(notes->src);  	return ret; | 
