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: default avatarRavi 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.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 47414424
...@@ -213,17 +213,17 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int ...@@ -213,17 +213,17 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
ui_browser__write_nstring(browser, bf, printed); ui_browser__write_nstring(browser, bf, printed);
if (change_color) if (change_color)
ui_browser__set_color(browser, color); ui_browser__set_color(browser, color);
if (dl->ins && dl->ins->ops->scnprintf) { if (dl->ins.ops && dl->ins.ops->scnprintf) {
if (ins__is_jump(dl->ins)) { if (ins__is_jump(&dl->ins)) {
bool fwd = dl->ops.target.offset > (u64)dl->offset; bool fwd = dl->ops.target.offset > (u64)dl->offset;
ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR : ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR :
SLSMG_UARROW_CHAR); SLSMG_UARROW_CHAR);
SLsmg_write_char(' '); SLsmg_write_char(' ');
} else if (ins__is_call(dl->ins)) { } else if (ins__is_call(&dl->ins)) {
ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); ui_browser__write_graph(browser, SLSMG_RARROW_CHAR);
SLsmg_write_char(' '); SLsmg_write_char(' ');
} else if (ins__is_ret(dl->ins)) { } else if (ins__is_ret(&dl->ins)) {
ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); ui_browser__write_graph(browser, SLSMG_LARROW_CHAR);
SLsmg_write_char(' '); SLsmg_write_char(' ');
} else { } else {
...@@ -243,7 +243,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int ...@@ -243,7 +243,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym) static bool disasm_line__is_valid_jump(struct disasm_line *dl, struct symbol *sym)
{ {
if (!dl || !dl->ins || !ins__is_jump(dl->ins) if (!dl || !dl->ins.ops || !ins__is_jump(&dl->ins)
|| !disasm_line__has_offset(dl) || !disasm_line__has_offset(dl)
|| dl->ops.target.offset >= symbol__size(sym)) || dl->ops.target.offset >= symbol__size(sym))
return false; return false;
...@@ -492,7 +492,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, ...@@ -492,7 +492,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
}; };
char title[SYM_TITLE_MAX_SIZE]; char title[SYM_TITLE_MAX_SIZE];
if (!ins__is_call(dl->ins)) if (!ins__is_call(&dl->ins))
return false; return false;
if (map_groups__find_ams(&target) || if (map_groups__find_ams(&target) ||
...@@ -545,7 +545,7 @@ static bool annotate_browser__jump(struct annotate_browser *browser) ...@@ -545,7 +545,7 @@ static bool annotate_browser__jump(struct annotate_browser *browser)
struct disasm_line *dl = browser->selection; struct disasm_line *dl = browser->selection;
s64 idx; s64 idx;
if (!ins__is_jump(dl->ins)) if (!ins__is_jump(&dl->ins))
return false; return false;
dl = annotate_browser__find_offset(browser, dl->ops.target.offset, &idx); dl = annotate_browser__find_offset(browser, dl->ops.target.offset, &idx);
...@@ -841,9 +841,9 @@ static int annotate_browser__run(struct annotate_browser *browser, ...@@ -841,9 +841,9 @@ static int annotate_browser__run(struct annotate_browser *browser,
ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org");
else if (browser->selection->offset == -1) else if (browser->selection->offset == -1)
ui_helpline__puts("Actions are only available for assembly lines."); ui_helpline__puts("Actions are only available for assembly lines.");
else if (!browser->selection->ins) else if (!browser->selection->ins.ops)
goto show_sup_ins; goto show_sup_ins;
else if (ins__is_ret(browser->selection->ins)) else if (ins__is_ret(&browser->selection->ins))
goto out; goto out;
else if (!(annotate_browser__jump(browser) || else if (!(annotate_browser__jump(browser) ||
annotate_browser__callq(browser, evsel, hbt))) { annotate_browser__callq(browser, evsel, hbt))) {
......
...@@ -28,8 +28,8 @@ const char *disassembler_style; ...@@ -28,8 +28,8 @@ const char *disassembler_style;
const char *objdump_path; const char *objdump_path;
static regex_t file_lineno; static regex_t file_lineno;
static struct ins *ins__find(struct arch *arch, const char *name); static struct ins_ops *ins__find(struct arch *arch, const char *name);
static int disasm_line__parse(char *line, char **namep, char **rawp); static int disasm_line__parse(char *line, const char **namep, char **rawp);
struct arch { struct arch {
const char *name; const char *name;
...@@ -218,26 +218,20 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) ...@@ -218,26 +218,20 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map *map) static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map *map)
{ {
char *name;
ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); ops->locked.ops = zalloc(sizeof(*ops->locked.ops));
if (ops->locked.ops == NULL) if (ops->locked.ops == NULL)
return 0; return 0;
if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0) if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops->raw) < 0)
goto out_free_ops; goto out_free_ops;
ops->locked.ins = ins__find(arch, name); ops->locked.ins.ops = ins__find(arch, ops->locked.ins.name);
free(name);
if (ops->locked.ins == NULL) if (ops->locked.ins.ops == NULL)
goto out_free_ops; goto out_free_ops;
if (!ops->locked.ins->ops) if (ops->locked.ins.ops->parse &&
return 0; ops->locked.ins.ops->parse(arch, ops->locked.ops, map) < 0)
if (ops->locked.ins->ops->parse &&
ops->locked.ins->ops->parse(arch, ops->locked.ops, map) < 0)
goto out_free_ops; goto out_free_ops;
return 0; return 0;
...@@ -252,19 +246,19 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size, ...@@ -252,19 +246,19 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
{ {
int printed; int printed;
if (ops->locked.ins == NULL) if (ops->locked.ins.ops == NULL)
return ins__raw_scnprintf(ins, bf, size, ops); return ins__raw_scnprintf(ins, bf, size, ops);
printed = scnprintf(bf, size, "%-6.6s ", ins->name); printed = scnprintf(bf, size, "%-6.6s ", ins->name);
return printed + ins__scnprintf(ops->locked.ins, bf + printed, return printed + ins__scnprintf(&ops->locked.ins, bf + printed,
size - printed, ops->locked.ops); size - printed, ops->locked.ops);
} }
static void lock__delete(struct ins_operands *ops) static void lock__delete(struct ins_operands *ops)
{ {
struct ins *ins = ops->locked.ins; struct ins *ins = &ops->locked.ins;
if (ins && ins->ops->free) if (ins->ops && ins->ops->free)
ins->ops->free(ops->locked.ops); ins->ops->free(ops->locked.ops);
else else
ins__delete(ops->locked.ops); ins__delete(ops->locked.ops);
...@@ -425,8 +419,9 @@ static void ins__sort(struct arch *arch) ...@@ -425,8 +419,9 @@ static void ins__sort(struct arch *arch)
qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp);
} }
static struct ins *ins__find(struct arch *arch, const char *name) static struct ins_ops *ins__find(struct arch *arch, const char *name)
{ {
struct ins *ins;
const int nmemb = arch->nr_instructions; const int nmemb = arch->nr_instructions;
if (!arch->sorted_instructions) { if (!arch->sorted_instructions) {
...@@ -434,7 +429,8 @@ static struct ins *ins__find(struct arch *arch, const char *name) ...@@ -434,7 +429,8 @@ static struct ins *ins__find(struct arch *arch, const char *name)
arch->sorted_instructions = true; arch->sorted_instructions = true;
} }
return bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp);
return ins ? ins->ops : NULL;
} }
static int arch__key_cmp(const void *name, const void *archp) static 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,19 +687,16 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip)
static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map)
{ {
dl->ins = ins__find(arch, dl->name); dl->ins.ops = ins__find(arch, dl->ins.name);
if (dl->ins == NULL)
return;
if (!dl->ins->ops) if (!dl->ins.ops)
return; return;
if (dl->ins->ops->parse && dl->ins->ops->parse(arch, &dl->ops, map) < 0) if (dl->ins.ops->parse && dl->ins.ops->parse(arch, &dl->ops, map) < 0)
dl->ins = NULL; dl->ins.ops = NULL;
} }
static int disasm_line__parse(char *line, char **namep, char **rawp) static int disasm_line__parse(char *line, const char **namep, char **rawp)
{ {
char *name = line, tmp; char *name = line, tmp;
...@@ -736,7 +729,8 @@ static int disasm_line__parse(char *line, char **namep, char **rawp) ...@@ -736,7 +729,8 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
return 0; return 0;
out_free_name: out_free_name:
zfree(namep); free((void *)namep);
*namep = NULL;
return -1; return -1;
} }
...@@ -755,7 +749,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, ...@@ -755,7 +749,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line,
goto out_delete; goto out_delete;
if (offset != -1) { if (offset != -1) {
if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0) if (disasm_line__parse(dl->line, &dl->ins.name, &dl->ops.raw) < 0)
goto out_free_line; goto out_free_line;
disasm_line__init_ins(dl, arch, map); disasm_line__init_ins(dl, arch, map);
...@@ -774,20 +768,21 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, ...@@ -774,20 +768,21 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line,
void disasm_line__free(struct disasm_line *dl) void disasm_line__free(struct disasm_line *dl)
{ {
zfree(&dl->line); zfree(&dl->line);
zfree(&dl->name); if (dl->ins.ops && dl->ins.ops->free)
if (dl->ins && dl->ins->ops->free) dl->ins.ops->free(&dl->ops);
dl->ins->ops->free(&dl->ops);
else else
ins__delete(&dl->ops); ins__delete(&dl->ops);
free((void *)dl->ins.name);
dl->ins.name = NULL;
free(dl); free(dl);
} }
int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw) int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw)
{ {
if (raw || !dl->ins) if (raw || !dl->ins.ops)
return scnprintf(bf, size, "%-6.6s %s", dl->name, dl->ops.raw); return scnprintf(bf, size, "%-6.6s %s", dl->ins.name, dl->ops.raw);
return ins__scnprintf(dl->ins, bf, size, &dl->ops); return ins__scnprintf(&dl->ins, bf, size, &dl->ops);
} }
static void disasm__add(struct list_head *head, struct disasm_line *line) static 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,7 +1138,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
map__rip_2objdump(map, sym->start); map__rip_2objdump(map, sym->start);
/* kcore has no symbols, so add the call target name */ /* kcore has no symbols, so add the call target name */
if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) { if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.name) {
struct addr_map_symbol target = { struct addr_map_symbol target = {
.map = map, .map = map,
.addr = dl->ops.target.addr, .addr = dl->ops.target.addr,
...@@ -1173,8 +1168,8 @@ static void delete_last_nop(struct symbol *sym) ...@@ -1173,8 +1168,8 @@ static void delete_last_nop(struct symbol *sym)
while (!list_empty(list)) { while (!list_empty(list)) {
dl = list_entry(list->prev, struct disasm_line, node); dl = list_entry(list->prev, struct disasm_line, node);
if (dl->ins && dl->ins->ops) { if (dl->ins.ops) {
if (dl->ins->ops != &nop_ops) if (dl->ins.ops != &nop_ops)
return; return;
} else { } else {
if (!strstr(dl->line, " nop ") && if (!strstr(dl->line, " nop ") &&
...@@ -1767,7 +1762,7 @@ static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp) ...@@ -1767,7 +1762,7 @@ static size_t disasm_line__fprintf(struct disasm_line *dl, FILE *fp)
if (dl->offset == -1) if (dl->offset == -1)
return fprintf(fp, "%s\n", dl->line); return fprintf(fp, "%s\n", dl->line);
printed = fprintf(fp, "%#" PRIx64 " %s", dl->offset, dl->name); printed = fprintf(fp, "%#" PRIx64 " %s", dl->offset, dl->ins.name);
if (dl->ops.raw[0] != '\0') { if (dl->ops.raw[0] != '\0') {
printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ", printed += fprintf(fp, "%.*s %s\n", 6 - (int)printed, " ",
......
...@@ -11,7 +11,12 @@ ...@@ -11,7 +11,12 @@
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <pthread.h> #include <pthread.h>
struct ins; struct ins_ops;
struct ins {
const char *name;
struct ins_ops *ops;
};
struct ins_operands { struct ins_operands {
char *raw; char *raw;
...@@ -28,7 +33,7 @@ struct ins_operands { ...@@ -28,7 +33,7 @@ struct ins_operands {
u64 addr; u64 addr;
} source; } source;
struct { struct {
struct ins *ins; struct ins ins;
struct ins_operands *ops; struct ins_operands *ops;
} locked; } locked;
}; };
...@@ -43,11 +48,6 @@ struct ins_ops { ...@@ -43,11 +48,6 @@ struct ins_ops {
struct ins_operands *ops); struct ins_operands *ops);
}; };
struct ins {
const char *name;
struct ins_ops *ops;
};
bool ins__is_jump(const struct ins *ins); bool ins__is_jump(const struct ins *ins);
bool ins__is_call(const struct ins *ins); bool ins__is_call(const struct ins *ins);
bool ins__is_ret(const struct ins *ins); bool ins__is_ret(const struct ins *ins);
...@@ -59,8 +59,7 @@ struct disasm_line { ...@@ -59,8 +59,7 @@ struct disasm_line {
struct list_head node; struct list_head node;
s64 offset; s64 offset;
char *line; char *line;
char *name; struct ins ins;
struct ins *ins;
int line_nr; int line_nr;
float ipc; float ipc;
u64 cycles; u64 cycles;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment