aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/annotate.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2016-11-24 09:16:06 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-11-25 08:24:16 -0500
commit75b49202d87c142a646e37edb466462ea6fbe0fb (patch)
treeaff7e428622c52271ae0b4052281082f5c413132 /tools/perf/util/annotate.c
parent47414424c53a70eceb0fc6e0a35a31a2b763d5b2 (diff)
perf annotate: Remove duplicate 'name' field from disasm_line
The disasm_line::name field is always equal to ins::name, being used just to locate the instruction's ins_ops from the per-arch instructions table. Eliminate this duplication, nuking that field and instead make ins__find() return an ins_ops, store it in disasm_line::ins.ops, and keep just in disasm_line::ins.name what was in disasm_line::name, this way we end up not keeping a reference to entries in the per-arch instructions table. This in turn will help supporting multiple ways to manage the per-arch instructions table, allowing resorting that array, for instance, when the entries will move after references to its addresses were made. The same problem is avoided when one grows the array with realloc. So architectures simply keeping a constant array will work as well as architectures building the table using regular expressions or other logic that involves resorting the table. Reviewed-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Chris Riyder <chris.ryder@arm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kim Phillips <kim.phillips@arm.com> Cc: Markus Trippelsdorf <markus@trippelsdorf.de> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Cc: Pawel Moll <pawel.moll@arm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Russell King <rmk+kernel@arm.linux.org.uk> Cc: Taeung Song <treeze.taeung@gmail.com> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/n/tip-vr899azvabnw9gtuepuqfd9t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r--tools/perf/util/annotate.c73
1 files changed, 34 insertions, 39 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 095d90a9077f..b48a39be071b 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -28,8 +28,8 @@ const char *disassembler_style;
28const char *objdump_path; 28const char *objdump_path;
29static regex_t file_lineno; 29static regex_t file_lineno;
30 30
31static struct ins *ins__find(struct arch *arch, const char *name); 31static struct ins_ops *ins__find(struct arch *arch, const char *name);
32static int disasm_line__parse(char *line, char **namep, char **rawp); 32static int disasm_line__parse(char *line, const char **namep, char **rawp);
33 33
34struct arch { 34struct arch {
35 const char *name; 35 const char *name;
@@ -218,26 +218,20 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
218 218
219static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map *map) 219static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map *map)
220{ 220{
221 char *name;
222
223 ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); 221 ops->locked.ops = zalloc(sizeof(*ops->locked.ops));
224 if (ops->locked.ops == NULL) 222 if (ops->locked.ops == NULL)
225 return 0; 223 return 0;
226 224
227 if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0) 225 if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops->raw) < 0)
228 goto out_free_ops; 226 goto out_free_ops;
229 227
230 ops->locked.ins = ins__find(arch, name); 228 ops->locked.ins.ops = ins__find(arch, ops->locked.ins.name);
231 free(name);
232 229
233 if (ops->locked.ins == NULL) 230 if (ops->locked.ins.ops == NULL)
234 goto out_free_ops; 231 goto out_free_ops;
235 232
236 if (!ops->locked.ins->ops) 233 if (ops->locked.ins.ops->parse &&
237 return 0; 234 ops->locked.ins.ops->parse(arch, ops->locked.ops, map) < 0)
238
239 if (ops->locked.ins->ops->parse &&
240 ops->locked.ins->ops->parse(arch, ops->locked.ops, map) < 0)
241 goto out_free_ops; 235 goto out_free_ops;
242 236
243 return 0; 237 return 0;
@@ -252,19 +246,19 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
252{ 246{
253 int printed; 247 int printed;
254 248
255 if (ops->locked.ins == NULL) 249 if (ops->locked.ins.ops == NULL)
256 return ins__raw_scnprintf(ins, bf, size, ops); 250 return ins__raw_scnprintf(ins, bf, size, ops);
257 251
258 printed = scnprintf(bf, size, "%-6.6s ", ins->name); 252 printed = scnprintf(bf, size, "%-6.6s ", ins->name);
259 return printed + ins__scnprintf(ops->locked.ins, bf + printed, 253 return printed + ins__scnprintf(&ops->locked.ins, bf + printed,
260 size - printed, ops->locked.ops); 254 size - printed, ops->locked.ops);
261} 255}
262 256
263static void lock__delete(struct ins_operands *ops) 257static void lock__delete(struct ins_operands *ops)
264{ 258{
265 struct ins *ins = ops->locked.ins; 259 struct ins *ins = &ops->locked.ins;
266 260
267 if (ins && ins->ops->free) 261 if (ins->ops && ins->ops->free)
268 ins->ops->free(ops->locked.ops); 262 ins->ops->free(ops->locked.ops);
269 else 263 else
270 ins__delete(ops->locked.ops); 264 ins__delete(ops->locked.ops);
@@ -425,8 +419,9 @@ static void ins__sort(struct arch *arch)
425 qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); 419 qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp);
426} 420}
427 421
428static struct ins *ins__find(struct arch *arch, const char *name) 422static struct ins_ops *ins__find(struct arch *arch, const char *name)
429{ 423{
424 struct ins *ins;
430 const int nmemb = arch->nr_instructions; 425 const int nmemb = arch->nr_instructions;
431 426
432 if (!arch->sorted_instructions) { 427 if (!arch->sorted_instructions) {
@@ -434,7 +429,8 @@ static struct ins *ins__find(struct arch *arch, const char *name)
434 arch->sorted_instructions = true; 429 arch->sorted_instructions = true;
435 } 430 }
436 431
437 return bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); 432 ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp);
433 return ins ? ins->ops : NULL;
438} 434}
439 435
440static int arch__key_cmp(const void *name, const void *archp) 436static int arch__key_cmp(const void *name, const void *archp)
@@ -691,19 +687,16 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
691 687
692static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) 688static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map)
693{ 689{
694 dl->ins = ins__find(arch, dl->name); 690 dl->ins.ops = ins__find(arch, dl->ins.name);
695
696 if (dl->ins == NULL)
697 return;
698 691
699 if (!dl->ins->ops) 692 if (!dl->ins.ops)
700 return; 693 return;
701 694
702 if (dl->ins->ops->parse && dl->ins->ops->parse(arch, &dl->ops, map) < 0) 695 if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, map) < 0)
703 dl->ins = NULL; 696 dl->ins.ops = NULL;
704} 697}
705 698
706static int disasm_line__parse(char *line, char **namep, char **rawp) 699static int disasm_line__parse(char *line, const char **namep, char **rawp)
707{ 700{
708 char *name = line, tmp; 701 char *name = line, tmp;
709 702
@@ -736,7 +729,8 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
736 return 0; 729 return 0;
737 730
738out_free_name: 731out_free_name:
739 zfree(namep); 732 free((void *)namep);
733 *namep = NULL;
740 return -1; 734 return -1;
741} 735}
742 736
@@ -755,7 +749,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line,
755 goto out_delete; 749 goto out_delete;
756 750
757 if (offset != -1) { 751 if (offset != -1) {
758 if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0) 752 if (disasm_line__parse(dl->line, &dl->ins.name, &dl->ops.raw) < 0)
759 goto out_free_line; 753 goto out_free_line;
760 754
761 disasm_line__init_ins(dl, arch, map); 755 disasm_line__init_ins(dl, arch, map);
@@ -774,20 +768,21 @@ out_delete:
774void disasm_line__free(struct disasm_line *dl) 768void disasm_line__free(struct disasm_line *dl)
775{ 769{
776 zfree(&dl->line); 770 zfree(&dl->line);
777 zfree(&dl->name); 771 if (dl->ins.ops && dl->ins.ops->free)
778 if (dl->ins && dl->ins->ops->free) 772 dl->ins.ops->free(&dl->ops);
779 dl->ins->ops->free(&dl->ops);
780 else 773 else
781 ins__delete(&dl->ops); 774 ins__delete(&dl->ops);
775 free((void *)dl->ins.name);
776 dl->ins.name = NULL;
782 free(dl); 777 free(dl);
783} 778}
784 779
785int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw) 780int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw)
786{ 781{
787 if (raw || !dl->ins) 782 if (raw || !dl->ins.ops)
788 return scnprintf(bf, size, "%-6.6s %s", dl->name, dl->ops.raw); 783 return scnprintf(bf, size, "%-6.6s %s", dl->ins.name, dl->ops.raw);
789 784
790 return ins__scnprintf(dl->ins, bf, size, &dl->ops); 785 return ins__scnprintf(&dl->ins, bf, size, &dl->ops);
791} 786}
792 787
793static void disasm__add(struct list_head *head, struct disasm_line *line) 788static void disasm__add(struct list_head *head, struct disasm_line *line)
@@ -1143,7 +1138,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
1143 map__rip_2objdump(map, sym->start); 1138 map__rip_2objdump(map, sym->start);
1144 1139
1145 /* kcore has no symbols, so add the call target name */ 1140 /* kcore has no symbols, so add the call target name */
1146 if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) { 1141 if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.name) {
1147 struct addr_map_symbol target = { 1142 struct addr_map_symbol target = {
1148 .map = map, 1143 .map = map,
1149 .addr = dl->ops.target.addr, 1144 .addr = dl->ops.target.addr,
@@ -1173,8 +1168,8 @@ static void delete_last_nop(struct symbol *sym)
1173 while (!list_empty(list)) { 1168 while (!list_empty(list)) {
1174 dl = list_entry(list->prev, struct disasm_line, node); 1169 dl = list_entry(list->prev, struct disasm_line, node);
1175 1170
1176 if (dl->ins && dl->ins->ops) { 1171 if (dl->ins.ops) {
1177 if (dl->ins->ops != &nop_ops) 1172 if (dl->ins.ops != &nop_ops)
1178 return; 1173 return;
1179 } else { 1174 } else {
1180 if (!strstr(dl->line, " nop ") && 1175 if (!strstr(dl->line, " nop ") &&
@@ -1767,7 +1762,7 @@ static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp)
1767 if (dl->offset == -1) 1762 if (dl->offset == -1)
1768 return fprintf(fp, "%s\n", dl->line); 1763 return fprintf(fp, "%s\n", dl->line);
1769 1764
1770 printed = fprintf(fp, "%#" PRIx64 " %s", dl->offset, dl->name); 1765 printed = fprintf(fp, "%#" PRIx64 " %s", dl->offset, dl->ins.name);
1771 1766
1772 if (dl->ops.raw[0] != '\0') { 1767 if (dl->ops.raw[0] != '\0') {
1773 printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ", 1768 printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ",