Commit 353dcaa2 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo

perf annotate: Avoid reallocation in objdump parsing

Objdump output is parsed using getline which allocates memory for the
read. Getline will realloc if the memory is too small, but currently the
line is always freed after the call.

Simplify parse_objdump_line by performing the reading in symbol__disassemble.
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jin Yao <yao.jin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <songliubraving@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: clang-built-linux@googlegroups.com
Link: http://lore.kernel.org/lkml/20191010183649.23768-2-irogers@google.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 800d3f56
...@@ -1489,24 +1489,17 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start ...@@ -1489,24 +1489,17 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start
* means that it's not a disassembly line so should be treated differently. * means that it's not a disassembly line so should be treated differently.
* The ops.raw part will be parsed further according to type of the instruction. * The ops.raw part will be parsed further according to type of the instruction.
*/ */
static int symbol__parse_objdump_line(struct symbol *sym, FILE *file, static int symbol__parse_objdump_line(struct symbol *sym,
struct annotate_args *args, struct annotate_args *args,
int *line_nr) char *line, int *line_nr)
{ {
struct map *map = args->ms.map; struct map *map = args->ms.map;
struct annotation *notes = symbol__annotation(sym); struct annotation *notes = symbol__annotation(sym);
struct disasm_line *dl; struct disasm_line *dl;
char *line = NULL, *parsed_line, *tmp, *tmp2; char *parsed_line, *tmp, *tmp2;
size_t line_len;
s64 line_ip, offset = -1; s64 line_ip, offset = -1;
regmatch_t match[2]; regmatch_t match[2];
if (getline(&line, &line_len, file) < 0)
return -1;
if (!line)
return -1;
line_ip = -1; line_ip = -1;
parsed_line = strim(line); parsed_line = strim(line);
...@@ -1543,7 +1536,6 @@ static int symbol__parse_objdump_line(struct symbol *sym, FILE *file, ...@@ -1543,7 +1536,6 @@ static int symbol__parse_objdump_line(struct symbol *sym, FILE *file,
args->ms.sym = sym; args->ms.sym = sym;
dl = disasm_line__new(args); dl = disasm_line__new(args);
free(line);
(*line_nr)++; (*line_nr)++;
if (dl == NULL) if (dl == NULL)
...@@ -1876,6 +1868,8 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) ...@@ -1876,6 +1868,8 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
int lineno = 0; int lineno = 0;
int nline; int nline;
pid_t pid; pid_t pid;
char *line;
size_t line_len;
int err = dso__disassemble_filename(dso, symfs_filename, sizeof(symfs_filename)); int err = dso__disassemble_filename(dso, symfs_filename, sizeof(symfs_filename));
if (err) if (err)
...@@ -1964,18 +1958,26 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args) ...@@ -1964,18 +1958,26 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
goto out_free_command; goto out_free_command;
} }
/* Storage for getline. */
line = NULL;
line_len = 0;
nline = 0; nline = 0;
while (!feof(file)) { while (!feof(file)) {
if (getline(&line, &line_len, file) < 0 || !line)
break;
/* /*
* The source code line number (lineno) needs to be kept in * The source code line number (lineno) needs to be kept in
* across calls to symbol__parse_objdump_line(), so that it * across calls to symbol__parse_objdump_line(), so that it
* can associate it with the instructions till the next one. * can associate it with the instructions till the next one.
* See disasm_line__new() and struct disasm_line::line_nr. * See disasm_line__new() and struct disasm_line::line_nr.
*/ */
if (symbol__parse_objdump_line(sym, file, args, &lineno) < 0) if (symbol__parse_objdump_line(sym, args, line, &lineno) < 0)
break; break;
nline++; nline++;
} }
free(line);
if (nline == 0) if (nline == 0)
pr_err("No output from %s\n", command); pr_err("No output from %s\n", command);
......
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