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 | |
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>
-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; |