All of lore.kernel.org
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: Arnaldo Carvalho de Melo <acme@kernel.org>,
	Jiri Olsa <jolsa@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>
Cc: Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Ingo Molnar <mingo@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-perf-users@vger.kernel.org,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Stephane Eranian <eranian@google.com>,
	Masami Hiramatsu <mhiramat@kernel.org>,
	linux-toolchains@vger.kernel.org,
	linux-trace-devel@vger.kernel.org
Subject: [PATCH 17/48] perf annotate-data: Add member field in the data type
Date: Wed, 11 Oct 2023 20:50:40 -0700	[thread overview]
Message-ID: <20231012035111.676789-18-namhyung@kernel.org> (raw)
In-Reply-To: <20231012035111.676789-1-namhyung@kernel.org>

Add child member field if the current type is a composite type like a
struct or union.  The member fields are linked in the children list
and do the same recursively if the child itself is a composite type.
Add 'self' member to the annotated_data_type to handle the members in
the same way.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/annotate-data.c | 106 ++++++++++++++++++++++++++++----
 tools/perf/util/annotate-data.h |  27 ++++++--
 tools/perf/util/sort.c          |   4 +-
 3 files changed, 119 insertions(+), 18 deletions(-)

diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index 3e3a561d73e3..63205506b9fe 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -19,7 +19,10 @@
 
 /* Pseudo data types */
 struct annotated_data_type unknown_type = {
-	.type_name = (char *)"(unknown)",
+	.self = {
+		.type_name = (char *)"(unknown)",
+		.children = LIST_HEAD_INIT(unknown_type.self.children),
+	},
 };
 
 /*
@@ -35,9 +38,9 @@ static int data_type_cmp(const void *_key, const struct rb_node *node)
 
 	type = rb_entry(node, struct annotated_data_type, node);
 
-	if (key->type_size != type->type_size)
-		return key->type_size - type->type_size;
-	return strcmp(key->type_name, type->type_name);
+	if (key->self.size != type->self.size)
+		return key->self.size - type->self.size;
+	return strcmp(key->self.type_name, type->self.type_name);
 }
 
 static bool data_type_less(struct rb_node *node_a, const struct rb_node *node_b)
@@ -47,9 +50,80 @@ static bool data_type_less(struct rb_node *node_a, const struct rb_node *node_b)
 	a = rb_entry(node_a, struct annotated_data_type, node);
 	b = rb_entry(node_b, struct annotated_data_type, node);
 
-	if (a->type_size != b->type_size)
-		return a->type_size < b->type_size;
-	return strcmp(a->type_name, b->type_name) < 0;
+	if (a->self.size != b->self.size)
+		return a->self.size < b->self.size;
+	return strcmp(a->self.type_name, b->self.type_name) < 0;
+}
+
+/* Recursively add new members for struct/union */
+static int __add_member_cb(Dwarf_Die *die, void *arg)
+{
+	struct annotated_member *parent = arg;
+	struct annotated_member *member;
+	Dwarf_Die member_type, die_mem;
+	Dwarf_Word size, loc;
+	Dwarf_Attribute attr;
+	struct strbuf sb;
+	int tag;
+
+	if (dwarf_tag(die) != DW_TAG_member)
+		return DIE_FIND_CB_SIBLING;
+
+	member = zalloc(sizeof(*member));
+	if (member == NULL)
+		return DIE_FIND_CB_END;
+
+	strbuf_init(&sb, 32);
+	die_get_typename(die, &sb);
+
+	die_get_real_type(die, &member_type);
+	if (dwarf_aggregate_size(&member_type, &size) < 0)
+		size = 0;
+
+	if (!dwarf_attr_integrate(die, DW_AT_data_member_location, &attr))
+		loc = 0;
+	else
+		dwarf_formudata(&attr, &loc);
+
+	member->type_name = strbuf_detach(&sb, NULL);
+	/* member->var_name can be NULL */
+	if (dwarf_diename(die))
+		member->var_name = strdup(dwarf_diename(die));
+	member->size = size;
+	member->offset = loc + parent->offset;
+	INIT_LIST_HEAD(&member->children);
+	list_add_tail(&member->node, &parent->children);
+
+	tag = dwarf_tag(&member_type);
+	switch (tag) {
+	case DW_TAG_structure_type:
+	case DW_TAG_union_type:
+		die_find_child(&member_type, __add_member_cb, member, &die_mem);
+		break;
+	default:
+		break;
+	}
+	return DIE_FIND_CB_SIBLING;
+}
+
+static void add_member_types(struct annotated_data_type *parent, Dwarf_Die *type)
+{
+	Dwarf_Die die_mem;
+
+	die_find_child(type, __add_member_cb, &parent->self, &die_mem);
+}
+
+static void delete_members(struct annotated_member *member)
+{
+	struct annotated_member *child, *tmp;
+
+	list_for_each_entry_safe(child, tmp, &member->children, node) {
+		list_del(&child->node);
+		delete_members(child);
+		free(child->type_name);
+		free(child->var_name);
+		free(child);
+	}
 }
 
 static struct annotated_data_type *dso__findnew_data_type(struct dso *dso,
@@ -69,8 +143,8 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso,
 	dwarf_aggregate_size(type_die, &size);
 
 	/* Check existing nodes in dso->data_types tree */
-	key.type_name = type_name;
-	key.type_size = size;
+	key.self.type_name = type_name;
+	key.self.size = size;
 	node = rb_find(&key, &dso->data_types, data_type_cmp);
 	if (node) {
 		result = rb_entry(node, struct annotated_data_type, node);
@@ -85,8 +159,15 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso,
 		return NULL;
 	}
 
-	result->type_name = type_name;
-	result->type_size = size;
+	result->self.type_name = type_name;
+	result->self.size = size;
+	INIT_LIST_HEAD(&result->self.children);
+
+	/*
+	 * Fill member info unconditionally for now,
+	 * later perf annotate would need it.
+	 */
+	add_member_types(result, type_die);
 
 	rb_add(&result->node, &dso->data_types, data_type_less);
 	return result;
@@ -237,7 +318,8 @@ void annotated_data_type__tree_delete(struct rb_root *root)
 
 		rb_erase(node, root);
 		pos = rb_entry(node, struct annotated_data_type, node);
-		free(pos->type_name);
+		delete_members(&pos->self);
+		free(pos->self.type_name);
 		free(pos);
 	}
 }
diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h
index 6efdd7e21b28..33748222e6aa 100644
--- a/tools/perf/util/annotate-data.h
+++ b/tools/perf/util/annotate-data.h
@@ -9,17 +9,36 @@
 
 struct map_symbol;
 
+/**
+ * struct annotated_member - Type of member field
+ * @node: List entry in the parent list
+ * @children: List head for child nodes
+ * @type_name: Name of the member type
+ * @var_name: Name of the member variable
+ * @offset: Offset from the outer data type
+ * @size: Size of the member field
+ *
+ * This represents a member type in a data type.
+ */
+struct annotated_member {
+	struct list_head node;
+	struct list_head children;
+	char *type_name;
+	char *var_name;
+	int offset;
+	int size;
+};
+
 /**
  * struct annotated_data_type - Data type to profile
- * @type_name: Name of the data type
- * @type_size: Size of the data type
+ * @node: RB-tree node for dso->type_tree
+ * @self: Actual type information
  *
  * This represents a data type accessed by samples in the profile data.
  */
 struct annotated_data_type {
 	struct rb_node node;
-	char *type_name;
-	int type_size;
+	struct annotated_member self;
 };
 
 extern struct annotated_data_type unknown_type;
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index c79564c1d5df..01300831333e 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2166,7 +2166,7 @@ sort__type_collapse(struct hist_entry *left, struct hist_entry *right)
 		right_type = right->mem_type;
 	}
 
-	return strcmp(left_type->type_name, right_type->type_name);
+	return strcmp(left_type->self.type_name, right_type->self.type_name);
 }
 
 static int64_t
@@ -2178,7 +2178,7 @@ sort__type_sort(struct hist_entry *left, struct hist_entry *right)
 static int hist_entry__type_snprintf(struct hist_entry *he, char *bf,
 				     size_t size, unsigned int width)
 {
-	return repsep_snprintf(bf, size, "%-*s", width, he->mem_type->type_name);
+	return repsep_snprintf(bf, size, "%-*s", width, he->mem_type->self.type_name);
 }
 
 struct sort_entry sort_type = {
-- 
2.42.0.655.g421f12c284-goog


  parent reply	other threads:[~2023-10-12  3:53 UTC|newest]

Thread overview: 96+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-12  3:50 [RFC 00/48] perf tools: Introduce data type profiling (v1) Namhyung Kim
2023-10-12  3:50 ` [PATCH 01/48] perf annotate: Move raw_comment and raw_func_start Namhyung Kim
2023-10-12  3:50 ` [PATCH 02/48] perf annotate: Check if operand has multiple regs Namhyung Kim
2023-11-27 19:05   ` Arnaldo Carvalho de Melo
2023-10-12  3:50 ` [PATCH 03/48] perf tools: Add util/debuginfo.[ch] files Namhyung Kim
2023-10-12  3:50 ` [PATCH 04/48] perf dwarf-aux: Fix die_get_typename() for void * Namhyung Kim
2023-11-04 10:52   ` Masami Hiramatsu
2023-10-12  3:50 ` [PATCH 05/48] perf dwarf-aux: Move #ifdef code to the header file Namhyung Kim
2023-11-04 10:59   ` Masami Hiramatsu
2023-10-12  3:50 ` [PATCH 06/48] perf dwarf-aux: Add die_get_scopes() helper Namhyung Kim
2023-11-05  9:50   ` Masami Hiramatsu
2023-10-12  3:50 ` [PATCH 07/48] perf dwarf-aux: Add die_find_variable_by_reg() helper Namhyung Kim
2023-11-05  9:48   ` Masami Hiramatsu
2023-10-12  3:50 ` [PATCH 08/48] perf dwarf-aux: Factor out __die_get_typename() Namhyung Kim
2023-11-05  9:07   ` Masami Hiramatsu
2023-11-06  4:01     ` Namhyung Kim
2023-10-12  3:50 ` [PATCH 09/48] perf dwarf-regs: Add get_dwarf_regnum() Namhyung Kim
2023-11-05  8:36   ` Masami Hiramatsu
2023-11-06  4:12     ` Namhyung Kim
2023-10-12  3:50 ` [PATCH 10/48] perf annotate-data: Add find_data_type() Namhyung Kim
2023-10-12  3:50 ` [PATCH 11/48] perf annotate-data: Add dso->data_types tree Namhyung Kim
2023-10-12  3:50 ` [PATCH 12/48] perf annotate: Factor out evsel__get_arch() Namhyung Kim
2023-10-12  3:50 ` [PATCH 13/48] perf annotate: Add annotate_get_insn_location() Namhyung Kim
2023-10-23 16:38   ` Arnaldo Carvalho de Melo
2023-10-24 19:10     ` Namhyung Kim
2023-10-26  5:26       ` Namhyung Kim
2023-10-26 19:37         ` Arnaldo Carvalho de Melo
2023-10-12  3:50 ` [PATCH 14/48] perf annotate: Implement hist_entry__get_data_type() Namhyung Kim
2023-10-12  3:50 ` [PATCH 15/48] perf report: Add 'type' sort key Namhyung Kim
2023-10-23 16:53   ` Arnaldo Carvalho de Melo
2023-10-24 19:11     ` Namhyung Kim
2023-10-12  3:50 ` [PATCH 16/48] perf report: Support data type profiling Namhyung Kim
2023-10-12  3:50 ` Namhyung Kim [this message]
2023-10-12  3:50 ` [PATCH 18/48] perf annotate-data: Update sample histogram for type Namhyung Kim
2023-10-12  3:50 ` [PATCH 19/48] perf report: Add 'typeoff' sort key Namhyung Kim
2023-10-12  3:50 ` [PATCH 20/48] perf report: Add 'symoff' " Namhyung Kim
2023-10-12  3:50 ` [PATCH 21/48] perf annotate: Add --data-type option Namhyung Kim
2023-10-12  3:50 ` [PATCH 22/48] perf annotate: Add --type-stat option for debugging Namhyung Kim
2023-10-23 17:28   ` Arnaldo Carvalho de Melo
2023-10-23 17:40     ` Arnaldo Carvalho de Melo
2023-10-24 19:12       ` Namhyung Kim
2023-10-12  3:50 ` [PATCH 23/48] perf annotate: Add --insn-stat " Namhyung Kim
2023-10-12  3:50 ` [PATCH 24/48] perf annotate-data: Parse 'lock' prefix from llvm-objdump Namhyung Kim
2023-10-12  3:50 ` [PATCH 25/48] perf annotate-data: Handle macro fusion on x86 Namhyung Kim
2023-10-12  3:50 ` [PATCH 26/48] perf annotate-data: Handle array style accesses Namhyung Kim
2023-10-12  3:50 ` [PATCH 27/48] perf annotate-data: Add stack operation pseudo type Namhyung Kim
2023-10-12  3:50 ` [PATCH 28/48] perf dwarf-aux: Add die_find_variable_by_addr() Namhyung Kim
2023-11-06 15:25   ` Masami Hiramatsu
2023-11-09  5:36     ` Namhyung Kim
2023-10-12  3:50 ` [PATCH 29/48] perf annotate-data: Handle PC-relative addressing Namhyung Kim
2023-10-12  3:50 ` [PATCH 30/48] perf annotate-data: Support global variables Namhyung Kim
2023-10-12  3:50 ` [PATCH 31/48] perf dwarf-aux: Add die_get_cfa() Namhyung Kim
2023-11-07  0:50   ` Masami Hiramatsu
2023-11-08  5:28     ` Namhyung Kim
2023-10-12  3:50 ` [PATCH 32/48] perf annotate-data: Support stack variables Namhyung Kim
2023-10-12  3:50 ` [PATCH 33/48] perf dwarf-aux: Check allowed DWARF Ops Namhyung Kim
2023-11-07  9:32   ` Masami Hiramatsu
2023-11-08  5:34     ` Namhyung Kim
2023-10-12  3:50 ` [PATCH 34/48] perf dwarf-aux: Add die_collect_vars() Namhyung Kim
2023-11-08 10:52   ` Masami Hiramatsu
2023-11-09  5:05     ` Namhyung Kim
2023-10-12  3:50 ` [PATCH 35/48] perf dwarf-aux: Handle type transfer for memory access Namhyung Kim
2023-11-08 10:57   ` Masami Hiramatsu
2023-10-12  3:50 ` [PATCH 36/48] perf annotate-data: Introduce struct data_loc_info Namhyung Kim
2023-12-03 16:22   ` Athira Rajeev
2023-12-05  0:10     ` Namhyung Kim
2023-12-05  7:17       ` Athira Rajeev
2023-10-12  3:51 ` [PATCH 37/48] perf map: Add map__objdump_2rip() Namhyung Kim
2023-10-12  3:51 ` [PATCH 38/48] perf annotate: Add annotate_get_basic_blocks() Namhyung Kim
2023-10-12  3:51 ` [PATCH 39/48] perf annotate-data: Maintain variable type info Namhyung Kim
2023-10-12  3:51 ` [PATCH 40/48] perf annotate-data: Add update_insn_state() Namhyung Kim
2023-10-12  3:51 ` [PATCH 41/48] perf annotate-data: Handle global variable access Namhyung Kim
2023-10-12  3:51 ` [PATCH 42/48] perf annotate-data: Handle call instructions Namhyung Kim
2023-10-12  3:51 ` [PATCH 43/48] perf annotate-data: Implement instruction tracking Namhyung Kim
2023-10-12  3:51 ` [PATCH 44/48] perf annotate: Parse x86 segment register location Namhyung Kim
2023-10-12  3:51 ` [PATCH 45/48] perf annotate-data: Handle this-cpu variables in kernel Namhyung Kim
2023-10-12  3:51 ` [PATCH 46/48] perf annotate-data: Track instructions with a this-cpu variable Namhyung Kim
2023-10-12  3:51 ` [PATCH 47/48] perf annotate-data: Add stack canary type Namhyung Kim
2023-10-12  3:51 ` [PATCH 48/48] perf annotate-data: Add debug message Namhyung Kim
2023-10-12  6:03 ` [RFC 00/48] perf tools: Introduce data type profiling (v1) Ingo Molnar
2023-10-12 16:19   ` Namhyung Kim
2023-10-12 18:33     ` Ingo Molnar
2023-10-12 20:45       ` Namhyung Kim
2023-10-12  9:11 ` Peter Zijlstra
2023-10-12 16:41   ` Namhyung Kim
     [not found]     ` <CADzB+2mu98v9EUsA1Y-wVDSrXT2kznKi87Tb6QdN5y4mMFNsyg@mail.gmail.com>
2023-10-25  5:58       ` Namhyung Kim
2023-10-12  9:15 ` Peter Zijlstra
2023-10-12 16:52   ` Namhyung Kim
2023-10-13 14:15 ` Arnaldo Carvalho de Melo
2023-10-23 21:58 ` Andi Kleen
2023-10-24 19:16   ` Namhyung Kim
2023-10-25  2:09     ` Andi Kleen
2023-10-25  5:51       ` Namhyung Kim
2023-10-25 20:01         ` Andi Kleen
2023-11-08 17:12 ` Joe Mario
2023-11-09  4:48   ` Namhyung Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231012035111.676789-18-namhyung@kernel.org \
    --to=namhyung@kernel.org \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=eranian@google.com \
    --cc=irogers@google.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-toolchains@vger.kernel.org \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.