aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2012-04-24 13:24:28 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-04-24 13:24:28 -0400
commita3f895be1f1ed17f66e6e71adeef0cc7f937512c (patch)
tree167a39caa601782726a483d977e9e4150d5fb3a7 /tools/perf/ui
parent59d038d591f7f00e6752cbfadbbc1c0ca318c5c0 (diff)
perf annotate browser: Initial loop detection
Simple algorithm, just look for the next backward jump that points to before the cursor. Then draw an arrow connecting the jump to its target. Do this as you move the cursor, entering/exiting possible loops. Ex (graph chars replaced to avoid mail encoding woes): avc_has_perm_flags 0.00 | nopl 0x0(%rax) 5.36 |+-> 68: mov (%rax),%rax 5.15 || test %rax,%rax 0.00 || v je 130 2.96 || 74: cmp -0x20(%rax),%ebx 47.38 || lea -0x20(%rax),%rcx 0.28 || ^ jne 68 3.16 || cmp -0x18(%rax),%dx 0.00 |+------^ jne 68 4.92 | cmp 0x4(%rcx),%r13d 0.00 | v jne 68 1.15 | test %rcx,%rcx 0.00 | v je 130 Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-5gairf6or7dazlx3ocxwvftm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui')
-rw-r--r--tools/perf/ui/browser.c39
-rw-r--r--tools/perf/ui/browser.h2
-rw-r--r--tools/perf/ui/browsers/annotate.c61
3 files changed, 98 insertions, 4 deletions
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 973ff74e364..32ac1165100 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -600,6 +600,45 @@ void ui_browser__write_graph(struct ui_browser *browser __used, int graph)
600 SLsmg_set_char_set(0); 600 SLsmg_set_char_set(0);
601} 601}
602 602
603void __ui_browser__line_arrow_up(struct ui_browser *browser, unsigned int column,
604 u64 start, u64 end, int start_width)
605{
606 unsigned int row, end_row;
607
608 SLsmg_set_char_set(1);
609
610 if (start < browser->top_idx + browser->height) {
611 row = start - browser->top_idx;
612 ui_browser__gotorc(browser, row, column);
613 SLsmg_write_char(SLSMG_LLCORN_CHAR);
614 ui_browser__gotorc(browser, row, column + 1);
615 SLsmg_draw_hline(start_width);
616
617 if (row-- == 0)
618 goto out;
619 } else
620 row = browser->height - 1;
621
622 if (end > browser->top_idx)
623 end_row = end - browser->top_idx;
624 else
625 end_row = 0;
626
627 ui_browser__gotorc(browser, end_row, column);
628 SLsmg_draw_vline(row - end_row + 1);
629
630 ui_browser__gotorc(browser, end_row, column);
631 if (end >= browser->top_idx) {
632 SLsmg_write_char(SLSMG_ULCORN_CHAR);
633 ui_browser__gotorc(browser, end_row, column + 1);
634 SLsmg_write_char(SLSMG_HLINE_CHAR);
635 ui_browser__gotorc(browser, end_row, column + 2);
636 SLsmg_write_char(SLSMG_RARROW_CHAR);
637 }
638out:
639 SLsmg_set_char_set(0);
640}
641
603void ui_browser__init(void) 642void ui_browser__init(void)
604{ 643{
605 int i = 0; 644 int i = 0;
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index ce20975419d..2f226cb79f6 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -38,6 +38,8 @@ void ui_browser__reset_index(struct ui_browser *self);
38 38
39void ui_browser__gotorc(struct ui_browser *self, int y, int x); 39void ui_browser__gotorc(struct ui_browser *self, int y, int x);
40void ui_browser__write_graph(struct ui_browser *browser, int graph); 40void ui_browser__write_graph(struct ui_browser *browser, int graph);
41void __ui_browser__line_arrow_up(struct ui_browser *browser, unsigned int column,
42 u64 start, u64 end, int start_width);
41void __ui_browser__show_title(struct ui_browser *browser, const char *title); 43void __ui_browser__show_title(struct ui_browser *browser, const char *title);
42void ui_browser__show_title(struct ui_browser *browser, const char *title); 44void ui_browser__show_title(struct ui_browser *browser, const char *title);
43int ui_browser__show(struct ui_browser *self, const char *title, 45int ui_browser__show(struct ui_browser *self, const char *title,
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index c3fc6f39f90..9e3310cd02c 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -94,13 +94,13 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
94 addr += ab->start; 94 addr += ab->start;
95 95
96 if (!ab->use_offset) { 96 if (!ab->use_offset) {
97 printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ":", addr); 97 printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr);
98 } else { 98 } else {
99 if (bdl->jump_target) { 99 if (bdl->jump_target) {
100 printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ":", 100 printed = scnprintf(bf, sizeof(bf), " %*" PRIx64 ":",
101 ab->offset_width, addr); 101 ab->offset_width, addr);
102 } else { 102 } else {
103 printed = scnprintf(bf, sizeof(bf), "%*s ", 103 printed = scnprintf(bf, sizeof(bf), " %*s ",
104 ab->offset_width, " "); 104 ab->offset_width, " ");
105 } 105 }
106 } 106 }
@@ -141,6 +141,59 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
141 ab->selection = dl; 141 ab->selection = dl;
142} 142}
143 143
144static void annotate_browser__draw_current_loop(struct ui_browser *browser)
145{
146 struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
147 struct map_symbol *ms = browser->priv;
148 struct symbol *sym = ms->sym;
149 struct annotation *notes = symbol__annotation(sym);
150 struct disasm_line *cursor = ab->selection, *pos = cursor, *target;
151 struct browser_disasm_line *bcursor = disasm_line__browser(cursor),
152 *btarget, *bpos;
153 unsigned int from, to, start_width = 2;
154
155 list_for_each_entry_from(pos, &notes->src->source, node) {
156 if (!pos->ins || !ins__is_jump(pos->ins))
157 continue;
158
159 target = ab->offsets[pos->ops.target];
160 if (!target)
161 continue;
162
163 btarget = disasm_line__browser(target);
164 if (btarget->idx <= bcursor->idx)
165 goto found;
166 }
167
168 return;
169
170found:
171 bpos = disasm_line__browser(pos);
172 if (ab->hide_src_code) {
173 from = bpos->idx_asm;
174 to = btarget->idx_asm;
175 } else {
176 from = (u64)bpos->idx;
177 to = (u64)btarget->idx;
178 }
179
180 ui_browser__set_color(browser, HE_COLORSET_CODE);
181
182 if (!bpos->jump_target)
183 start_width += ab->offset_width + 1;
184
185 __ui_browser__line_arrow_up(browser, 10, from, to, start_width);
186}
187
188static unsigned int annotate_browser__refresh(struct ui_browser *browser)
189{
190 int ret = ui_browser__list_head_refresh(browser);
191
192 annotate_browser__draw_current_loop(browser);
193
194 return ret;
195}
196
144static double disasm_line__calc_percent(struct disasm_line *dl, struct symbol *sym, int evidx) 197static double disasm_line__calc_percent(struct disasm_line *dl, struct symbol *sym, int evidx)
145{ 198{
146 double percent = 0.0; 199 double percent = 0.0;
@@ -666,7 +719,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
666 }; 719 };
667 struct annotate_browser browser = { 720 struct annotate_browser browser = {
668 .b = { 721 .b = {
669 .refresh = ui_browser__list_head_refresh, 722 .refresh = annotate_browser__refresh,
670 .seek = ui_browser__list_head_seek, 723 .seek = ui_browser__list_head_seek,
671 .write = annotate_browser__write, 724 .write = annotate_browser__write,
672 .filter = disasm_line__filter, 725 .filter = disasm_line__filter,