Skip to content

Commit a3f895b

Browse files
committed
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 <[email protected]> Cc: David Ahern <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Mike Galbraith <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Link: http://lkml.kernel.org/n/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 59d038d commit a3f895b

File tree

3 files changed

+98
-4
lines changed

3 files changed

+98
-4
lines changed

tools/perf/ui/browser.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,45 @@ void ui_browser__write_graph(struct ui_browser *browser __used, int graph)
600600
SLsmg_set_char_set(0);
601601
}
602602

603+
void __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+
}
638+
out:
639+
SLsmg_set_char_set(0);
640+
}
641+
603642
void ui_browser__init(void)
604643
{
605644
int i = 0;

tools/perf/ui/browser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ void ui_browser__reset_index(struct ui_browser *self);
3838

3939
void ui_browser__gotorc(struct ui_browser *self, int y, int x);
4040
void ui_browser__write_graph(struct ui_browser *browser, int graph);
41+
void __ui_browser__line_arrow_up(struct ui_browser *browser, unsigned int column,
42+
u64 start, u64 end, int start_width);
4143
void __ui_browser__show_title(struct ui_browser *browser, const char *title);
4244
void ui_browser__show_title(struct ui_browser *browser, const char *title);
4345
int ui_browser__show(struct ui_browser *self, const char *title,

tools/perf/ui/browsers/annotate.c

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
9494
addr += ab->start;
9595

9696
if (!ab->use_offset) {
97-
printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ":", addr);
97+
printed = scnprintf(bf, sizeof(bf), " %" PRIx64 ":", addr);
9898
} else {
9999
if (bdl->jump_target) {
100-
printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ":",
100+
printed = scnprintf(bf, sizeof(bf), " %*" PRIx64 ":",
101101
ab->offset_width, addr);
102102
} else {
103-
printed = scnprintf(bf, sizeof(bf), "%*s ",
103+
printed = scnprintf(bf, sizeof(bf), " %*s ",
104104
ab->offset_width, " ");
105105
}
106106
}
@@ -141,6 +141,59 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
141141
ab->selection = dl;
142142
}
143143

144+
static 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+
170+
found:
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+
188+
static 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+
144197
static double disasm_line__calc_percent(struct disasm_line *dl, struct symbol *sym, int evidx)
145198
{
146199
double percent = 0.0;
@@ -666,7 +719,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
666719
};
667720
struct annotate_browser browser = {
668721
.b = {
669-
.refresh = ui_browser__list_head_refresh,
722+
.refresh = annotate_browser__refresh,
670723
.seek = ui_browser__list_head_seek,
671724
.write = annotate_browser__write,
672725
.filter = disasm_line__filter,

0 commit comments

Comments
 (0)