lkml.org 
[lkml]   [2012]   [May]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4/8] perf annotate: Augment lock instruction output
    Date
    From: Arnaldo Carvalho de Melo <acme@redhat.com>

    It just chops off the 'lock' and uses the ins__find, etc machinery to
    call instruction specific parsers/beautifiers.

    Cc: David Ahern <dsahern@gmail.com>
    Cc: Frederic Weisbecker <fweisbec@gmail.com>
    Cc: Mike Galbraith <efault@gmx.de>
    Cc: Namhyung Kim <namhyung@gmail.com>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Stephane Eranian <eranian@google.com>
    Link: http://lkml.kernel.org/n/tip-4913ba2dzakz5rivgumosqbh@git.kernel.org
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    ---
    tools/perf/util/annotate.c | 127 ++++++++++++++++++++++++++++++++++----------
    tools/perf/util/annotate.h | 16 ++++--
    2 files changed, 109 insertions(+), 34 deletions(-)

    diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
    index a6109dc..1dce098 100644
    --- a/tools/perf/util/annotate.c
    +++ b/tools/perf/util/annotate.c
    @@ -18,6 +18,9 @@

    const char *disassembler_style;

    +static struct ins *ins__find(const char *name);
    +static int disasm_line__parse(char *line, char **namep, char **rawp);
    +
    static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size,
    struct ins_operands *ops)
    {
    @@ -147,6 +150,53 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
    return 0;
    }

    +static int lock__parse(struct ins_operands *ops)
    +{
    + char *name;
    +
    + ops->locked.ops = zalloc(sizeof(*ops->locked.ops));
    + if (ops->locked.ops == NULL)
    + return 0;
    +
    + if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0)
    + goto out_free_ops;
    +
    + ops->locked.ins = ins__find(name);
    + if (ops->locked.ins == NULL)
    + goto out_free_ops;
    +
    + if (!ops->locked.ins->ops)
    + return 0;
    +
    + if (ops->locked.ins->ops->parse)
    + ops->locked.ins->ops->parse(ops->locked.ops);
    +
    + return 0;
    +
    +out_free_ops:
    + free(ops->locked.ops);
    + ops->locked.ops = NULL;
    + return 0;
    +}
    +
    +static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
    + struct ins_operands *ops)
    +{
    + int printed;
    +
    + if (ops->locked.ins == NULL)
    + return ins__raw_scnprintf(ins, bf, size, ops);
    +
    + printed = scnprintf(bf, size, "%-6.6s ", ins->name);
    + return printed + ins__scnprintf(ops->locked.ins, bf + printed,
    + size - printed, ops->locked.ops);
    +}
    +
    +static struct ins_ops lock_ops = {
    + .parse = lock__parse,
    + .scnprintf = lock__scnprintf,
    +};
    +
    static int mov__parse(struct ins_operands *ops)
    {
    char *s = strchr(ops->raw, ','), *target, *comment, prev;
    @@ -265,6 +315,7 @@ static struct ins instructions[] = {
    { .name = "addq", .ops = &mov_ops, },
    { .name = "addw", .ops = &mov_ops, },
    { .name = "and", .ops = &mov_ops, },
    + { .name = "bts", .ops = &mov_ops, },
    { .name = "call", .ops = &call_ops, },
    { .name = "callq", .ops = &call_ops, },
    { .name = "cmp", .ops = &mov_ops, },
    @@ -314,6 +365,7 @@ static struct ins instructions[] = {
    { .name = "js", .ops = &jump_ops, },
    { .name = "jz", .ops = &jump_ops, },
    { .name = "lea", .ops = &mov_ops, },
    + { .name = "lock", .ops = &lock_ops, },
    { .name = "mov", .ops = &mov_ops, },
    { .name = "movb", .ops = &mov_ops, },
    { .name = "movdqa",.ops = &mov_ops, },
    @@ -330,6 +382,7 @@ static struct ins instructions[] = {
    { .name = "test", .ops = &mov_ops, },
    { .name = "testb", .ops = &mov_ops, },
    { .name = "testl", .ops = &mov_ops, },
    + { .name = "xadd", .ops = &mov_ops, },
    };

    static int ins__cmp(const void *name, const void *insp)
    @@ -420,6 +473,44 @@ static void disasm_line__init_ins(struct disasm_line *dl)
    dl->ins->ops->parse(&dl->ops);
    }

    +static int disasm_line__parse(char *line, char **namep, char **rawp)
    +{
    + char *name = line, tmp;
    +
    + while (isspace(name[0]))
    + ++name;
    +
    + if (name[0] == '\0')
    + return -1;
    +
    + *rawp = name + 1;
    +
    + while ((*rawp)[0] != '\0' && !isspace((*rawp)[0]))
    + ++*rawp;
    +
    + tmp = (*rawp)[0];
    + (*rawp)[0] = '\0';
    + *namep = strdup(name);
    +
    + if (*namep == NULL)
    + goto out_free_name;
    +
    + (*rawp)[0] = tmp;
    +
    + if ((*rawp)[0] != '\0') {
    + (*rawp)++;
    + while (isspace((*rawp)[0]))
    + ++(*rawp);
    + }
    +
    + return 0;
    +
    +out_free_name:
    + free(*namep);
    + *namep = NULL;
    + return -1;
    +}
    +
    static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privsize)
    {
    struct disasm_line *dl = zalloc(sizeof(*dl) + privsize);
    @@ -431,35 +522,9 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privs
    goto out_delete;

    if (offset != -1) {
    - char *name = dl->line, tmp;
    -
    - while (isspace(name[0]))
    - ++name;
    -
    - if (name[0] == '\0')
    - goto out_delete;
    -
    - dl->ops.raw = name + 1;
    -
    - while (dl->ops.raw[0] != '\0' &&
    - !isspace(dl->ops.raw[0]))
    - ++dl->ops.raw;
    -
    - tmp = dl->ops.raw[0];
    - dl->ops.raw[0] = '\0';
    - dl->name = strdup(name);
    -
    - if (dl->name == NULL)
    + if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0)
    goto out_free_line;

    - dl->ops.raw[0] = tmp;
    -
    - if (dl->ops.raw[0] != '\0') {
    - dl->ops.raw++;
    - while (isspace(dl->ops.raw[0]))
    - ++dl->ops.raw;
    - }
    -
    disasm_line__init_ins(dl);
    }
    }
    @@ -477,8 +542,12 @@ void disasm_line__free(struct disasm_line *dl)
    {
    free(dl->line);
    free(dl->name);
    - free(dl->ops.source.raw);
    - free(dl->ops.source.name);
    + if (dl->ins && dl->ins->ops == &lock_ops) {
    + free(dl->ops.locked.ops);
    + } else {
    + free(dl->ops.source.raw);
    + free(dl->ops.source.name);
    + }
    free(dl->ops.target.raw);
    free(dl->ops.target.name);
    free(dl);
    diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
    index 066d31d..b79d326 100644
    --- a/tools/perf/util/annotate.h
    +++ b/tools/perf/util/annotate.h
    @@ -18,11 +18,17 @@ struct ins_operands {
    u64 addr;
    u64 offset;
    } target;
    - struct {
    - char *raw;
    - char *name;
    - u64 addr;
    - } source;
    + union {
    + struct {
    + char *raw;
    + char *name;
    + u64 addr;
    + } source;
    + struct {
    + struct ins *ins;
    + struct ins_operands *ops;
    + } locked;
    + };
    };

    struct ins_ops {
    --
    1.7.9.2.358.g22243


    \
     
     \ /
      Last update: 2012-05-12 22:41    [W:0.035 / U:154.260 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site