diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 149 |
1 files changed, 98 insertions, 51 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index be1caabb9290..da1c4c4a0dd8 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -47,7 +47,11 @@ struct arch { | |||
47 | bool sorted_instructions; | 47 | bool sorted_instructions; |
48 | bool initialized; | 48 | bool initialized; |
49 | void *priv; | 49 | void *priv; |
50 | int (*init)(struct arch *arch); | 50 | unsigned int model; |
51 | unsigned int family; | ||
52 | int (*init)(struct arch *arch, char *cpuid); | ||
53 | bool (*ins_is_fused)(struct arch *arch, const char *ins1, | ||
54 | const char *ins2); | ||
51 | struct { | 55 | struct { |
52 | char comment_char; | 56 | char comment_char; |
53 | char skip_functions_char; | 57 | char skip_functions_char; |
@@ -127,8 +131,10 @@ static struct arch architectures[] = { | |||
127 | }, | 131 | }, |
128 | { | 132 | { |
129 | .name = "x86", | 133 | .name = "x86", |
134 | .init = x86__annotate_init, | ||
130 | .instructions = x86__instructions, | 135 | .instructions = x86__instructions, |
131 | .nr_instructions = ARRAY_SIZE(x86__instructions), | 136 | .nr_instructions = ARRAY_SIZE(x86__instructions), |
137 | .ins_is_fused = x86__ins_is_fused, | ||
132 | .objdump = { | 138 | .objdump = { |
133 | .comment_char = '#', | 139 | .comment_char = '#', |
134 | }, | 140 | }, |
@@ -171,6 +177,14 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size, | |||
171 | return ins__raw_scnprintf(ins, bf, size, ops); | 177 | return ins__raw_scnprintf(ins, bf, size, ops); |
172 | } | 178 | } |
173 | 179 | ||
180 | bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) | ||
181 | { | ||
182 | if (!arch || !arch->ins_is_fused) | ||
183 | return false; | ||
184 | |||
185 | return arch->ins_is_fused(arch, ins1, ins2); | ||
186 | } | ||
187 | |||
174 | static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) | 188 | static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) |
175 | { | 189 | { |
176 | char *endptr, *tok, *name; | 190 | char *endptr, *tok, *name; |
@@ -502,6 +516,11 @@ bool ins__is_ret(const struct ins *ins) | |||
502 | return ins->ops == &ret_ops; | 516 | return ins->ops == &ret_ops; |
503 | } | 517 | } |
504 | 518 | ||
519 | bool ins__is_lock(const struct ins *ins) | ||
520 | { | ||
521 | return ins->ops == &lock_ops; | ||
522 | } | ||
523 | |||
505 | static int ins__key_cmp(const void *name, const void *insp) | 524 | static int ins__key_cmp(const void *name, const void *insp) |
506 | { | 525 | { |
507 | const struct ins *ins = insp; | 526 | const struct ins *ins = insp; |
@@ -586,14 +605,24 @@ static struct arch *arch__find(const char *name) | |||
586 | int symbol__alloc_hist(struct symbol *sym) | 605 | int symbol__alloc_hist(struct symbol *sym) |
587 | { | 606 | { |
588 | struct annotation *notes = symbol__annotation(sym); | 607 | struct annotation *notes = symbol__annotation(sym); |
589 | const size_t size = symbol__size(sym); | 608 | size_t size = symbol__size(sym); |
590 | size_t sizeof_sym_hist; | 609 | size_t sizeof_sym_hist; |
591 | 610 | ||
611 | /* | ||
612 | * Add buffer of one element for zero length symbol. | ||
613 | * When sample is taken from first instruction of | ||
614 | * zero length symbol, perf still resolves it and | ||
615 | * shows symbol name in perf report and allows to | ||
616 | * annotate it. | ||
617 | */ | ||
618 | if (size == 0) | ||
619 | size = 1; | ||
620 | |||
592 | /* Check for overflow when calculating sizeof_sym_hist */ | 621 | /* Check for overflow when calculating sizeof_sym_hist */ |
593 | if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64)) | 622 | if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry)) |
594 | return -1; | 623 | return -1; |
595 | 624 | ||
596 | sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64)); | 625 | sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(struct sym_hist_entry)); |
597 | 626 | ||
598 | /* Check for overflow in zalloc argument */ | 627 | /* Check for overflow in zalloc argument */ |
599 | if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) | 628 | if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) |
@@ -677,7 +706,8 @@ static int __symbol__account_cycles(struct annotation *notes, | |||
677 | } | 706 | } |
678 | 707 | ||
679 | static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 708 | static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
680 | struct annotation *notes, int evidx, u64 addr) | 709 | struct annotation *notes, int evidx, u64 addr, |
710 | struct perf_sample *sample) | ||
681 | { | 711 | { |
682 | unsigned offset; | 712 | unsigned offset; |
683 | struct sym_hist *h; | 713 | struct sym_hist *h; |
@@ -693,12 +723,15 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
693 | 723 | ||
694 | offset = addr - sym->start; | 724 | offset = addr - sym->start; |
695 | h = annotation__histogram(notes, evidx); | 725 | h = annotation__histogram(notes, evidx); |
696 | h->sum++; | 726 | h->nr_samples++; |
697 | h->addr[offset]++; | 727 | h->addr[offset].nr_samples++; |
728 | h->period += sample->period; | ||
729 | h->addr[offset].period += sample->period; | ||
698 | 730 | ||
699 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 | 731 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 |
700 | ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, | 732 | ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n", |
701 | addr, addr - sym->start, evidx, h->addr[offset]); | 733 | sym->start, sym->name, addr, addr - sym->start, evidx, |
734 | h->addr[offset].nr_samples, h->addr[offset].period); | ||
702 | return 0; | 735 | return 0; |
703 | } | 736 | } |
704 | 737 | ||
@@ -718,7 +751,8 @@ static struct annotation *symbol__get_annotation(struct symbol *sym, bool cycles | |||
718 | } | 751 | } |
719 | 752 | ||
720 | static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 753 | static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
721 | int evidx, u64 addr) | 754 | int evidx, u64 addr, |
755 | struct perf_sample *sample) | ||
722 | { | 756 | { |
723 | struct annotation *notes; | 757 | struct annotation *notes; |
724 | 758 | ||
@@ -727,7 +761,7 @@ static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
727 | notes = symbol__get_annotation(sym, false); | 761 | notes = symbol__get_annotation(sym, false); |
728 | if (notes == NULL) | 762 | if (notes == NULL) |
729 | return -ENOMEM; | 763 | return -ENOMEM; |
730 | return __symbol__inc_addr_samples(sym, map, notes, evidx, addr); | 764 | return __symbol__inc_addr_samples(sym, map, notes, evidx, addr, sample); |
731 | } | 765 | } |
732 | 766 | ||
733 | static int symbol__account_cycles(u64 addr, u64 start, | 767 | static int symbol__account_cycles(u64 addr, u64 start, |
@@ -791,14 +825,16 @@ int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, | |||
791 | return err; | 825 | return err; |
792 | } | 826 | } |
793 | 827 | ||
794 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx) | 828 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, |
829 | int evidx) | ||
795 | { | 830 | { |
796 | return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr); | 831 | return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr, sample); |
797 | } | 832 | } |
798 | 833 | ||
799 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) | 834 | int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, |
835 | int evidx, u64 ip) | ||
800 | { | 836 | { |
801 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); | 837 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip, sample); |
802 | } | 838 | } |
803 | 839 | ||
804 | static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) | 840 | static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) |
@@ -908,11 +944,12 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa | |||
908 | } | 944 | } |
909 | 945 | ||
910 | double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, | 946 | double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, |
911 | s64 end, const char **path, u64 *nr_samples) | 947 | s64 end, const char **path, struct sym_hist_entry *sample) |
912 | { | 948 | { |
913 | struct source_line *src_line = notes->src->lines; | 949 | struct source_line *src_line = notes->src->lines; |
914 | double percent = 0.0; | 950 | double percent = 0.0; |
915 | *nr_samples = 0; | 951 | |
952 | sample->nr_samples = sample->period = 0; | ||
916 | 953 | ||
917 | if (src_line) { | 954 | if (src_line) { |
918 | size_t sizeof_src_line = sizeof(*src_line) + | 955 | size_t sizeof_src_line = sizeof(*src_line) + |
@@ -926,19 +963,24 @@ double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, | |||
926 | *path = src_line->path; | 963 | *path = src_line->path; |
927 | 964 | ||
928 | percent += src_line->samples[evidx].percent; | 965 | percent += src_line->samples[evidx].percent; |
929 | *nr_samples += src_line->samples[evidx].nr; | 966 | sample->nr_samples += src_line->samples[evidx].nr; |
930 | offset++; | 967 | offset++; |
931 | } | 968 | } |
932 | } else { | 969 | } else { |
933 | struct sym_hist *h = annotation__histogram(notes, evidx); | 970 | struct sym_hist *h = annotation__histogram(notes, evidx); |
934 | unsigned int hits = 0; | 971 | unsigned int hits = 0; |
972 | u64 period = 0; | ||
935 | 973 | ||
936 | while (offset < end) | 974 | while (offset < end) { |
937 | hits += h->addr[offset++]; | 975 | hits += h->addr[offset].nr_samples; |
976 | period += h->addr[offset].period; | ||
977 | ++offset; | ||
978 | } | ||
938 | 979 | ||
939 | if (h->sum) { | 980 | if (h->nr_samples) { |
940 | *nr_samples = hits; | 981 | sample->period = period; |
941 | percent = 100.0 * hits / h->sum; | 982 | sample->nr_samples = hits; |
983 | percent = 100.0 * hits / h->nr_samples; | ||
942 | } | 984 | } |
943 | } | 985 | } |
944 | 986 | ||
@@ -1037,10 +1079,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1037 | 1079 | ||
1038 | if (dl->offset != -1) { | 1080 | if (dl->offset != -1) { |
1039 | const char *path = NULL; | 1081 | const char *path = NULL; |
1040 | u64 nr_samples; | ||
1041 | double percent, max_percent = 0.0; | 1082 | double percent, max_percent = 0.0; |
1042 | double *ppercents = &percent; | 1083 | double *ppercents = &percent; |
1043 | u64 *psamples = &nr_samples; | 1084 | struct sym_hist_entry sample; |
1085 | struct sym_hist_entry *psamples = &sample; | ||
1044 | int i, nr_percent = 1; | 1086 | int i, nr_percent = 1; |
1045 | const char *color; | 1087 | const char *color; |
1046 | struct annotation *notes = symbol__annotation(sym); | 1088 | struct annotation *notes = symbol__annotation(sym); |
@@ -1054,7 +1096,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1054 | if (perf_evsel__is_group_event(evsel)) { | 1096 | if (perf_evsel__is_group_event(evsel)) { |
1055 | nr_percent = evsel->nr_members; | 1097 | nr_percent = evsel->nr_members; |
1056 | ppercents = calloc(nr_percent, sizeof(double)); | 1098 | ppercents = calloc(nr_percent, sizeof(double)); |
1057 | psamples = calloc(nr_percent, sizeof(u64)); | 1099 | psamples = calloc(nr_percent, sizeof(struct sym_hist_entry)); |
1058 | if (ppercents == NULL || psamples == NULL) { | 1100 | if (ppercents == NULL || psamples == NULL) { |
1059 | return -1; | 1101 | return -1; |
1060 | } | 1102 | } |
@@ -1065,10 +1107,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1065 | notes->src->lines ? i : evsel->idx + i, | 1107 | notes->src->lines ? i : evsel->idx + i, |
1066 | offset, | 1108 | offset, |
1067 | next ? next->offset : (s64) len, | 1109 | next ? next->offset : (s64) len, |
1068 | &path, &nr_samples); | 1110 | &path, &sample); |
1069 | 1111 | ||
1070 | ppercents[i] = percent; | 1112 | ppercents[i] = percent; |
1071 | psamples[i] = nr_samples; | 1113 | psamples[i] = sample; |
1072 | if (percent > max_percent) | 1114 | if (percent > max_percent) |
1073 | max_percent = percent; | 1115 | max_percent = percent; |
1074 | } | 1116 | } |
@@ -1106,12 +1148,15 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1106 | 1148 | ||
1107 | for (i = 0; i < nr_percent; i++) { | 1149 | for (i = 0; i < nr_percent; i++) { |
1108 | percent = ppercents[i]; | 1150 | percent = ppercents[i]; |
1109 | nr_samples = psamples[i]; | 1151 | sample = psamples[i]; |
1110 | color = get_percent_color(percent); | 1152 | color = get_percent_color(percent); |
1111 | 1153 | ||
1112 | if (symbol_conf.show_total_period) | 1154 | if (symbol_conf.show_total_period) |
1155 | color_fprintf(stdout, color, " %11" PRIu64, | ||
1156 | sample.period); | ||
1157 | else if (symbol_conf.show_nr_samples) | ||
1113 | color_fprintf(stdout, color, " %7" PRIu64, | 1158 | color_fprintf(stdout, color, " %7" PRIu64, |
1114 | nr_samples); | 1159 | sample.nr_samples); |
1115 | else | 1160 | else |
1116 | color_fprintf(stdout, color, " %7.2f", percent); | 1161 | color_fprintf(stdout, color, " %7.2f", percent); |
1117 | } | 1162 | } |
@@ -1127,13 +1172,13 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1127 | if (ppercents != &percent) | 1172 | if (ppercents != &percent) |
1128 | free(ppercents); | 1173 | free(ppercents); |
1129 | 1174 | ||
1130 | if (psamples != &nr_samples) | 1175 | if (psamples != &sample) |
1131 | free(psamples); | 1176 | free(psamples); |
1132 | 1177 | ||
1133 | } else if (max_lines && printed >= max_lines) | 1178 | } else if (max_lines && printed >= max_lines) |
1134 | return 1; | 1179 | return 1; |
1135 | else { | 1180 | else { |
1136 | int width = 8; | 1181 | int width = symbol_conf.show_total_period ? 12 : 8; |
1137 | 1182 | ||
1138 | if (queue) | 1183 | if (queue) |
1139 | return -1; | 1184 | return -1; |
@@ -1327,7 +1372,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil | |||
1327 | !dso__is_kcore(dso)) | 1372 | !dso__is_kcore(dso)) |
1328 | return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; | 1373 | return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; |
1329 | 1374 | ||
1330 | build_id_filename = dso__build_id_filename(dso, NULL, 0); | 1375 | build_id_filename = dso__build_id_filename(dso, NULL, 0, false); |
1331 | if (build_id_filename) { | 1376 | if (build_id_filename) { |
1332 | __symbol__join_symfs(filename, filename_size, build_id_filename); | 1377 | __symbol__join_symfs(filename, filename_size, build_id_filename); |
1333 | free(build_id_filename); | 1378 | free(build_id_filename); |
@@ -1381,7 +1426,7 @@ static const char *annotate__norm_arch(const char *arch_name) | |||
1381 | 1426 | ||
1382 | int symbol__disassemble(struct symbol *sym, struct map *map, | 1427 | int symbol__disassemble(struct symbol *sym, struct map *map, |
1383 | const char *arch_name, size_t privsize, | 1428 | const char *arch_name, size_t privsize, |
1384 | struct arch **parch) | 1429 | struct arch **parch, char *cpuid) |
1385 | { | 1430 | { |
1386 | struct dso *dso = map->dso; | 1431 | struct dso *dso = map->dso; |
1387 | char command[PATH_MAX * 2]; | 1432 | char command[PATH_MAX * 2]; |
@@ -1411,7 +1456,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, | |||
1411 | *parch = arch; | 1456 | *parch = arch; |
1412 | 1457 | ||
1413 | if (arch->init) { | 1458 | if (arch->init) { |
1414 | err = arch->init(arch); | 1459 | err = arch->init(arch, cpuid); |
1415 | if (err) { | 1460 | if (err) { |
1416 | pr_err("%s: failed to initialize %s arch priv area\n", __func__, arch->name); | 1461 | pr_err("%s: failed to initialize %s arch priv area\n", __func__, arch->name); |
1417 | return err; | 1462 | return err; |
@@ -1648,19 +1693,19 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1648 | struct sym_hist *h = annotation__histogram(notes, evidx); | 1693 | struct sym_hist *h = annotation__histogram(notes, evidx); |
1649 | struct rb_root tmp_root = RB_ROOT; | 1694 | struct rb_root tmp_root = RB_ROOT; |
1650 | int nr_pcnt = 1; | 1695 | int nr_pcnt = 1; |
1651 | u64 h_sum = h->sum; | 1696 | u64 nr_samples = h->nr_samples; |
1652 | size_t sizeof_src_line = sizeof(struct source_line); | 1697 | size_t sizeof_src_line = sizeof(struct source_line); |
1653 | 1698 | ||
1654 | if (perf_evsel__is_group_event(evsel)) { | 1699 | if (perf_evsel__is_group_event(evsel)) { |
1655 | for (i = 1; i < evsel->nr_members; i++) { | 1700 | for (i = 1; i < evsel->nr_members; i++) { |
1656 | h = annotation__histogram(notes, evidx + i); | 1701 | h = annotation__histogram(notes, evidx + i); |
1657 | h_sum += h->sum; | 1702 | nr_samples += h->nr_samples; |
1658 | } | 1703 | } |
1659 | nr_pcnt = evsel->nr_members; | 1704 | nr_pcnt = evsel->nr_members; |
1660 | sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->samples); | 1705 | sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->samples); |
1661 | } | 1706 | } |
1662 | 1707 | ||
1663 | if (!h_sum) | 1708 | if (!nr_samples) |
1664 | return 0; | 1709 | return 0; |
1665 | 1710 | ||
1666 | src_line = notes->src->lines = calloc(len, sizeof_src_line); | 1711 | src_line = notes->src->lines = calloc(len, sizeof_src_line); |
@@ -1670,7 +1715,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1670 | start = map__rip_2objdump(map, sym->start); | 1715 | start = map__rip_2objdump(map, sym->start); |
1671 | 1716 | ||
1672 | for (i = 0; i < len; i++) { | 1717 | for (i = 0; i < len; i++) { |
1673 | u64 offset, nr_samples; | 1718 | u64 offset; |
1674 | double percent_max = 0.0; | 1719 | double percent_max = 0.0; |
1675 | 1720 | ||
1676 | src_line->nr_pcnt = nr_pcnt; | 1721 | src_line->nr_pcnt = nr_pcnt; |
@@ -1679,9 +1724,9 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1679 | double percent = 0.0; | 1724 | double percent = 0.0; |
1680 | 1725 | ||
1681 | h = annotation__histogram(notes, evidx + k); | 1726 | h = annotation__histogram(notes, evidx + k); |
1682 | nr_samples = h->addr[i]; | 1727 | nr_samples = h->addr[i].nr_samples; |
1683 | if (h->sum) | 1728 | if (h->nr_samples) |
1684 | percent = 100.0 * nr_samples / h->sum; | 1729 | percent = 100.0 * nr_samples / h->nr_samples; |
1685 | 1730 | ||
1686 | if (percent > percent_max) | 1731 | if (percent > percent_max) |
1687 | percent_max = percent; | 1732 | percent_max = percent; |
@@ -1750,10 +1795,10 @@ static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel) | |||
1750 | u64 len = symbol__size(sym), offset; | 1795 | u64 len = symbol__size(sym), offset; |
1751 | 1796 | ||
1752 | for (offset = 0; offset < len; ++offset) | 1797 | for (offset = 0; offset < len; ++offset) |
1753 | if (h->addr[offset] != 0) | 1798 | if (h->addr[offset].nr_samples != 0) |
1754 | printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, | 1799 | printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, |
1755 | sym->start + offset, h->addr[offset]); | 1800 | sym->start + offset, h->addr[offset].nr_samples); |
1756 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); | 1801 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples); |
1757 | } | 1802 | } |
1758 | 1803 | ||
1759 | int symbol__annotate_printf(struct symbol *sym, struct map *map, | 1804 | int symbol__annotate_printf(struct symbol *sym, struct map *map, |
@@ -1771,7 +1816,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, | |||
1771 | int printed = 2, queue_len = 0; | 1816 | int printed = 2, queue_len = 0; |
1772 | int more = 0; | 1817 | int more = 0; |
1773 | u64 len; | 1818 | u64 len; |
1774 | int width = 8; | 1819 | int width = symbol_conf.show_total_period ? 12 : 8; |
1775 | int graph_dotted_len; | 1820 | int graph_dotted_len; |
1776 | 1821 | ||
1777 | filename = strdup(dso->long_name); | 1822 | filename = strdup(dso->long_name); |
@@ -1789,7 +1834,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, | |||
1789 | width *= evsel->nr_members; | 1834 | width *= evsel->nr_members; |
1790 | 1835 | ||
1791 | graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n", | 1836 | graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n", |
1792 | width, width, "Percent", d_filename, evsel_name, h->sum); | 1837 | width, width, symbol_conf.show_total_period ? "Period" : |
1838 | symbol_conf.show_nr_samples ? "Samples" : "Percent", | ||
1839 | d_filename, evsel_name, h->nr_samples); | ||
1793 | 1840 | ||
1794 | printf("%-*.*s----\n", | 1841 | printf("%-*.*s----\n", |
1795 | graph_dotted_len, graph_dotted_len, graph_dotted_line); | 1842 | graph_dotted_len, graph_dotted_len, graph_dotted_line); |
@@ -1853,10 +1900,10 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) | |||
1853 | struct sym_hist *h = annotation__histogram(notes, evidx); | 1900 | struct sym_hist *h = annotation__histogram(notes, evidx); |
1854 | int len = symbol__size(sym), offset; | 1901 | int len = symbol__size(sym), offset; |
1855 | 1902 | ||
1856 | h->sum = 0; | 1903 | h->nr_samples = 0; |
1857 | for (offset = 0; offset < len; ++offset) { | 1904 | for (offset = 0; offset < len; ++offset) { |
1858 | h->addr[offset] = h->addr[offset] * 7 / 8; | 1905 | h->addr[offset].nr_samples = h->addr[offset].nr_samples * 7 / 8; |
1859 | h->sum += h->addr[offset]; | 1906 | h->nr_samples += h->addr[offset].nr_samples; |
1860 | } | 1907 | } |
1861 | } | 1908 | } |
1862 | 1909 | ||
@@ -1907,7 +1954,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, | |||
1907 | u64 len; | 1954 | u64 len; |
1908 | 1955 | ||
1909 | if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), | 1956 | if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), |
1910 | 0, NULL) < 0) | 1957 | 0, NULL, NULL) < 0) |
1911 | return -1; | 1958 | return -1; |
1912 | 1959 | ||
1913 | len = symbol__size(sym); | 1960 | len = symbol__size(sym); |