diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2013-01-29 17:59:09 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-01-29 18:10:15 -0500 |
commit | de65d816aa44f9ddd79861ae21d75010cc1fd003 (patch) | |
tree | 04a637a43b2e52a733d0dcb7595a47057571e7da /tools/perf/util/annotate.c | |
parent | 9710f581bb4c35589ac046b0cfc0deb7f369fc85 (diff) | |
parent | 5dcd14ecd41ea2b3ae3295a9b30d98769d52165f (diff) |
Merge remote-tracking branch 'origin/x86/boot' into x86/mm2
Coming patches to x86/mm2 require the changes and advanced baseline in
x86/boot.
Resolved Conflicts:
arch/x86/kernel/setup.c
mm/nobootmem.c
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 72 |
1 files changed, 62 insertions, 10 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index f0a910371377..07aaeea60000 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "debug.h" | 15 | #include "debug.h" |
16 | #include "annotate.h" | 16 | #include "annotate.h" |
17 | #include <pthread.h> | 17 | #include <pthread.h> |
18 | #include <linux/bitops.h> | ||
18 | 19 | ||
19 | const char *disassembler_style; | 20 | const char *disassembler_style; |
20 | const char *objdump_path; | 21 | const char *objdump_path; |
@@ -170,15 +171,15 @@ static int lock__parse(struct ins_operands *ops) | |||
170 | if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0) | 171 | if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0) |
171 | goto out_free_ops; | 172 | goto out_free_ops; |
172 | 173 | ||
173 | ops->locked.ins = ins__find(name); | 174 | ops->locked.ins = ins__find(name); |
174 | if (ops->locked.ins == NULL) | 175 | if (ops->locked.ins == NULL) |
175 | goto out_free_ops; | 176 | goto out_free_ops; |
176 | 177 | ||
177 | if (!ops->locked.ins->ops) | 178 | if (!ops->locked.ins->ops) |
178 | return 0; | 179 | return 0; |
179 | 180 | ||
180 | if (ops->locked.ins->ops->parse) | 181 | if (ops->locked.ins->ops->parse) |
181 | ops->locked.ins->ops->parse(ops->locked.ops); | 182 | ops->locked.ins->ops->parse(ops->locked.ops); |
182 | 183 | ||
183 | return 0; | 184 | return 0; |
184 | 185 | ||
@@ -400,6 +401,8 @@ static struct ins instructions[] = { | |||
400 | { .name = "testb", .ops = &mov_ops, }, | 401 | { .name = "testb", .ops = &mov_ops, }, |
401 | { .name = "testl", .ops = &mov_ops, }, | 402 | { .name = "testl", .ops = &mov_ops, }, |
402 | { .name = "xadd", .ops = &mov_ops, }, | 403 | { .name = "xadd", .ops = &mov_ops, }, |
404 | { .name = "xbeginl", .ops = &jump_ops, }, | ||
405 | { .name = "xbeginq", .ops = &jump_ops, }, | ||
403 | }; | 406 | }; |
404 | 407 | ||
405 | static int ins__cmp(const void *name, const void *insp) | 408 | static int ins__cmp(const void *name, const void *insp) |
@@ -855,21 +858,68 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin | |||
855 | struct source_line *iter; | 858 | struct source_line *iter; |
856 | struct rb_node **p = &root->rb_node; | 859 | struct rb_node **p = &root->rb_node; |
857 | struct rb_node *parent = NULL; | 860 | struct rb_node *parent = NULL; |
861 | int ret; | ||
858 | 862 | ||
859 | while (*p != NULL) { | 863 | while (*p != NULL) { |
860 | parent = *p; | 864 | parent = *p; |
861 | iter = rb_entry(parent, struct source_line, node); | 865 | iter = rb_entry(parent, struct source_line, node); |
862 | 866 | ||
863 | if (src_line->percent > iter->percent) | 867 | ret = strcmp(iter->path, src_line->path); |
868 | if (ret == 0) { | ||
869 | iter->percent_sum += src_line->percent; | ||
870 | return; | ||
871 | } | ||
872 | |||
873 | if (ret < 0) | ||
864 | p = &(*p)->rb_left; | 874 | p = &(*p)->rb_left; |
865 | else | 875 | else |
866 | p = &(*p)->rb_right; | 876 | p = &(*p)->rb_right; |
867 | } | 877 | } |
868 | 878 | ||
879 | src_line->percent_sum = src_line->percent; | ||
880 | |||
869 | rb_link_node(&src_line->node, parent, p); | 881 | rb_link_node(&src_line->node, parent, p); |
870 | rb_insert_color(&src_line->node, root); | 882 | rb_insert_color(&src_line->node, root); |
871 | } | 883 | } |
872 | 884 | ||
885 | static void __resort_source_line(struct rb_root *root, struct source_line *src_line) | ||
886 | { | ||
887 | struct source_line *iter; | ||
888 | struct rb_node **p = &root->rb_node; | ||
889 | struct rb_node *parent = NULL; | ||
890 | |||
891 | while (*p != NULL) { | ||
892 | parent = *p; | ||
893 | iter = rb_entry(parent, struct source_line, node); | ||
894 | |||
895 | if (src_line->percent_sum > iter->percent_sum) | ||
896 | p = &(*p)->rb_left; | ||
897 | else | ||
898 | p = &(*p)->rb_right; | ||
899 | } | ||
900 | |||
901 | rb_link_node(&src_line->node, parent, p); | ||
902 | rb_insert_color(&src_line->node, root); | ||
903 | } | ||
904 | |||
905 | static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root) | ||
906 | { | ||
907 | struct source_line *src_line; | ||
908 | struct rb_node *node; | ||
909 | |||
910 | node = rb_first(src_root); | ||
911 | while (node) { | ||
912 | struct rb_node *next; | ||
913 | |||
914 | src_line = rb_entry(node, struct source_line, node); | ||
915 | next = rb_next(node); | ||
916 | rb_erase(node, src_root); | ||
917 | |||
918 | __resort_source_line(dest_root, src_line); | ||
919 | node = next; | ||
920 | } | ||
921 | } | ||
922 | |||
873 | static void symbol__free_source_line(struct symbol *sym, int len) | 923 | static void symbol__free_source_line(struct symbol *sym, int len) |
874 | { | 924 | { |
875 | struct annotation *notes = symbol__annotation(sym); | 925 | struct annotation *notes = symbol__annotation(sym); |
@@ -894,6 +944,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
894 | struct source_line *src_line; | 944 | struct source_line *src_line; |
895 | struct annotation *notes = symbol__annotation(sym); | 945 | struct annotation *notes = symbol__annotation(sym); |
896 | struct sym_hist *h = annotation__histogram(notes, evidx); | 946 | struct sym_hist *h = annotation__histogram(notes, evidx); |
947 | struct rb_root tmp_root = RB_ROOT; | ||
897 | 948 | ||
898 | if (!h->sum) | 949 | if (!h->sum) |
899 | return 0; | 950 | return 0; |
@@ -928,12 +979,13 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
928 | goto next; | 979 | goto next; |
929 | 980 | ||
930 | strcpy(src_line[i].path, path); | 981 | strcpy(src_line[i].path, path); |
931 | insert_source_line(root, &src_line[i]); | 982 | insert_source_line(&tmp_root, &src_line[i]); |
932 | 983 | ||
933 | next: | 984 | next: |
934 | pclose(fp); | 985 | pclose(fp); |
935 | } | 986 | } |
936 | 987 | ||
988 | resort_source_line(root, &tmp_root); | ||
937 | return 0; | 989 | return 0; |
938 | } | 990 | } |
939 | 991 | ||
@@ -957,7 +1009,7 @@ static void print_summary(struct rb_root *root, const char *filename) | |||
957 | char *path; | 1009 | char *path; |
958 | 1010 | ||
959 | src_line = rb_entry(node, struct source_line, node); | 1011 | src_line = rb_entry(node, struct source_line, node); |
960 | percent = src_line->percent; | 1012 | percent = src_line->percent_sum; |
961 | color = get_percent_color(percent); | 1013 | color = get_percent_color(percent); |
962 | path = src_line->path; | 1014 | path = src_line->path; |
963 | 1015 | ||