Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf annotate: Introduce alternative method of keeping instructions table

Some arches may want to dynamically populate the table using regular
expressions on the instruction names to associate them with a set of
parsing/formatting/etc functions (struct ins_ops), so provide a fallback
for when the ins__find() method fails.

That fall back will be able to resize the arch->instructions, setting
arch->nr_instructions appropriately, helper functions to associate an
ins_ops to an instruction name, growing the arch->instructions if needed
and resorting it are provided, all the arch specific callback needs to
do is to decide if the missing instruction should be added to
arch->instructions with a ins_ops association.

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-auu13yradxf7g5dgtpnzt97a@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+62 -1
+62 -1
tools/perf/util/annotate.c
··· 29 29 static regex_t file_lineno; 30 30 31 31 static struct ins_ops *ins__find(struct arch *arch, const char *name); 32 + static void ins__sort(struct arch *arch); 32 33 static int disasm_line__parse(char *line, const char **namep, char **rawp); 33 34 34 35 struct arch { 35 36 const char *name; 36 37 struct ins *instructions; 37 38 size_t nr_instructions; 39 + size_t nr_instructions_allocated; 40 + struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name); 38 41 bool sorted_instructions; 39 42 struct { 40 43 char comment_char; ··· 52 49 static struct ins_ops nop_ops; 53 50 static struct ins_ops lock_ops; 54 51 static struct ins_ops ret_ops; 52 + 53 + static int arch__grow_instructions(struct arch *arch) 54 + { 55 + struct ins *new_instructions; 56 + size_t new_nr_allocated; 57 + 58 + if (arch->nr_instructions_allocated == 0 && arch->instructions) 59 + goto grow_from_non_allocated_table; 60 + 61 + new_nr_allocated = arch->nr_instructions_allocated + 128; 62 + new_instructions = realloc(arch->instructions, new_nr_allocated * sizeof(struct ins)); 63 + if (new_instructions == NULL) 64 + return -1; 65 + 66 + out_update_instructions: 67 + arch->instructions = new_instructions; 68 + arch->nr_instructions_allocated = new_nr_allocated; 69 + return 0; 70 + 71 + grow_from_non_allocated_table: 72 + new_nr_allocated = arch->nr_instructions + 128; 73 + new_instructions = calloc(new_nr_allocated, sizeof(struct ins)); 74 + if (new_instructions == NULL) 75 + return -1; 76 + 77 + memcpy(new_instructions, arch->instructions, arch->nr_instructions); 78 + goto out_update_instructions; 79 + } 80 + 81 + static __maybe_unused int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops) 82 + { 83 + struct ins *ins; 84 + 85 + if (arch->nr_instructions == arch->nr_instructions_allocated && 86 + arch__grow_instructions(arch)) 87 + return -1; 88 + 89 + ins = &arch->instructions[arch->nr_instructions]; 90 + ins->name = strdup(name); 91 + if (!ins->name) 92 + return -1; 93 + 94 + ins->ops = ops; 95 + arch->nr_instructions++; 96 + 97 + ins__sort(arch); 98 + return 0; 99 + } 55 100 56 101 #include "arch/arm/annotate/instructions.c" 57 102 #include "arch/x86/annotate/instructions.c" ··· 470 419 qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); 471 420 } 472 421 473 - static struct ins_ops *ins__find(struct arch *arch, const char *name) 422 + static struct ins_ops *__ins__find(struct arch *arch, const char *name) 474 423 { 475 424 struct ins *ins; 476 425 const int nmemb = arch->nr_instructions; ··· 482 431 483 432 ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); 484 433 return ins ? ins->ops : NULL; 434 + } 435 + 436 + static struct ins_ops *ins__find(struct arch *arch, const char *name) 437 + { 438 + struct ins_ops *ops = __ins__find(arch, name); 439 + 440 + if (!ops && arch->associate_instruction_ops) 441 + ops = arch->associate_instruction_ops(arch, name); 442 + 443 + return ops; 485 444 } 486 445 487 446 static int arch__key_cmp(const void *name, const void *archp)