diff options
| author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-03-24 15:40:17 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-03-26 03:52:57 -0400 |
| commit | 59fd53062f71011a68d03f4cd0ba93d822ac3249 (patch) | |
| tree | d707ca954b8e1fb9c0808b23d83951f357ac8a0d /tools/perf | |
| parent | ac73c5a9c1767b2771e6d2b5accafdef89db04c2 (diff) | |
perf tools: Introduce struct map_symbol
That will be in both struct hist_entry and struct
callchain_list, so that the TUI can store a pointer to the pair
(map, symbol) in the trees where hist_entries and
callchain_lists are present, to allow precise annotation instead
of looking for the first symbol with the selected name.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1269459619-982-4-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 34 | ||||
| -rw-r--r-- | tools/perf/util/hist.c | 8 | ||||
| -rw-r--r-- | tools/perf/util/newt.c | 4 | ||||
| -rw-r--r-- | tools/perf/util/sort.c | 22 | ||||
| -rw-r--r-- | tools/perf/util/sort.h | 3 | ||||
| -rw-r--r-- | tools/perf/util/symbol.h | 5 |
6 files changed, 41 insertions, 35 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index ce9b1ef784b0..887e8e04a6f9 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -69,13 +69,13 @@ static int sym__alloc_hist(struct symbol *self) | |||
| 69 | static int annotate__hist_hit(struct hist_entry *he, u64 ip) | 69 | static int annotate__hist_hit(struct hist_entry *he, u64 ip) |
| 70 | { | 70 | { |
| 71 | unsigned int sym_size, offset; | 71 | unsigned int sym_size, offset; |
| 72 | struct symbol *sym = he->sym; | 72 | struct symbol *sym = he->ms.sym; |
| 73 | struct sym_priv *priv; | 73 | struct sym_priv *priv; |
| 74 | struct sym_hist *h; | 74 | struct sym_hist *h; |
| 75 | 75 | ||
| 76 | he->count++; | 76 | he->count++; |
| 77 | 77 | ||
| 78 | if (!sym || !he->map) | 78 | if (!sym || !he->ms.map) |
| 79 | return 0; | 79 | return 0; |
| 80 | 80 | ||
| 81 | priv = symbol__priv(sym); | 81 | priv = symbol__priv(sym); |
| @@ -85,7 +85,7 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip) | |||
| 85 | sym_size = sym->end - sym->start; | 85 | sym_size = sym->end - sym->start; |
| 86 | offset = ip - sym->start; | 86 | offset = ip - sym->start; |
| 87 | 87 | ||
| 88 | pr_debug3("%s: ip=%#Lx\n", __func__, he->map->unmap_ip(he->map, ip)); | 88 | pr_debug3("%s: ip=%#Lx\n", __func__, he->ms.map->unmap_ip(he->ms.map, ip)); |
| 89 | 89 | ||
| 90 | if (offset >= sym_size) | 90 | if (offset >= sym_size) |
| 91 | return 0; | 91 | return 0; |
| @@ -94,8 +94,8 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip) | |||
| 94 | h->sum++; | 94 | h->sum++; |
| 95 | h->ip[offset]++; | 95 | h->ip[offset]++; |
| 96 | 96 | ||
| 97 | pr_debug3("%#Lx %s: count++ [ip: %#Lx, %#Lx] => %Ld\n", he->sym->start, | 97 | pr_debug3("%#Lx %s: count++ [ip: %#Lx, %#Lx] => %Ld\n", he->ms.sym->start, |
| 98 | he->sym->name, ip, ip - he->sym->start, h->ip[offset]); | 98 | he->ms.sym->name, ip, ip - he->ms.sym->start, h->ip[offset]); |
| 99 | return 0; | 99 | return 0; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| @@ -187,7 +187,7 @@ static struct objdump_line *objdump__get_next_ip_line(struct list_head *head, | |||
| 187 | static int parse_line(FILE *file, struct hist_entry *he, | 187 | static int parse_line(FILE *file, struct hist_entry *he, |
| 188 | struct list_head *head) | 188 | struct list_head *head) |
| 189 | { | 189 | { |
| 190 | struct symbol *sym = he->sym; | 190 | struct symbol *sym = he->ms.sym; |
| 191 | struct objdump_line *objdump_line; | 191 | struct objdump_line *objdump_line; |
| 192 | char *line = NULL, *tmp, *tmp2; | 192 | char *line = NULL, *tmp, *tmp2; |
| 193 | size_t line_len; | 193 | size_t line_len; |
| @@ -226,7 +226,7 @@ static int parse_line(FILE *file, struct hist_entry *he, | |||
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | if (line_ip != -1) { | 228 | if (line_ip != -1) { |
| 229 | u64 start = map__rip_2objdump(he->map, sym->start); | 229 | u64 start = map__rip_2objdump(he->ms.map, sym->start); |
| 230 | offset = line_ip - start; | 230 | offset = line_ip - start; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| @@ -244,7 +244,7 @@ static int objdump_line__print(struct objdump_line *self, | |||
| 244 | struct list_head *head, | 244 | struct list_head *head, |
| 245 | struct hist_entry *he, u64 len) | 245 | struct hist_entry *he, u64 len) |
| 246 | { | 246 | { |
| 247 | struct symbol *sym = he->sym; | 247 | struct symbol *sym = he->ms.sym; |
| 248 | static const char *prev_line; | 248 | static const char *prev_line; |
| 249 | static const char *prev_color; | 249 | static const char *prev_color; |
| 250 | 250 | ||
| @@ -327,7 +327,7 @@ static void insert_source_line(struct sym_ext *sym_ext) | |||
| 327 | 327 | ||
| 328 | static void free_source_line(struct hist_entry *he, int len) | 328 | static void free_source_line(struct hist_entry *he, int len) |
| 329 | { | 329 | { |
| 330 | struct sym_priv *priv = symbol__priv(he->sym); | 330 | struct sym_priv *priv = symbol__priv(he->ms.sym); |
| 331 | struct sym_ext *sym_ext = priv->ext; | 331 | struct sym_ext *sym_ext = priv->ext; |
| 332 | int i; | 332 | int i; |
| 333 | 333 | ||
| @@ -346,7 +346,7 @@ static void free_source_line(struct hist_entry *he, int len) | |||
| 346 | static void | 346 | static void |
| 347 | get_source_line(struct hist_entry *he, int len, const char *filename) | 347 | get_source_line(struct hist_entry *he, int len, const char *filename) |
| 348 | { | 348 | { |
| 349 | struct symbol *sym = he->sym; | 349 | struct symbol *sym = he->ms.sym; |
| 350 | u64 start; | 350 | u64 start; |
| 351 | int i; | 351 | int i; |
| 352 | char cmd[PATH_MAX * 2]; | 352 | char cmd[PATH_MAX * 2]; |
| @@ -361,7 +361,7 @@ get_source_line(struct hist_entry *he, int len, const char *filename) | |||
| 361 | if (!priv->ext) | 361 | if (!priv->ext) |
| 362 | return; | 362 | return; |
| 363 | 363 | ||
| 364 | start = he->map->unmap_ip(he->map, sym->start); | 364 | start = he->ms.map->unmap_ip(he->ms.map, sym->start); |
| 365 | 365 | ||
| 366 | for (i = 0; i < len; i++) { | 366 | for (i = 0; i < len; i++) { |
| 367 | char *path = NULL; | 367 | char *path = NULL; |
| @@ -425,7 +425,7 @@ static void print_summary(const char *filename) | |||
| 425 | 425 | ||
| 426 | static void hist_entry__print_hits(struct hist_entry *self) | 426 | static void hist_entry__print_hits(struct hist_entry *self) |
| 427 | { | 427 | { |
| 428 | struct symbol *sym = self->sym; | 428 | struct symbol *sym = self->ms.sym; |
| 429 | struct sym_priv *priv = symbol__priv(sym); | 429 | struct sym_priv *priv = symbol__priv(sym); |
| 430 | struct sym_hist *h = priv->hist; | 430 | struct sym_hist *h = priv->hist; |
| 431 | u64 len = sym->end - sym->start, offset; | 431 | u64 len = sym->end - sym->start, offset; |
| @@ -439,9 +439,9 @@ static void hist_entry__print_hits(struct hist_entry *self) | |||
| 439 | 439 | ||
| 440 | static void annotate_sym(struct hist_entry *he) | 440 | static void annotate_sym(struct hist_entry *he) |
| 441 | { | 441 | { |
| 442 | struct map *map = he->map; | 442 | struct map *map = he->ms.map; |
| 443 | struct dso *dso = map->dso; | 443 | struct dso *dso = map->dso; |
| 444 | struct symbol *sym = he->sym; | 444 | struct symbol *sym = he->ms.sym; |
| 445 | const char *filename = dso->long_name, *d_filename; | 445 | const char *filename = dso->long_name, *d_filename; |
| 446 | u64 len; | 446 | u64 len; |
| 447 | char command[PATH_MAX*2]; | 447 | char command[PATH_MAX*2]; |
| @@ -526,17 +526,17 @@ static void perf_session__find_annotations(struct perf_session *self) | |||
| 526 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); | 526 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); |
| 527 | struct sym_priv *priv; | 527 | struct sym_priv *priv; |
| 528 | 528 | ||
| 529 | if (he->sym == NULL) | 529 | if (he->ms.sym == NULL) |
| 530 | continue; | 530 | continue; |
| 531 | 531 | ||
| 532 | priv = symbol__priv(he->sym); | 532 | priv = symbol__priv(he->ms.sym); |
| 533 | if (priv->hist == NULL) | 533 | if (priv->hist == NULL) |
| 534 | continue; | 534 | continue; |
| 535 | 535 | ||
| 536 | annotate_sym(he); | 536 | annotate_sym(he); |
| 537 | /* | 537 | /* |
| 538 | * Since we have a hist_entry per IP for the same symbol, free | 538 | * Since we have a hist_entry per IP for the same symbol, free |
| 539 | * he->sym->hist to signal we already processed this symbol. | 539 | * he->ms.sym->hist to signal we already processed this symbol. |
| 540 | */ | 540 | */ |
| 541 | free(priv->hist); | 541 | free(priv->hist); |
| 542 | priv->hist = NULL; | 542 | priv->hist = NULL; |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 5843a9c572ad..4eefb52a8661 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -22,8 +22,10 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
| 22 | struct hist_entry *he; | 22 | struct hist_entry *he; |
| 23 | struct hist_entry entry = { | 23 | struct hist_entry entry = { |
| 24 | .thread = al->thread, | 24 | .thread = al->thread, |
| 25 | .map = al->map, | 25 | .ms = { |
| 26 | .sym = al->sym, | 26 | .map = al->map, |
| 27 | .sym = al->sym, | ||
| 28 | }, | ||
| 27 | .ip = al->addr, | 29 | .ip = al->addr, |
| 28 | .level = al->level, | 30 | .level = al->level, |
| 29 | .count = count, | 31 | .count = count, |
| @@ -654,7 +656,7 @@ print_entries: | |||
| 654 | if (symbol_conf.use_callchain) | 656 | if (symbol_conf.use_callchain) |
| 655 | ret += hist_entry__fprintf_callchain(h, fp, session_total); | 657 | ret += hist_entry__fprintf_callchain(h, fp, session_total); |
| 656 | 658 | ||
| 657 | if (h->map == NULL && verbose > 1) { | 659 | if (h->ms.map == NULL && verbose > 1) { |
| 658 | __map_groups__fprintf_maps(&h->thread->mg, | 660 | __map_groups__fprintf_maps(&h->thread->mg, |
| 659 | MAP__FUNCTION, fp); | 661 | MAP__FUNCTION, fp); |
| 660 | fprintf(fp, "%.10s end\n", graph_dotted_line); | 662 | fprintf(fp, "%.10s end\n", graph_dotted_line); |
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index a3465a0ad70d..25cd2e1f4251 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c | |||
| @@ -287,9 +287,9 @@ static size_t hist_entry__append_browser(struct hist_entry *self, | |||
| 287 | 287 | ||
| 288 | indexes[0] = NEWT_ARG_APPEND; | 288 | indexes[0] = NEWT_ARG_APPEND; |
| 289 | indexes[1] = NEWT_ARG_LAST; | 289 | indexes[1] = NEWT_ARG_LAST; |
| 290 | newt_checkbox_tree__add(tree, s, self->sym, indexes); | 290 | newt_checkbox_tree__add(tree, s, self->ms.sym, indexes); |
| 291 | } else | 291 | } else |
| 292 | newtListboxAppendEntry(tree, s, self->sym); | 292 | newtListboxAppendEntry(tree, s, self->ms.sym); |
| 293 | 293 | ||
| 294 | return strlen(s); | 294 | return strlen(s); |
| 295 | } | 295 | } |
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index cb0f327de9e8..9b80c13cae46 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
| @@ -131,8 +131,8 @@ sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width) | |||
| 131 | int64_t | 131 | int64_t |
| 132 | sort__dso_cmp(struct hist_entry *left, struct hist_entry *right) | 132 | sort__dso_cmp(struct hist_entry *left, struct hist_entry *right) |
| 133 | { | 133 | { |
| 134 | struct dso *dso_l = left->map ? left->map->dso : NULL; | 134 | struct dso *dso_l = left->ms.map ? left->ms.map->dso : NULL; |
| 135 | struct dso *dso_r = right->map ? right->map->dso : NULL; | 135 | struct dso *dso_r = right->ms.map ? right->ms.map->dso : NULL; |
| 136 | const char *dso_name_l, *dso_name_r; | 136 | const char *dso_name_l, *dso_name_r; |
| 137 | 137 | ||
| 138 | if (!dso_l || !dso_r) | 138 | if (!dso_l || !dso_r) |
| @@ -152,9 +152,9 @@ sort__dso_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 152 | size_t | 152 | size_t |
| 153 | sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width) | 153 | sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width) |
| 154 | { | 154 | { |
| 155 | if (self->map && self->map->dso) { | 155 | if (self->ms.map && self->ms.map->dso) { |
| 156 | const char *dso_name = !verbose ? self->map->dso->short_name : | 156 | const char *dso_name = !verbose ? self->ms.map->dso->short_name : |
| 157 | self->map->dso->long_name; | 157 | self->ms.map->dso->long_name; |
| 158 | return repsep_fprintf(fp, "%-*s", width, dso_name); | 158 | return repsep_fprintf(fp, "%-*s", width, dso_name); |
| 159 | } | 159 | } |
| 160 | 160 | ||
| @@ -168,11 +168,11 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right) | |||
| 168 | { | 168 | { |
| 169 | u64 ip_l, ip_r; | 169 | u64 ip_l, ip_r; |
| 170 | 170 | ||
| 171 | if (left->sym == right->sym) | 171 | if (left->ms.sym == right->ms.sym) |
| 172 | return 0; | 172 | return 0; |
| 173 | 173 | ||
| 174 | ip_l = left->sym ? left->sym->start : left->ip; | 174 | ip_l = left->ms.sym ? left->ms.sym->start : left->ip; |
| 175 | ip_r = right->sym ? right->sym->start : right->ip; | 175 | ip_r = right->ms.sym ? right->ms.sym->start : right->ip; |
| 176 | 176 | ||
| 177 | return (int64_t)(ip_r - ip_l); | 177 | return (int64_t)(ip_r - ip_l); |
| 178 | } | 178 | } |
| @@ -184,13 +184,13 @@ sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used) | |||
| 184 | size_t ret = 0; | 184 | size_t ret = 0; |
| 185 | 185 | ||
| 186 | if (verbose) { | 186 | if (verbose) { |
| 187 | char o = self->map ? dso__symtab_origin(self->map->dso) : '!'; | 187 | char o = self->ms.map ? dso__symtab_origin(self->ms.map->dso) : '!'; |
| 188 | ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip, o); | 188 | ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip, o); |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | ret += repsep_fprintf(fp, "[%c] ", self->level); | 191 | ret += repsep_fprintf(fp, "[%c] ", self->level); |
| 192 | if (self->sym) | 192 | if (self->ms.sym) |
| 193 | ret += repsep_fprintf(fp, "%s", self->sym->name); | 193 | ret += repsep_fprintf(fp, "%s", self->ms.sym->name); |
| 194 | else | 194 | else |
| 195 | ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip); | 195 | ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip); |
| 196 | 196 | ||
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 753f9ea99fb0..598568696f97 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h | |||
| @@ -45,8 +45,7 @@ struct hist_entry { | |||
| 45 | struct rb_node rb_node; | 45 | struct rb_node rb_node; |
| 46 | u64 count; | 46 | u64 count; |
| 47 | struct thread *thread; | 47 | struct thread *thread; |
| 48 | struct map *map; | 48 | struct map_symbol ms; |
| 49 | struct symbol *sym; | ||
| 50 | u64 ip; | 49 | u64 ip; |
| 51 | char level; | 50 | char level; |
| 52 | struct symbol *parent; | 51 | struct symbol *parent; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 0da2455d5b90..a4a894b8ea03 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -88,6 +88,11 @@ struct ref_reloc_sym { | |||
| 88 | u64 unrelocated_addr; | 88 | u64 unrelocated_addr; |
| 89 | }; | 89 | }; |
| 90 | 90 | ||
| 91 | struct map_symbol { | ||
| 92 | struct map *map; | ||
| 93 | struct symbol *sym; | ||
| 94 | }; | ||
| 95 | |||
| 91 | struct addr_location { | 96 | struct addr_location { |
| 92 | struct thread *thread; | 97 | struct thread *thread; |
| 93 | struct map *map; | 98 | struct map *map; |
