diff options
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 137 |
1 files changed, 89 insertions, 48 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index be1caabb9290..4397a8b6e6cd 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -47,7 +47,12 @@ struct arch { | |||
47 | bool sorted_instructions; | 47 | bool sorted_instructions; |
48 | bool initialized; | 48 | bool initialized; |
49 | void *priv; | 49 | void *priv; |
50 | unsigned int model; | ||
51 | unsigned int family; | ||
50 | int (*init)(struct arch *arch); | 52 | int (*init)(struct arch *arch); |
53 | bool (*ins_is_fused)(struct arch *arch, const char *ins1, | ||
54 | const char *ins2); | ||
55 | int (*cpuid_parse)(struct arch *arch, char *cpuid); | ||
51 | struct { | 56 | struct { |
52 | char comment_char; | 57 | char comment_char; |
53 | char skip_functions_char; | 58 | char skip_functions_char; |
@@ -129,6 +134,8 @@ static struct arch architectures[] = { | |||
129 | .name = "x86", | 134 | .name = "x86", |
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, | ||
138 | .cpuid_parse = x86__cpuid_parse, | ||
132 | .objdump = { | 139 | .objdump = { |
133 | .comment_char = '#', | 140 | .comment_char = '#', |
134 | }, | 141 | }, |
@@ -171,6 +178,14 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size, | |||
171 | return ins__raw_scnprintf(ins, bf, size, ops); | 178 | return ins__raw_scnprintf(ins, bf, size, ops); |
172 | } | 179 | } |
173 | 180 | ||
181 | bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) | ||
182 | { | ||
183 | if (!arch || !arch->ins_is_fused) | ||
184 | return false; | ||
185 | |||
186 | return arch->ins_is_fused(arch, ins1, ins2); | ||
187 | } | ||
188 | |||
174 | static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) | 189 | static int call__parse(struct arch *arch, struct ins_operands *ops, struct map *map) |
175 | { | 190 | { |
176 | char *endptr, *tok, *name; | 191 | char *endptr, *tok, *name; |
@@ -502,6 +517,11 @@ bool ins__is_ret(const struct ins *ins) | |||
502 | return ins->ops == &ret_ops; | 517 | return ins->ops == &ret_ops; |
503 | } | 518 | } |
504 | 519 | ||
520 | bool ins__is_lock(const struct ins *ins) | ||
521 | { | ||
522 | return ins->ops == &lock_ops; | ||
523 | } | ||
524 | |||
505 | static int ins__key_cmp(const void *name, const void *insp) | 525 | static int ins__key_cmp(const void *name, const void *insp) |
506 | { | 526 | { |
507 | const struct ins *ins = insp; | 527 | const struct ins *ins = insp; |
@@ -590,10 +610,10 @@ int symbol__alloc_hist(struct symbol *sym) | |||
590 | size_t sizeof_sym_hist; | 610 | size_t sizeof_sym_hist; |
591 | 611 | ||
592 | /* Check for overflow when calculating sizeof_sym_hist */ | 612 | /* Check for overflow when calculating sizeof_sym_hist */ |
593 | if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64)) | 613 | if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry)) |
594 | return -1; | 614 | return -1; |
595 | 615 | ||
596 | sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64)); | 616 | sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(struct sym_hist_entry)); |
597 | 617 | ||
598 | /* Check for overflow in zalloc argument */ | 618 | /* Check for overflow in zalloc argument */ |
599 | if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) | 619 | if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) |
@@ -677,7 +697,8 @@ static int __symbol__account_cycles(struct annotation *notes, | |||
677 | } | 697 | } |
678 | 698 | ||
679 | static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 699 | static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
680 | struct annotation *notes, int evidx, u64 addr) | 700 | struct annotation *notes, int evidx, u64 addr, |
701 | struct perf_sample *sample) | ||
681 | { | 702 | { |
682 | unsigned offset; | 703 | unsigned offset; |
683 | struct sym_hist *h; | 704 | struct sym_hist *h; |
@@ -693,12 +714,15 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
693 | 714 | ||
694 | offset = addr - sym->start; | 715 | offset = addr - sym->start; |
695 | h = annotation__histogram(notes, evidx); | 716 | h = annotation__histogram(notes, evidx); |
696 | h->sum++; | 717 | h->nr_samples++; |
697 | h->addr[offset]++; | 718 | h->addr[offset].nr_samples++; |
719 | h->period += sample->period; | ||
720 | h->addr[offset].period += sample->period; | ||
698 | 721 | ||
699 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 | 722 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 |
700 | ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, | 723 | ", evidx=%d] => nr_samples: %" PRIu64 ", period: %" PRIu64 "\n", |
701 | addr, addr - sym->start, evidx, h->addr[offset]); | 724 | sym->start, sym->name, addr, addr - sym->start, evidx, |
725 | h->addr[offset].nr_samples, h->addr[offset].period); | ||
702 | return 0; | 726 | return 0; |
703 | } | 727 | } |
704 | 728 | ||
@@ -718,7 +742,8 @@ static struct annotation *symbol__get_annotation(struct symbol *sym, bool cycles | |||
718 | } | 742 | } |
719 | 743 | ||
720 | static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | 744 | static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, |
721 | int evidx, u64 addr) | 745 | int evidx, u64 addr, |
746 | struct perf_sample *sample) | ||
722 | { | 747 | { |
723 | struct annotation *notes; | 748 | struct annotation *notes; |
724 | 749 | ||
@@ -727,7 +752,7 @@ static int symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
727 | notes = symbol__get_annotation(sym, false); | 752 | notes = symbol__get_annotation(sym, false); |
728 | if (notes == NULL) | 753 | if (notes == NULL) |
729 | return -ENOMEM; | 754 | return -ENOMEM; |
730 | return __symbol__inc_addr_samples(sym, map, notes, evidx, addr); | 755 | return __symbol__inc_addr_samples(sym, map, notes, evidx, addr, sample); |
731 | } | 756 | } |
732 | 757 | ||
733 | static int symbol__account_cycles(u64 addr, u64 start, | 758 | static int symbol__account_cycles(u64 addr, u64 start, |
@@ -791,14 +816,16 @@ int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, | |||
791 | return err; | 816 | return err; |
792 | } | 817 | } |
793 | 818 | ||
794 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, int evidx) | 819 | int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample, |
820 | int evidx) | ||
795 | { | 821 | { |
796 | return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr); | 822 | return symbol__inc_addr_samples(ams->sym, ams->map, evidx, ams->al_addr, sample); |
797 | } | 823 | } |
798 | 824 | ||
799 | int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) | 825 | int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, |
826 | int evidx, u64 ip) | ||
800 | { | 827 | { |
801 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); | 828 | return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip, sample); |
802 | } | 829 | } |
803 | 830 | ||
804 | static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) | 831 | static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) |
@@ -908,11 +935,12 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa | |||
908 | } | 935 | } |
909 | 936 | ||
910 | double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, | 937 | double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, |
911 | s64 end, const char **path, u64 *nr_samples) | 938 | s64 end, const char **path, struct sym_hist_entry *sample) |
912 | { | 939 | { |
913 | struct source_line *src_line = notes->src->lines; | 940 | struct source_line *src_line = notes->src->lines; |
914 | double percent = 0.0; | 941 | double percent = 0.0; |
915 | *nr_samples = 0; | 942 | |
943 | sample->nr_samples = sample->period = 0; | ||
916 | 944 | ||
917 | if (src_line) { | 945 | if (src_line) { |
918 | size_t sizeof_src_line = sizeof(*src_line) + | 946 | size_t sizeof_src_line = sizeof(*src_line) + |
@@ -926,19 +954,24 @@ double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, | |||
926 | *path = src_line->path; | 954 | *path = src_line->path; |
927 | 955 | ||
928 | percent += src_line->samples[evidx].percent; | 956 | percent += src_line->samples[evidx].percent; |
929 | *nr_samples += src_line->samples[evidx].nr; | 957 | sample->nr_samples += src_line->samples[evidx].nr; |
930 | offset++; | 958 | offset++; |
931 | } | 959 | } |
932 | } else { | 960 | } else { |
933 | struct sym_hist *h = annotation__histogram(notes, evidx); | 961 | struct sym_hist *h = annotation__histogram(notes, evidx); |
934 | unsigned int hits = 0; | 962 | unsigned int hits = 0; |
963 | u64 period = 0; | ||
935 | 964 | ||
936 | while (offset < end) | 965 | while (offset < end) { |
937 | hits += h->addr[offset++]; | 966 | hits += h->addr[offset].nr_samples; |
967 | period += h->addr[offset].period; | ||
968 | ++offset; | ||
969 | } | ||
938 | 970 | ||
939 | if (h->sum) { | 971 | if (h->nr_samples) { |
940 | *nr_samples = hits; | 972 | sample->period = period; |
941 | percent = 100.0 * hits / h->sum; | 973 | sample->nr_samples = hits; |
974 | percent = 100.0 * hits / h->nr_samples; | ||
942 | } | 975 | } |
943 | } | 976 | } |
944 | 977 | ||
@@ -1037,10 +1070,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1037 | 1070 | ||
1038 | if (dl->offset != -1) { | 1071 | if (dl->offset != -1) { |
1039 | const char *path = NULL; | 1072 | const char *path = NULL; |
1040 | u64 nr_samples; | ||
1041 | double percent, max_percent = 0.0; | 1073 | double percent, max_percent = 0.0; |
1042 | double *ppercents = &percent; | 1074 | double *ppercents = &percent; |
1043 | u64 *psamples = &nr_samples; | 1075 | struct sym_hist_entry sample; |
1076 | struct sym_hist_entry *psamples = &sample; | ||
1044 | int i, nr_percent = 1; | 1077 | int i, nr_percent = 1; |
1045 | const char *color; | 1078 | const char *color; |
1046 | struct annotation *notes = symbol__annotation(sym); | 1079 | struct annotation *notes = symbol__annotation(sym); |
@@ -1054,7 +1087,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1054 | if (perf_evsel__is_group_event(evsel)) { | 1087 | if (perf_evsel__is_group_event(evsel)) { |
1055 | nr_percent = evsel->nr_members; | 1088 | nr_percent = evsel->nr_members; |
1056 | ppercents = calloc(nr_percent, sizeof(double)); | 1089 | ppercents = calloc(nr_percent, sizeof(double)); |
1057 | psamples = calloc(nr_percent, sizeof(u64)); | 1090 | psamples = calloc(nr_percent, sizeof(struct sym_hist_entry)); |
1058 | if (ppercents == NULL || psamples == NULL) { | 1091 | if (ppercents == NULL || psamples == NULL) { |
1059 | return -1; | 1092 | return -1; |
1060 | } | 1093 | } |
@@ -1065,10 +1098,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1065 | notes->src->lines ? i : evsel->idx + i, | 1098 | notes->src->lines ? i : evsel->idx + i, |
1066 | offset, | 1099 | offset, |
1067 | next ? next->offset : (s64) len, | 1100 | next ? next->offset : (s64) len, |
1068 | &path, &nr_samples); | 1101 | &path, &sample); |
1069 | 1102 | ||
1070 | ppercents[i] = percent; | 1103 | ppercents[i] = percent; |
1071 | psamples[i] = nr_samples; | 1104 | psamples[i] = sample; |
1072 | if (percent > max_percent) | 1105 | if (percent > max_percent) |
1073 | max_percent = percent; | 1106 | max_percent = percent; |
1074 | } | 1107 | } |
@@ -1106,12 +1139,15 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1106 | 1139 | ||
1107 | for (i = 0; i < nr_percent; i++) { | 1140 | for (i = 0; i < nr_percent; i++) { |
1108 | percent = ppercents[i]; | 1141 | percent = ppercents[i]; |
1109 | nr_samples = psamples[i]; | 1142 | sample = psamples[i]; |
1110 | color = get_percent_color(percent); | 1143 | color = get_percent_color(percent); |
1111 | 1144 | ||
1112 | if (symbol_conf.show_total_period) | 1145 | if (symbol_conf.show_total_period) |
1146 | color_fprintf(stdout, color, " %11" PRIu64, | ||
1147 | sample.period); | ||
1148 | else if (symbol_conf.show_nr_samples) | ||
1113 | color_fprintf(stdout, color, " %7" PRIu64, | 1149 | color_fprintf(stdout, color, " %7" PRIu64, |
1114 | nr_samples); | 1150 | sample.nr_samples); |
1115 | else | 1151 | else |
1116 | color_fprintf(stdout, color, " %7.2f", percent); | 1152 | color_fprintf(stdout, color, " %7.2f", percent); |
1117 | } | 1153 | } |
@@ -1127,13 +1163,13 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1127 | if (ppercents != &percent) | 1163 | if (ppercents != &percent) |
1128 | free(ppercents); | 1164 | free(ppercents); |
1129 | 1165 | ||
1130 | if (psamples != &nr_samples) | 1166 | if (psamples != &sample) |
1131 | free(psamples); | 1167 | free(psamples); |
1132 | 1168 | ||
1133 | } else if (max_lines && printed >= max_lines) | 1169 | } else if (max_lines && printed >= max_lines) |
1134 | return 1; | 1170 | return 1; |
1135 | else { | 1171 | else { |
1136 | int width = 8; | 1172 | int width = symbol_conf.show_total_period ? 12 : 8; |
1137 | 1173 | ||
1138 | if (queue) | 1174 | if (queue) |
1139 | return -1; | 1175 | return -1; |
@@ -1327,7 +1363,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil | |||
1327 | !dso__is_kcore(dso)) | 1363 | !dso__is_kcore(dso)) |
1328 | return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; | 1364 | return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX; |
1329 | 1365 | ||
1330 | build_id_filename = dso__build_id_filename(dso, NULL, 0); | 1366 | build_id_filename = dso__build_id_filename(dso, NULL, 0, false); |
1331 | if (build_id_filename) { | 1367 | if (build_id_filename) { |
1332 | __symbol__join_symfs(filename, filename_size, build_id_filename); | 1368 | __symbol__join_symfs(filename, filename_size, build_id_filename); |
1333 | free(build_id_filename); | 1369 | free(build_id_filename); |
@@ -1381,7 +1417,7 @@ static const char *annotate__norm_arch(const char *arch_name) | |||
1381 | 1417 | ||
1382 | int symbol__disassemble(struct symbol *sym, struct map *map, | 1418 | int symbol__disassemble(struct symbol *sym, struct map *map, |
1383 | const char *arch_name, size_t privsize, | 1419 | const char *arch_name, size_t privsize, |
1384 | struct arch **parch) | 1420 | struct arch **parch, char *cpuid) |
1385 | { | 1421 | { |
1386 | struct dso *dso = map->dso; | 1422 | struct dso *dso = map->dso; |
1387 | char command[PATH_MAX * 2]; | 1423 | char command[PATH_MAX * 2]; |
@@ -1418,6 +1454,9 @@ int symbol__disassemble(struct symbol *sym, struct map *map, | |||
1418 | } | 1454 | } |
1419 | } | 1455 | } |
1420 | 1456 | ||
1457 | if (arch->cpuid_parse && cpuid) | ||
1458 | arch->cpuid_parse(arch, cpuid); | ||
1459 | |||
1421 | pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, | 1460 | pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__, |
1422 | symfs_filename, sym->name, map->unmap_ip(map, sym->start), | 1461 | symfs_filename, sym->name, map->unmap_ip(map, sym->start), |
1423 | map->unmap_ip(map, sym->end)); | 1462 | map->unmap_ip(map, sym->end)); |
@@ -1648,19 +1687,19 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1648 | struct sym_hist *h = annotation__histogram(notes, evidx); | 1687 | struct sym_hist *h = annotation__histogram(notes, evidx); |
1649 | struct rb_root tmp_root = RB_ROOT; | 1688 | struct rb_root tmp_root = RB_ROOT; |
1650 | int nr_pcnt = 1; | 1689 | int nr_pcnt = 1; |
1651 | u64 h_sum = h->sum; | 1690 | u64 nr_samples = h->nr_samples; |
1652 | size_t sizeof_src_line = sizeof(struct source_line); | 1691 | size_t sizeof_src_line = sizeof(struct source_line); |
1653 | 1692 | ||
1654 | if (perf_evsel__is_group_event(evsel)) { | 1693 | if (perf_evsel__is_group_event(evsel)) { |
1655 | for (i = 1; i < evsel->nr_members; i++) { | 1694 | for (i = 1; i < evsel->nr_members; i++) { |
1656 | h = annotation__histogram(notes, evidx + i); | 1695 | h = annotation__histogram(notes, evidx + i); |
1657 | h_sum += h->sum; | 1696 | nr_samples += h->nr_samples; |
1658 | } | 1697 | } |
1659 | nr_pcnt = evsel->nr_members; | 1698 | nr_pcnt = evsel->nr_members; |
1660 | sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->samples); | 1699 | sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->samples); |
1661 | } | 1700 | } |
1662 | 1701 | ||
1663 | if (!h_sum) | 1702 | if (!nr_samples) |
1664 | return 0; | 1703 | return 0; |
1665 | 1704 | ||
1666 | src_line = notes->src->lines = calloc(len, sizeof_src_line); | 1705 | src_line = notes->src->lines = calloc(len, sizeof_src_line); |
@@ -1670,7 +1709,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1670 | start = map__rip_2objdump(map, sym->start); | 1709 | start = map__rip_2objdump(map, sym->start); |
1671 | 1710 | ||
1672 | for (i = 0; i < len; i++) { | 1711 | for (i = 0; i < len; i++) { |
1673 | u64 offset, nr_samples; | 1712 | u64 offset; |
1674 | double percent_max = 0.0; | 1713 | double percent_max = 0.0; |
1675 | 1714 | ||
1676 | src_line->nr_pcnt = nr_pcnt; | 1715 | src_line->nr_pcnt = nr_pcnt; |
@@ -1679,9 +1718,9 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1679 | double percent = 0.0; | 1718 | double percent = 0.0; |
1680 | 1719 | ||
1681 | h = annotation__histogram(notes, evidx + k); | 1720 | h = annotation__histogram(notes, evidx + k); |
1682 | nr_samples = h->addr[i]; | 1721 | nr_samples = h->addr[i].nr_samples; |
1683 | if (h->sum) | 1722 | if (h->nr_samples) |
1684 | percent = 100.0 * nr_samples / h->sum; | 1723 | percent = 100.0 * nr_samples / h->nr_samples; |
1685 | 1724 | ||
1686 | if (percent > percent_max) | 1725 | if (percent > percent_max) |
1687 | percent_max = percent; | 1726 | percent_max = percent; |
@@ -1750,10 +1789,10 @@ static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel) | |||
1750 | u64 len = symbol__size(sym), offset; | 1789 | u64 len = symbol__size(sym), offset; |
1751 | 1790 | ||
1752 | for (offset = 0; offset < len; ++offset) | 1791 | for (offset = 0; offset < len; ++offset) |
1753 | if (h->addr[offset] != 0) | 1792 | if (h->addr[offset].nr_samples != 0) |
1754 | printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, | 1793 | printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, |
1755 | sym->start + offset, h->addr[offset]); | 1794 | sym->start + offset, h->addr[offset].nr_samples); |
1756 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); | 1795 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->nr_samples", h->nr_samples); |
1757 | } | 1796 | } |
1758 | 1797 | ||
1759 | int symbol__annotate_printf(struct symbol *sym, struct map *map, | 1798 | int symbol__annotate_printf(struct symbol *sym, struct map *map, |
@@ -1771,7 +1810,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, | |||
1771 | int printed = 2, queue_len = 0; | 1810 | int printed = 2, queue_len = 0; |
1772 | int more = 0; | 1811 | int more = 0; |
1773 | u64 len; | 1812 | u64 len; |
1774 | int width = 8; | 1813 | int width = symbol_conf.show_total_period ? 12 : 8; |
1775 | int graph_dotted_len; | 1814 | int graph_dotted_len; |
1776 | 1815 | ||
1777 | filename = strdup(dso->long_name); | 1816 | filename = strdup(dso->long_name); |
@@ -1789,7 +1828,9 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, | |||
1789 | width *= evsel->nr_members; | 1828 | width *= evsel->nr_members; |
1790 | 1829 | ||
1791 | graph_dotted_len = printf(" %-*.*s| Source code & Disassembly of %s for %s (%" PRIu64 " samples)\n", | 1830 | 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); | 1831 | width, width, symbol_conf.show_total_period ? "Period" : |
1832 | symbol_conf.show_nr_samples ? "Samples" : "Percent", | ||
1833 | d_filename, evsel_name, h->nr_samples); | ||
1793 | 1834 | ||
1794 | printf("%-*.*s----\n", | 1835 | printf("%-*.*s----\n", |
1795 | graph_dotted_len, graph_dotted_len, graph_dotted_line); | 1836 | graph_dotted_len, graph_dotted_len, graph_dotted_line); |
@@ -1853,10 +1894,10 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) | |||
1853 | struct sym_hist *h = annotation__histogram(notes, evidx); | 1894 | struct sym_hist *h = annotation__histogram(notes, evidx); |
1854 | int len = symbol__size(sym), offset; | 1895 | int len = symbol__size(sym), offset; |
1855 | 1896 | ||
1856 | h->sum = 0; | 1897 | h->nr_samples = 0; |
1857 | for (offset = 0; offset < len; ++offset) { | 1898 | for (offset = 0; offset < len; ++offset) { |
1858 | h->addr[offset] = h->addr[offset] * 7 / 8; | 1899 | h->addr[offset].nr_samples = h->addr[offset].nr_samples * 7 / 8; |
1859 | h->sum += h->addr[offset]; | 1900 | h->nr_samples += h->addr[offset].nr_samples; |
1860 | } | 1901 | } |
1861 | } | 1902 | } |
1862 | 1903 | ||
@@ -1907,7 +1948,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, | |||
1907 | u64 len; | 1948 | u64 len; |
1908 | 1949 | ||
1909 | if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), | 1950 | if (symbol__disassemble(sym, map, perf_evsel__env_arch(evsel), |
1910 | 0, NULL) < 0) | 1951 | 0, NULL, NULL) < 0) |
1911 | return -1; | 1952 | return -1; |
1912 | 1953 | ||
1913 | len = symbol__size(sym); | 1954 | len = symbol__size(sym); |