diff options
Diffstat (limited to 'tools/perf/util/ui/browsers/annotate.c')
-rw-r--r-- | tools/perf/util/ui/browsers/annotate.c | 76 |
1 files changed, 71 insertions, 5 deletions
diff --git a/tools/perf/util/ui/browsers/annotate.c b/tools/perf/util/ui/browsers/annotate.c index 84315c999284..eb2712ecb601 100644 --- a/tools/perf/util/ui/browsers/annotate.c +++ b/tools/perf/util/ui/browsers/annotate.c | |||
@@ -21,12 +21,16 @@ struct annotate_browser { | |||
21 | struct rb_root entries; | 21 | struct rb_root entries; |
22 | struct rb_node *curr_hot; | 22 | struct rb_node *curr_hot; |
23 | struct objdump_line *selection; | 23 | struct objdump_line *selection; |
24 | int nr_asm_entries; | ||
25 | int nr_entries; | ||
26 | bool hide_src_code; | ||
24 | }; | 27 | }; |
25 | 28 | ||
26 | struct objdump_line_rb_node { | 29 | struct objdump_line_rb_node { |
27 | struct rb_node rb_node; | 30 | struct rb_node rb_node; |
28 | double percent; | 31 | double percent; |
29 | u32 idx; | 32 | u32 idx; |
33 | int idx_asm; | ||
30 | }; | 34 | }; |
31 | 35 | ||
32 | static inline | 36 | static inline |
@@ -35,10 +39,22 @@ struct objdump_line_rb_node *objdump_line__rb(struct objdump_line *self) | |||
35 | return (struct objdump_line_rb_node *)(self + 1); | 39 | return (struct objdump_line_rb_node *)(self + 1); |
36 | } | 40 | } |
37 | 41 | ||
42 | static bool objdump_line__filter(struct ui_browser *browser, void *entry) | ||
43 | { | ||
44 | struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); | ||
45 | |||
46 | if (ab->hide_src_code) { | ||
47 | struct objdump_line *ol = list_entry(entry, struct objdump_line, node); | ||
48 | return ol->offset == -1; | ||
49 | } | ||
50 | |||
51 | return false; | ||
52 | } | ||
53 | |||
38 | static void annotate_browser__write(struct ui_browser *self, void *entry, int row) | 54 | static void annotate_browser__write(struct ui_browser *self, void *entry, int row) |
39 | { | 55 | { |
40 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); | 56 | struct annotate_browser *ab = container_of(self, struct annotate_browser, b); |
41 | struct objdump_line *ol = rb_entry(entry, struct objdump_line, node); | 57 | struct objdump_line *ol = list_entry(entry, struct objdump_line, node); |
42 | bool current_entry = ui_browser__is_current_entry(self, row); | 58 | bool current_entry = ui_browser__is_current_entry(self, row); |
43 | int width = self->width; | 59 | int width = self->width; |
44 | 60 | ||
@@ -168,6 +184,45 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser, | |||
168 | browser->curr_hot = rb_last(&browser->entries); | 184 | browser->curr_hot = rb_last(&browser->entries); |
169 | } | 185 | } |
170 | 186 | ||
187 | static bool annotate_browser__toggle_source(struct annotate_browser *browser) | ||
188 | { | ||
189 | struct objdump_line *ol; | ||
190 | struct objdump_line_rb_node *olrb; | ||
191 | off_t offset = browser->b.index - browser->b.top_idx; | ||
192 | |||
193 | browser->b.seek(&browser->b, offset, SEEK_CUR); | ||
194 | ol = list_entry(browser->b.top, struct objdump_line, node); | ||
195 | olrb = objdump_line__rb(ol); | ||
196 | |||
197 | if (browser->hide_src_code) { | ||
198 | if (olrb->idx_asm < offset) | ||
199 | offset = olrb->idx; | ||
200 | |||
201 | browser->b.nr_entries = browser->nr_entries; | ||
202 | browser->hide_src_code = false; | ||
203 | browser->b.seek(&browser->b, -offset, SEEK_CUR); | ||
204 | browser->b.top_idx = olrb->idx - offset; | ||
205 | browser->b.index = olrb->idx; | ||
206 | } else { | ||
207 | if (olrb->idx_asm < 0) { | ||
208 | ui_helpline__puts("Only available for assembly lines."); | ||
209 | browser->b.seek(&browser->b, -offset, SEEK_CUR); | ||
210 | return false; | ||
211 | } | ||
212 | |||
213 | if (olrb->idx_asm < offset) | ||
214 | offset = olrb->idx_asm; | ||
215 | |||
216 | browser->b.nr_entries = browser->nr_asm_entries; | ||
217 | browser->hide_src_code = true; | ||
218 | browser->b.seek(&browser->b, -offset, SEEK_CUR); | ||
219 | browser->b.top_idx = olrb->idx_asm - offset; | ||
220 | browser->b.index = olrb->idx_asm; | ||
221 | } | ||
222 | |||
223 | return true; | ||
224 | } | ||
225 | |||
171 | static int annotate_browser__run(struct annotate_browser *self, int evidx, | 226 | static int annotate_browser__run(struct annotate_browser *self, int evidx, |
172 | int nr_events, void(*timer)(void *arg), | 227 | int nr_events, void(*timer)(void *arg), |
173 | void *arg, int delay_secs) | 228 | void *arg, int delay_secs) |
@@ -175,11 +230,12 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, | |||
175 | struct rb_node *nd = NULL; | 230 | struct rb_node *nd = NULL; |
176 | struct map_symbol *ms = self->b.priv; | 231 | struct map_symbol *ms = self->b.priv; |
177 | struct symbol *sym = ms->sym; | 232 | struct symbol *sym = ms->sym; |
233 | const char *help = "<-, ESC: exit, TAB/shift+TAB: cycle hottest lines, " | ||
234 | "H: Hottest, -> Line action, S -> Toggle source " | ||
235 | "code view"; | ||
178 | int key; | 236 | int key; |
179 | 237 | ||
180 | if (ui_browser__show(&self->b, sym->name, | 238 | if (ui_browser__show(&self->b, sym->name, help) < 0) |
181 | "<- or ESC: exit, TAB/shift+TAB: " | ||
182 | "cycle hottest lines, H: Hottest, -> Line action") < 0) | ||
183 | return -1; | 239 | return -1; |
184 | 240 | ||
185 | annotate_browser__calc_percent(self, evidx); | 241 | annotate_browser__calc_percent(self, evidx); |
@@ -234,6 +290,10 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, | |||
234 | case 'H': | 290 | case 'H': |
235 | nd = self->curr_hot; | 291 | nd = self->curr_hot; |
236 | break; | 292 | break; |
293 | case 'S': | ||
294 | if (annotate_browser__toggle_source(self)) | ||
295 | ui_helpline__puts(help); | ||
296 | continue; | ||
237 | case NEWT_KEY_ENTER: | 297 | case NEWT_KEY_ENTER: |
238 | case NEWT_KEY_RIGHT: | 298 | case NEWT_KEY_RIGHT: |
239 | if (self->selection == NULL) { | 299 | if (self->selection == NULL) { |
@@ -324,6 +384,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
324 | .refresh = ui_browser__list_head_refresh, | 384 | .refresh = ui_browser__list_head_refresh, |
325 | .seek = ui_browser__list_head_seek, | 385 | .seek = ui_browser__list_head_seek, |
326 | .write = annotate_browser__write, | 386 | .write = annotate_browser__write, |
387 | .filter = objdump_line__filter, | ||
327 | .priv = &ms, | 388 | .priv = &ms, |
328 | }, | 389 | }, |
329 | }; | 390 | }; |
@@ -351,9 +412,14 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
351 | if (browser.b.width < line_len) | 412 | if (browser.b.width < line_len) |
352 | browser.b.width = line_len; | 413 | browser.b.width = line_len; |
353 | rbpos = objdump_line__rb(pos); | 414 | rbpos = objdump_line__rb(pos); |
354 | rbpos->idx = browser.b.nr_entries++; | 415 | rbpos->idx = browser.nr_entries++; |
416 | if (pos->offset != -1) | ||
417 | rbpos->idx_asm = browser.nr_asm_entries++; | ||
418 | else | ||
419 | rbpos->idx_asm = -1; | ||
355 | } | 420 | } |
356 | 421 | ||
422 | browser.b.nr_entries = browser.nr_entries; | ||
357 | browser.b.entries = ¬es->src->source, | 423 | browser.b.entries = ¬es->src->source, |
358 | browser.b.width += 18; /* Percentage */ | 424 | browser.b.width += 18; /* Percentage */ |
359 | ret = annotate_browser__run(&browser, evidx, nr_events, | 425 | ret = annotate_browser__run(&browser, evidx, nr_events, |