Skip to content

Commit 075de90

Browse files
author
Ingo Molnar
committed
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
2 parents c7f9a6f + 3653246 commit 075de90

File tree

12 files changed

+769
-688
lines changed

12 files changed

+769
-688
lines changed

tools/perf/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ LIB_H += util/include/dwarf-regs.h
401401
LIB_H += util/include/asm/dwarf2.h
402402
LIB_H += util/include/asm/cpufeature.h
403403
LIB_H += perf.h
404+
LIB_H += util/annotate.h
404405
LIB_H += util/cache.h
405406
LIB_H += util/callchain.h
406407
LIB_H += util/build-id.h
@@ -444,6 +445,7 @@ LIB_H += $(ARCH_INCLUDE)
444445

445446
LIB_OBJS += $(OUTPUT)util/abspath.o
446447
LIB_OBJS += $(OUTPUT)util/alias.o
448+
LIB_OBJS += $(OUTPUT)util/annotate.o
447449
LIB_OBJS += $(OUTPUT)util/build-id.o
448450
LIB_OBJS += $(OUTPUT)util/config.o
449451
LIB_OBJS += $(OUTPUT)util/ctype.o

tools/perf/builtin-annotate.c

Lines changed: 28 additions & 248 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "util/util.h"
1111

12+
#include "util/util.h"
1213
#include "util/color.h"
1314
#include <linux/list.h>
1415
#include "util/cache.h"
@@ -18,6 +19,7 @@
1819
#include "perf.h"
1920
#include "util/debug.h"
2021

22+
#include "util/annotate.h"
2123
#include "util/event.h"
2224
#include "util/parse-options.h"
2325
#include "util/parse-events.h"
@@ -55,7 +57,18 @@ static int hists__add_entry(struct hists *self, struct addr_location *al)
5557
if (he == NULL)
5658
return -ENOMEM;
5759

58-
return hist_entry__inc_addr_samples(he, al->addr);
60+
if (he->ms.sym != NULL) {
61+
/*
62+
* All aggregated on the first sym_hist.
63+
*/
64+
struct annotation *notes = symbol__annotation(he->ms.sym);
65+
if (notes->histograms == NULL && symbol__alloc_hist(he->ms.sym, 1) < 0)
66+
return -ENOMEM;
67+
68+
return hist_entry__inc_addr_samples(he, 0, al->addr);
69+
}
70+
71+
return 0;
5972
}
6073

6174
static int process_sample_event(union perf_event *event,
@@ -79,245 +92,10 @@ static int process_sample_event(union perf_event *event,
7992
return 0;
8093
}
8194

82-
static int objdump_line__print(struct objdump_line *self,
83-
struct list_head *head,
84-
struct hist_entry *he, u64 len)
85-
{
86-
struct symbol *sym = he->ms.sym;
87-
static const char *prev_line;
88-
static const char *prev_color;
89-
90-
if (self->offset != -1) {
91-
const char *path = NULL;
92-
unsigned int hits = 0;
93-
double percent = 0.0;
94-
const char *color;
95-
struct sym_priv *priv = symbol__priv(sym);
96-
struct sym_ext *sym_ext = priv->ext;
97-
struct sym_hist *h = priv->hist;
98-
s64 offset = self->offset;
99-
struct objdump_line *next = objdump__get_next_ip_line(head, self);
100-
101-
while (offset < (s64)len &&
102-
(next == NULL || offset < next->offset)) {
103-
if (sym_ext) {
104-
if (path == NULL)
105-
path = sym_ext[offset].path;
106-
percent += sym_ext[offset].percent;
107-
} else
108-
hits += h->ip[offset];
109-
110-
++offset;
111-
}
112-
113-
if (sym_ext == NULL && h->sum)
114-
percent = 100.0 * hits / h->sum;
115-
116-
color = get_percent_color(percent);
117-
118-
/*
119-
* Also color the filename and line if needed, with
120-
* the same color than the percentage. Don't print it
121-
* twice for close colored ip with the same filename:line
122-
*/
123-
if (path) {
124-
if (!prev_line || strcmp(prev_line, path)
125-
|| color != prev_color) {
126-
color_fprintf(stdout, color, " %s", path);
127-
prev_line = path;
128-
prev_color = color;
129-
}
130-
}
131-
132-
color_fprintf(stdout, color, " %7.2f", percent);
133-
printf(" : ");
134-
color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", self->line);
135-
} else {
136-
if (!*self->line)
137-
printf(" :\n");
138-
else
139-
printf(" : %s\n", self->line);
140-
}
141-
142-
return 0;
143-
}
144-
145-
static struct rb_root root_sym_ext;
146-
147-
static void insert_source_line(struct sym_ext *sym_ext)
148-
{
149-
struct sym_ext *iter;
150-
struct rb_node **p = &root_sym_ext.rb_node;
151-
struct rb_node *parent = NULL;
152-
153-
while (*p != NULL) {
154-
parent = *p;
155-
iter = rb_entry(parent, struct sym_ext, node);
156-
157-
if (sym_ext->percent > iter->percent)
158-
p = &(*p)->rb_left;
159-
else
160-
p = &(*p)->rb_right;
161-
}
162-
163-
rb_link_node(&sym_ext->node, parent, p);
164-
rb_insert_color(&sym_ext->node, &root_sym_ext);
165-
}
166-
167-
static void free_source_line(struct hist_entry *he, int len)
168-
{
169-
struct sym_priv *priv = symbol__priv(he->ms.sym);
170-
struct sym_ext *sym_ext = priv->ext;
171-
int i;
172-
173-
if (!sym_ext)
174-
return;
175-
176-
for (i = 0; i < len; i++)
177-
free(sym_ext[i].path);
178-
free(sym_ext);
179-
180-
priv->ext = NULL;
181-
root_sym_ext = RB_ROOT;
182-
}
183-
184-
/* Get the filename:line for the colored entries */
185-
static void
186-
get_source_line(struct hist_entry *he, int len, const char *filename)
187-
{
188-
struct symbol *sym = he->ms.sym;
189-
u64 start;
190-
int i;
191-
char cmd[PATH_MAX * 2];
192-
struct sym_ext *sym_ext;
193-
struct sym_priv *priv = symbol__priv(sym);
194-
struct sym_hist *h = priv->hist;
195-
196-
if (!h->sum)
197-
return;
198-
199-
sym_ext = priv->ext = calloc(len, sizeof(struct sym_ext));
200-
if (!priv->ext)
201-
return;
202-
203-
start = he->ms.map->unmap_ip(he->ms.map, sym->start);
204-
205-
for (i = 0; i < len; i++) {
206-
char *path = NULL;
207-
size_t line_len;
208-
u64 offset;
209-
FILE *fp;
210-
211-
sym_ext[i].percent = 100.0 * h->ip[i] / h->sum;
212-
if (sym_ext[i].percent <= 0.5)
213-
continue;
214-
215-
offset = start + i;
216-
sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset);
217-
fp = popen(cmd, "r");
218-
if (!fp)
219-
continue;
220-
221-
if (getline(&path, &line_len, fp) < 0 || !line_len)
222-
goto next;
223-
224-
sym_ext[i].path = malloc(sizeof(char) * line_len + 1);
225-
if (!sym_ext[i].path)
226-
goto next;
227-
228-
strcpy(sym_ext[i].path, path);
229-
insert_source_line(&sym_ext[i]);
230-
231-
next:
232-
pclose(fp);
233-
}
234-
}
235-
236-
static void print_summary(const char *filename)
95+
static int hist_entry__tty_annotate(struct hist_entry *he, int evidx)
23796
{
238-
struct sym_ext *sym_ext;
239-
struct rb_node *node;
240-
241-
printf("\nSorted summary for file %s\n", filename);
242-
printf("----------------------------------------------\n\n");
243-
244-
if (RB_EMPTY_ROOT(&root_sym_ext)) {
245-
printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
246-
return;
247-
}
248-
249-
node = rb_first(&root_sym_ext);
250-
while (node) {
251-
double percent;
252-
const char *color;
253-
char *path;
254-
255-
sym_ext = rb_entry(node, struct sym_ext, node);
256-
percent = sym_ext->percent;
257-
color = get_percent_color(percent);
258-
path = sym_ext->path;
259-
260-
color_fprintf(stdout, color, " %7.2f %s", percent, path);
261-
node = rb_next(node);
262-
}
263-
}
264-
265-
static void hist_entry__print_hits(struct hist_entry *self)
266-
{
267-
struct symbol *sym = self->ms.sym;
268-
struct sym_priv *priv = symbol__priv(sym);
269-
struct sym_hist *h = priv->hist;
270-
u64 len = sym->end - sym->start, offset;
271-
272-
for (offset = 0; offset < len; ++offset)
273-
if (h->ip[offset] != 0)
274-
printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2,
275-
sym->start + offset, h->ip[offset]);
276-
printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum);
277-
}
278-
279-
static int hist_entry__tty_annotate(struct hist_entry *he)
280-
{
281-
struct map *map = he->ms.map;
282-
struct dso *dso = map->dso;
283-
struct symbol *sym = he->ms.sym;
284-
const char *filename = dso->long_name, *d_filename;
285-
u64 len;
286-
LIST_HEAD(head);
287-
struct objdump_line *pos, *n;
288-
289-
if (hist_entry__annotate(he, &head, 0) < 0)
290-
return -1;
291-
292-
if (full_paths)
293-
d_filename = filename;
294-
else
295-
d_filename = basename(filename);
296-
297-
len = sym->end - sym->start;
298-
299-
if (print_line) {
300-
get_source_line(he, len, filename);
301-
print_summary(filename);
302-
}
303-
304-
printf("\n\n------------------------------------------------\n");
305-
printf(" Percent | Source code & Disassembly of %s\n", d_filename);
306-
printf("------------------------------------------------\n");
307-
308-
if (verbose)
309-
hist_entry__print_hits(he);
310-
311-
list_for_each_entry_safe(pos, n, &head, node) {
312-
objdump_line__print(pos, &head, he, len);
313-
list_del(&pos->node);
314-
objdump_line__free(pos);
315-
}
316-
317-
if (print_line)
318-
free_source_line(he, len);
319-
320-
return 0;
97+
return symbol__tty_annotate(he->ms.sym, he->ms.map, evidx,
98+
print_line, full_paths, 0, 0);
32199
}
322100

323101
static void hists__find_annotations(struct hists *self)
@@ -327,13 +105,13 @@ static void hists__find_annotations(struct hists *self)
327105

328106
while (nd) {
329107
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
330-
struct sym_priv *priv;
108+
struct annotation *notes;
331109

332110
if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned)
333111
goto find_next;
334112

335-
priv = symbol__priv(he->ms.sym);
336-
if (priv->hist == NULL) {
113+
notes = symbol__annotation(he->ms.sym);
114+
if (notes->histograms == NULL) {
337115
find_next:
338116
if (key == KEY_LEFT)
339117
nd = rb_prev(nd);
@@ -343,7 +121,8 @@ static void hists__find_annotations(struct hists *self)
343121
}
344122

345123
if (use_browser > 0) {
346-
key = hist_entry__tui_annotate(he);
124+
/* For now all is aggregated on the first */
125+
key = hist_entry__tui_annotate(he, 0);
347126
switch (key) {
348127
case KEY_RIGHT:
349128
next = rb_next(nd);
@@ -358,15 +137,16 @@ static void hists__find_annotations(struct hists *self)
358137
if (next != NULL)
359138
nd = next;
360139
} else {
361-
hist_entry__tty_annotate(he);
140+
/* For now all is aggregated on the first */
141+
hist_entry__tty_annotate(he, 0);
362142
nd = rb_next(nd);
363143
/*
364144
* Since we have a hist_entry per IP for the same
365-
* symbol, free he->ms.sym->hist to signal we already
145+
* symbol, free he->ms.sym->histogram to signal we already
366146
* processed this symbol.
367147
*/
368-
free(priv->hist);
369-
priv->hist = NULL;
148+
free(notes->histograms);
149+
notes->histograms = NULL;
370150
}
371151
}
372152
}
@@ -454,7 +234,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
454234

455235
setup_browser(true);
456236

457-
symbol_conf.priv_size = sizeof(struct sym_priv);
237+
symbol_conf.priv_size = sizeof(struct annotation);
458238
symbol_conf.try_vmlinux_path = true;
459239

460240
if (symbol__init() < 0)

0 commit comments

Comments
 (0)