summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/ui/browsers/annotate.c4
-rw-r--r--tools/perf/util/annotate.c63
-rw-r--r--tools/perf/util/annotate.h10
3 files changed, 68 insertions, 9 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index cfde5a2ca3f4..7ca5ae625cc9 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -76,7 +76,9 @@ struct annotate_browser {
static inline struct browser_disasm_line *disasm_line__browser(struct disasm_line *dl)
{
- return (struct browser_disasm_line *)(dl + 1);
+ struct annotation_line *al = &dl->al;
+
+ return (void *) al - al->privsize;
}
static bool disasm_line__filter(struct ui_browser *browser __maybe_unused,
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 11c7743203a0..7c74700ae6d7 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -888,14 +888,64 @@ struct annotate_args {
int line_nr;
};
+static void annotation_line__delete(struct annotation_line *al)
+{
+ void *ptr = (void *) al - al->privsize;
+
+ zfree(&al->line);
+ free(ptr);
+}
+
+/*
+ * Allocating the annotation line data with following
+ * structure:
+ *
+ * --------------------------------------
+ * private space | struct annotation_line
+ * --------------------------------------
+ *
+ * Size of the private space is stored in 'struct annotation_line'.
+ *
+ */
+static struct annotation_line *
+annotation_line__new(struct annotate_args *args, size_t privsize)
+{
+ struct annotation_line *al;
+ size_t size = privsize + sizeof(*al);
+
+ al = zalloc(size);
+ if (al) {
+ al = (void *) al + privsize;
+ al->privsize = privsize;
+ al->offset = args->offset;
+ al->line = strdup(args->line);
+ al->line_nr = args->line_nr;
+ }
+
+ return al;
+}
+
+/*
+ * Allocating the disasm annotation line data with
+ * following structure:
+ *
+ * ------------------------------------------------------------
+ * privsize space | struct disasm_line | struct annotation_line
+ * ------------------------------------------------------------
+ *
+ * We have 'struct annotation_line' member as last member
+ * of 'struct disasm_line' to have an easy access.
+ *
+ */
static struct disasm_line *disasm_line__new(struct annotate_args *args)
{
- struct disasm_line *dl = zalloc(sizeof(*dl) + args->privsize);
+ struct disasm_line *dl = NULL;
+ struct annotation_line *al;
+ size_t privsize = args->privsize + offsetof(struct disasm_line, al);
- if (dl != NULL) {
- dl->al.offset = args->offset;
- dl->al.line = strdup(args->line);
- dl->al.line_nr = args->line_nr;
+ al = annotation_line__new(args, privsize);
+ if (al != NULL) {
+ dl = disasm_line(al);
if (dl->al.line == NULL)
goto out_delete;
@@ -919,14 +969,13 @@ out_delete:
void disasm_line__free(struct disasm_line *dl)
{
- zfree(&dl->al.line);
if (dl->ins.ops && dl->ins.ops->free)
dl->ins.ops->free(&dl->ops);
else
ins__delete(&dl->ops);
free((void *)dl->ins.name);
dl->ins.name = NULL;
- free(dl);
+ annotation_line__delete(&dl->al);
}
int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw)
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 6f01e6117936..2e7a08afb04f 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -67,14 +67,22 @@ struct annotation_line {
int line_nr;
float ipc;
u64 cycles;
+ size_t privsize;
};
struct disasm_line {
- struct annotation_line al;
struct ins ins;
struct ins_operands ops;
+
+ /* This needs to be at the end. */
+ struct annotation_line al;
};
+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)
{
return dl->ops.target.offset_avail;