diff options
author | Ingo Molnar <mingo@kernel.org> | 2018-03-25 10:38:15 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-03-25 10:38:15 +0200 |
commit | a0ac7b3ca941fbbf96b48df7de6542d18d8d92f3 (patch) | |
tree | 2185281981513d704dcde213b4225848ae7a8b0f /tools/perf/util/annotate.h | |
parent | 7054e4e0b165ba74562adef96a6b1c53fb9600a4 (diff) | |
parent | 980b68ec0694f250e967cb18c5705ef5de10fdd5 (diff) |
Merge tag 'perf-core-for-mingo-4.17-20180323' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
- Move non-TUI specific annotation routines out of the TUI browser so
that it can be used in other UIs, and to demonstrate that introduce
a 'perf annotate --stdio2' option that will apply those formatting
routines to provide a non-interactive annotation mode (Arnaldo Carvalho de Melo)
- Add 'P' hotkey to the annotation TUI, so dump the current annotated
symbol to a file, easing report thru e-mail, by getting rid of the
spaces + right hand side scrollbar chars (Arnaldo Carvalho de Melo)
- Support --ignore-vmlinux to 'perf report' and 'perf annotate', that
was already present in 'perf top', to use /proc/{kcore,kallsyms},
allowing to see what is in fact running (patched stuff, alternatives,
ftrace, etc), not the initial state of the kernel (vmlinux) (Arnaldo Carvalho de Melo)
- Support 'jump' instructions to a different function, treating them
as 'call' instructions (Arnaldo Carvalho de Melo)
- Fix some jump artifacts when using vmlinux + ASM functions, where
the ELF symtab for instance, for entry_SYSCALL_64 includes that and
what comes after the 'syscall_return_via_sysret' label, but the
objdump -dS prints the jump targets + offsets using the
syscall_return_via_sysret address, which was confusing 'perf annotate'.
See the cset comments for further info (Arnaldo Carvalho de Melo)
- Report error from dwfl_attach_state() in the unwind code (Martin Vuille)
- Reference Py_None before returning it in the python extension (Petr Machata)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/util/annotate.h')
-rw-r--r-- | tools/perf/util/annotate.h | 102 |
1 files changed, 99 insertions, 3 deletions
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 7e914e834101..ff7e3df31efa 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -28,6 +28,7 @@ struct ins_operands { u64 addr; s64 offset; bool offset_avail; + bool outside; } target; union { struct { @@ -46,7 +47,7 @@ struct arch; struct ins_ops { void (*free)(struct ins_operands *ops); - int (*parse)(struct arch *arch, struct ins_operands *ops, struct map *map); + int (*parse)(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms); int (*scnprintf)(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); }; @@ -58,6 +59,21 @@ bool ins__is_lock(const struct ins *ins); int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); +#define ANNOTATION__IPC_WIDTH 6 +#define ANNOTATION__CYCLES_WIDTH 6 + +struct annotation_options { + bool hide_src_code, + use_offset, + jump_arrows, + show_linenr, + show_nr_jumps, + show_nr_samples, + show_total_period; +}; + +extern struct annotation_options annotation__default_options; + struct annotation; struct sym_hist_entry { @@ -77,10 +93,13 @@ struct annotation_line { s64 offset; char *line; int line_nr; + int jump_sources; float ipc; u64 cycles; size_t privsize; char *path; + u32 idx; + int idx_asm; int samples_nr; struct annotation_data samples[0]; }; @@ -98,14 +117,40 @@ static inline struct disasm_line *disasm_line(struct annotation_line *al) return al ? container_of(al, struct disasm_line, al) : NULL; } -static inline bool disasm_line__has_offset(const struct disasm_line *dl) +/* + * Is this offset in the same function as the line it is used? + * asm functions jump to other functions, for instance. + */ +static inline bool disasm_line__has_local_offset(const struct disasm_line *dl) { - return dl->ops.target.offset_avail; + return dl->ops.target.offset_avail && !dl->ops.target.outside; } +/* + * Can we draw an arrow from the jump to its target, for instance? I.e. + * is the jump and its target in the same function? + */ +bool disasm_line__is_valid_local_jump(struct disasm_line *dl, struct symbol *sym); + void disasm_line__free(struct disasm_line *dl); struct annotation_line * annotation_line__next(struct annotation_line *pos, struct list_head *head); + +struct annotation_write_ops { + bool first_line, current_entry, change_color; + int width; + void *obj; + int (*set_color)(void *obj, int color); + void (*set_percent_color)(void *obj, double percent, bool current); + int (*set_jumps_percent_color)(void *obj, int nr, bool current); + void (*printf)(void *obj, const char *fmt, ...); + void (*write_graph)(void *obj, int graph); +}; + +double annotation_line__max_percent(struct annotation_line *al, struct annotation *notes); +void annotation_line__write(struct annotation_line *al, struct annotation *notes, + struct annotation_write_ops *ops); + int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw); size_t disasm__fprintf(struct list_head *head, FILE *fp); void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel); @@ -151,9 +196,47 @@ struct annotated_source { struct annotation { pthread_mutex_t lock; u64 max_coverage; + u64 start; + struct annotation_options *options; + struct annotation_line **offsets; + int nr_events; + int nr_jumps; + int max_jump_sources; + int nr_entries; + int nr_asm_entries; + u16 max_line_len; + struct { + u8 addr; + u8 jumps; + u8 target; + u8 min_addr; + u8 max_addr; + } widths; + bool have_cycles; struct annotated_source *src; }; +static inline int annotation__cycles_width(struct annotation *notes) +{ + return notes->have_cycles ? ANNOTATION__IPC_WIDTH + ANNOTATION__CYCLES_WIDTH : 0; +} + +static inline int annotation__pcnt_width(struct annotation *notes) +{ + return (notes->options->show_total_period ? 12 : 7) * notes->nr_events; +} + +static inline bool annotation_line__filter(struct annotation_line *al, struct annotation *notes) +{ + return notes->options->hide_src_code && al->offset == -1; +} + +void annotation__set_offsets(struct annotation *notes, s64 size); +void annotation__compute_ipc(struct annotation *notes, size_t size); +void annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym); +void annotation__update_column_widths(struct annotation *notes); +void annotation__init_column_widths(struct annotation *notes, struct symbol *sym); + static inline struct sym_hist *annotation__histogram(struct annotation *notes, int idx) { return (((void *)¬es->src->histograms) + @@ -181,6 +264,10 @@ void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, size_t privsize, struct arch **parch); +int symbol__annotate2(struct symbol *sym, struct map *map, + struct perf_evsel *evsel, + struct annotation_options *options, + struct arch **parch); enum symbol_disassemble_errno { SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, @@ -205,16 +292,23 @@ int symbol__strerror_disassemble(struct symbol *sym, struct map *map, int symbol__annotate_printf(struct symbol *sym, struct map *map, struct perf_evsel *evsel, bool full_paths, int min_pcnt, int max_lines, int context); +int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp); void symbol__annotate_zero_histogram(struct symbol *sym, int evidx); void symbol__annotate_decay_histogram(struct symbol *sym, int evidx); void annotated_source__purge(struct annotated_source *as); +int map_symbol__annotation_dump(struct map_symbol *ms, struct perf_evsel *evsel); + bool ui__has_annotation(void); int symbol__tty_annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, bool print_lines, bool full_paths, int min_pcnt, int max_lines); +int symbol__tty_annotate2(struct symbol *sym, struct map *map, + struct perf_evsel *evsel, bool print_lines, + bool full_paths); + #ifdef HAVE_SLANG_SUPPORT int symbol__tui_annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, @@ -232,4 +326,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, extern const char *disassembler_style; +void annotation_config__init(void); + #endif /* __PERF_ANNOTATE_H */ |