diff options
Diffstat (limited to 'tools/perf/builtin-annotate.c')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 77bcc9b130f5..96db5248e995 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -277,7 +277,7 @@ static void hist_entry__print_hits(struct hist_entry *self) | |||
| 277 | printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum); | 277 | printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | static void annotate_sym(struct hist_entry *he) | 280 | static int hist_entry__tty_annotate(struct hist_entry *he) |
| 281 | { | 281 | { |
| 282 | struct map *map = he->ms.map; | 282 | struct map *map = he->ms.map; |
| 283 | struct dso *dso = map->dso; | 283 | struct dso *dso = map->dso; |
| @@ -288,7 +288,7 @@ static void annotate_sym(struct hist_entry *he) | |||
| 288 | struct objdump_line *pos, *n; | 288 | struct objdump_line *pos, *n; |
| 289 | 289 | ||
| 290 | if (hist_entry__annotate(he, &head) < 0) | 290 | if (hist_entry__annotate(he, &head) < 0) |
| 291 | return; | 291 | return -1; |
| 292 | 292 | ||
| 293 | if (full_paths) | 293 | if (full_paths) |
| 294 | d_filename = filename; | 294 | d_filename = filename; |
| @@ -317,30 +317,59 @@ static void annotate_sym(struct hist_entry *he) | |||
| 317 | 317 | ||
| 318 | if (print_line) | 318 | if (print_line) |
| 319 | free_source_line(he, len); | 319 | free_source_line(he, len); |
| 320 | |||
| 321 | return 0; | ||
| 320 | } | 322 | } |
| 321 | 323 | ||
| 322 | static void hists__find_annotations(struct hists *self) | 324 | static void hists__find_annotations(struct hists *self) |
| 323 | { | 325 | { |
| 324 | struct rb_node *nd; | 326 | struct rb_node *first = rb_first(&self->entries), *nd = first; |
| 327 | int key = KEY_RIGHT; | ||
| 325 | 328 | ||
| 326 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | 329 | while (nd) { |
| 327 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); | 330 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); |
| 328 | struct sym_priv *priv; | 331 | struct sym_priv *priv; |
| 329 | 332 | ||
| 330 | if (he->ms.sym == NULL) | 333 | if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned) |
| 331 | continue; | 334 | goto find_next; |
| 332 | 335 | ||
| 333 | priv = symbol__priv(he->ms.sym); | 336 | priv = symbol__priv(he->ms.sym); |
| 334 | if (priv->hist == NULL) | 337 | if (priv->hist == NULL) { |
| 338 | find_next: | ||
| 339 | if (key == KEY_LEFT) | ||
| 340 | nd = rb_prev(nd); | ||
| 341 | else | ||
| 342 | nd = rb_next(nd); | ||
| 335 | continue; | 343 | continue; |
| 344 | } | ||
| 336 | 345 | ||
| 337 | annotate_sym(he); | 346 | if (use_browser > 0) { |
| 338 | /* | 347 | key = hist_entry__tui_annotate(he); |
| 339 | * Since we have a hist_entry per IP for the same symbol, free | 348 | if (is_exit_key(key)) |
| 340 | * he->ms.sym->hist to signal we already processed this symbol. | 349 | break; |
| 341 | */ | 350 | switch (key) { |
| 342 | free(priv->hist); | 351 | case KEY_RIGHT: |
| 343 | priv->hist = NULL; | 352 | case '\t': |
| 353 | nd = rb_next(nd); | ||
| 354 | break; | ||
| 355 | case KEY_LEFT: | ||
| 356 | if (nd == first) | ||
| 357 | continue; | ||
| 358 | nd = rb_prev(nd); | ||
| 359 | default: | ||
| 360 | break; | ||
| 361 | } | ||
| 362 | } else { | ||
| 363 | hist_entry__tty_annotate(he); | ||
| 364 | nd = rb_next(nd); | ||
| 365 | /* | ||
| 366 | * Since we have a hist_entry per IP for the same | ||
| 367 | * symbol, free he->ms.sym->hist to signal we already | ||
| 368 | * processed this symbol. | ||
| 369 | */ | ||
| 370 | free(priv->hist); | ||
| 371 | priv->hist = NULL; | ||
| 372 | } | ||
| 344 | } | 373 | } |
| 345 | } | 374 | } |
| 346 | 375 | ||
| @@ -416,6 +445,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) | |||
| 416 | { | 445 | { |
| 417 | argc = parse_options(argc, argv, options, annotate_usage, 0); | 446 | argc = parse_options(argc, argv, options, annotate_usage, 0); |
| 418 | 447 | ||
| 448 | setup_browser(); | ||
| 449 | |||
| 419 | symbol_conf.priv_size = sizeof(struct sym_priv); | 450 | symbol_conf.priv_size = sizeof(struct sym_priv); |
| 420 | symbol_conf.try_vmlinux_path = true; | 451 | symbol_conf.try_vmlinux_path = true; |
| 421 | 452 | ||
| @@ -435,8 +466,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) | |||
| 435 | sym_hist_filter = argv[0]; | 466 | sym_hist_filter = argv[0]; |
| 436 | } | 467 | } |
| 437 | 468 | ||
| 438 | setup_pager(); | ||
| 439 | |||
| 440 | if (field_sep && *field_sep == '.') { | 469 | if (field_sep && *field_sep == '.') { |
| 441 | pr_err("'.' is the only non valid --field-separator argument\n"); | 470 | pr_err("'.' is the only non valid --field-separator argument\n"); |
| 442 | return -1; | 471 | return -1; |
