From 379a73c6eb4633d4b635034887b0c22604d31c57 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 24 Jun 2021 10:01:27 -0300 Subject: [PATCH] core: Make class_member->name a real string For the threaded code we want to access strings in tags at the same time that the string table may grow in another thread making the previous pointer invalid, so, to avoid excessive locking, use plain strings. The way the tools work will either consume the just produced CU straight away or keep just one copy of each data structure when we keep all CUs in memory, so lets try stopping using strings_t for strings. For the class_member->name case we get the bonus of removing another user of dwarves__active_loader. Signed-off-by: Arnaldo Carvalho de Melo --- btf_encoder.c | 2 +- btf_loader.c | 8 ++++---- codiff.c | 12 ++++++------ ctf_loader.c | 4 ++-- ctracer.c | 14 +++++++------- dwarf_loader.c | 2 +- dwarves.c | 6 ++---- dwarves.h | 13 +++++-------- dwarves_fprintf.c | 6 +++--- dwarves_reorganize.c | 24 ++++++++++++------------ pahole.c | 18 +++++++++--------- 11 files changed, 52 insertions(+), 57 deletions(-) diff --git a/btf_encoder.c b/btf_encoder.c index bfdc304..f5e527e 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -766,7 +766,7 @@ static int32_t btf_encoder__add_struct_type(struct btf_encoder *encoder, struct * scheme, which conforms to BTF requirement, so no conversion * is required. */ - name = dwarves__active_loader->strings__ptr(cu, pos->name); + name = class_member__name(pos); if (btf_encoder__add_field(encoder, name, type_id_off + pos->tag.type, pos->bitfield_size, pos->bit_offset)) return -1; } diff --git a/btf_loader.c b/btf_loader.c index 8eb9206..14802e4 100644 --- a/btf_loader.c +++ b/btf_loader.c @@ -220,7 +220,7 @@ static int create_new_array(struct cu *cu, const struct btf_type *tp, uint32_t i return 0; } -static int create_members(const struct btf_type *tp, struct type *class) +static int create_members(struct cu *cu, const struct btf_type *tp, struct type *class) { struct btf_member *mp = btf_members(tp); int i, vlen = btf_vlen(tp); @@ -233,7 +233,7 @@ static int create_members(const struct btf_type *tp, struct type *class) member->tag.tag = DW_TAG_member; member->tag.type = mp[i].type; - member->name = mp[i].name_off; + member->name = cu__btf_str(cu, mp[i].name_off); member->bit_offset = btf_member_bit_offset(tp, i); member->bitfield_size = btf_member_bitfield_size(tp, i); member->byte_offset = member->bit_offset / 8; @@ -247,7 +247,7 @@ static int create_members(const struct btf_type *tp, struct type *class) static int create_new_class(struct cu *cu, const struct btf_type *tp, uint32_t id) { struct class *class = class__new(tp->name_off, tp->size, false); - int member_size = create_members(tp, &class->type); + int member_size = create_members(cu, tp, &class->type); if (member_size < 0) goto out_free; @@ -263,7 +263,7 @@ out_free: static int create_new_union(struct cu *cu, const struct btf_type *tp, uint32_t id) { struct type *un = type__new(DW_TAG_union_type, tp->name_off, tp->size); - int member_size = create_members(tp, un); + int member_size = create_members(cu, tp, un); if (member_size < 0) goto out_free; diff --git a/codiff.c b/codiff.c index d67a766..d8cfd16 100644 --- a/codiff.c +++ b/codiff.c @@ -173,7 +173,7 @@ static int check_print_change(const struct class_member *old, printf(" %s\n" " from: %-21s /* %5u(%2u) %5zd(%2d) */\n" " to: %-21s /* %5u(%2u) %5zd(%2u) */\n", - class_member__name(old, old_cu), + class_member__name(old), old_type_name, old->byte_offset, old->bitfield_offset, old_size, old->bitfield_size, new_type_name, new->byte_offset, new->bitfield_offset, @@ -186,7 +186,7 @@ static struct class_member *class__find_pair_member(const struct class *structur const struct class_member *pair_member, const struct cu *pair_cu, int *nr_anonymousp) { - const char *member_name = class_member__name(pair_member, pair_cu); + const char *member_name = class_member__name(pair_member); struct class_member *member; if (member_name) @@ -198,7 +198,7 @@ static struct class_member *class__find_pair_member(const struct class *structur type__for_each_member(&structure->type, member) { if (member->tag.tag == pair_member->tag.tag && /* Both are class/union/struct (unnamed) */ - class_member__name(member, cu) == member_name && /* Both are NULL? */ + class_member__name(member) == member_name && /* Both are NULL? */ --nr_anonymous == 0) return member; } @@ -231,7 +231,7 @@ static int check_print_members_changes(const struct class *structure, type = cu__type(cu, member->tag.type); printf(" %s\n" " removed: %-21s /* %5u(%2u) %5zd(%2d) */\n", - class_member__name(member, cu), + class_member__name(member), tag__name(type, cu, name, sizeof(name), NULL), member->byte_offset, member->bitfield_offset, member->byte_size, member->bitfield_size); @@ -254,7 +254,7 @@ static int check_print_members_changes(const struct class *structure, type = cu__type(new_cu, member->tag.type); printf(" %s\n" " added: %-21s /* %5u(%2u) %5zd(%2d) */\n", - class_member__name(member, new_cu), + class_member__name(member), tag__name(type, new_cu, name, sizeof(name), NULL), member->byte_offset, member->bitfield_offset, member->byte_size, member->bitfield_size); @@ -438,7 +438,7 @@ static void show_changed_member(char change, const struct class_member *member, tag__assert_search_result(type); printf(" %c%-26s %-21s /* %5u %5zd */\n", change, tag__name(type, cu, bf, sizeof(bf), NULL), - class_member__name(member, cu), + class_member__name(member), member->byte_offset, member->byte_size); } diff --git a/ctf_loader.c b/ctf_loader.c index 5bd5b52..87e5232 100644 --- a/ctf_loader.c +++ b/ctf_loader.c @@ -292,7 +292,7 @@ static int create_full_members(struct ctf *ctf, void *ptr, member->tag.tag = DW_TAG_member; member->tag.type = ctf__get16(ctf, &mp[i].ctf_member_type); - member->name = ctf__get32(ctf, &mp[i].ctf_member_name); + member->name = ctf__string(ctf, ctf__get32(ctf, &mp[i].ctf_member_name)); member->bit_offset = (ctf__get32(ctf, &mp[i].ctf_member_offset_high) << 16) | ctf__get32(ctf, &mp[i].ctf_member_offset_low); /* sizes and offsets will be corrected at class__fixup_ctf_bitfields */ @@ -316,7 +316,7 @@ static int create_short_members(struct ctf *ctf, void *ptr, member->tag.tag = DW_TAG_member; member->tag.type = ctf__get16(ctf, &mp[i].ctf_member_type); - member->name = ctf__get32(ctf, &mp[i].ctf_member_name); + member->name = ctf__string(ctf, ctf__get32(ctf, &mp[i].ctf_member_name)); member->bit_offset = ctf__get16(ctf, &mp[i].ctf_member_offset); /* sizes and offsets will be corrected at class__fixup_ctf_bitfields */ diff --git a/ctracer.c b/ctracer.c index 350e74c..ef46bd6 100644 --- a/ctracer.c +++ b/ctracer.c @@ -317,7 +317,7 @@ static size_t class__find_biggest_member_name(const struct class *class, type__for_each_data_member(&class->type, pos) { const size_t len = pos->name ? - strlen(class_member__name(pos, cu)) : 0; + strlen(class_member__name(pos)) : 0; if (len > biggest_name_len) biggest_name_len = len; @@ -341,8 +341,8 @@ static void class__emit_class_state_collector(struct class *class, class__name(class, cu), class__name(clone, cu)); type__for_each_data_member(&clone->type, pos) fprintf(fp_collector, "\tmini_obj->%-*s = obj->%s;\n", len, - class_member__name(pos, cu), - class_member__name(pos, cu)); + class_member__name(pos), + class_member__name(pos)); fputs("}\n\n", fp_collector); } @@ -461,10 +461,10 @@ static int class__emit_ostra_converter(struct tag *tag, plen -= n; p += n; } fprintf(fp_converter, "%%u"); - n = snprintf(p, plen, "obj.%s", class_member__name(pos, cu)); + n = snprintf(p, plen, "obj.%s", class_member__name(pos)); plen -= n; p += n; emit_struct_member_table_entry(fp_fields, field++, - class_member__name(pos, cu), + class_member__name(pos), 1, "entry,exit"); } fprintf(fp_converter, @@ -780,9 +780,9 @@ static int cu_emit_pointer_probes_iterator(struct cu *cu, void *cookie) continue; function__emit_probes(pos_tag, function_id, cu, target_type_id, 0, - class_member__name(pos_member, cu)); /* entry */ + class_member__name(pos_member)); /* entry */ function__emit_probes(pos_tag, function_id, cu, target_type_id, 1, - class_member__name(pos_member, cu)); /* exit */ + class_member__name(pos_member)); /* exit */ } return 0; diff --git a/dwarf_loader.c b/dwarf_loader.c index 5c60a12..1e6794c 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -859,7 +859,7 @@ static struct class_member *class_member__new(Dwarf_Die *die, struct cu *cu, if (member != NULL) { tag__init(&member->tag, cu, die); - member->name = strings__add(strings, attr_string(die, DW_AT_name)); + member->name = strdup_attr_string(die, DW_AT_name); member->const_value = attr_numeric(die, DW_AT_const_value); member->alignment = attr_numeric(die, DW_AT_alignment); diff --git a/dwarves.c b/dwarves.c index 8f6dceb..883eb2a 100644 --- a/dwarves.c +++ b/dwarves.c @@ -1678,16 +1678,14 @@ int class__has_hole_ge(const struct class *class, const uint16_t size) return 0; } -struct class_member *type__find_member_by_name(const struct type *type, - const struct cu *cu, - const char *name) +struct class_member *type__find_member_by_name(const struct type *type, const char *name) { if (name == NULL) return NULL; struct class_member *pos; type__for_each_data_member(type, pos) { - const char *curr_name = class_member__name(pos, cu); + const char *curr_name = class_member__name(pos); if (curr_name && strcmp(curr_name, name) == 0) return pos; } diff --git a/dwarves.h b/dwarves.h index 94a6f18..0467139 100644 --- a/dwarves.h +++ b/dwarves.h @@ -892,7 +892,7 @@ static inline int function__inlined(const struct function *func) */ struct class_member { struct tag tag; - strings_t name; + const char *name; uint32_t bit_offset; uint32_t bit_size; uint32_t byte_offset; @@ -918,10 +918,9 @@ static inline struct class_member *tag__class_member(const struct tag *tag) return (struct class_member *)tag; } -static inline const char *class_member__name(const struct class_member *member, - const struct cu *cu) +static inline const char *class_member__name(const struct class_member *member) { - return cu__string(cu, member->name); + return member->name; } static __pure inline int tag__is_class_member(const struct tag *tag) @@ -1084,9 +1083,7 @@ struct class_member * type__find_first_biggest_size_base_type_member(struct type *type, const struct cu *cu); -struct class_member *type__find_member_by_name(const struct type *type, - const struct cu *cu, - const char *name); +struct class_member *type__find_member_by_name(const struct type *type, const char *name); uint32_t type__nr_members_of_type(const struct type *type, const type_id_t oftype); struct class_member *type__last_member(struct type *type); @@ -1178,7 +1175,7 @@ static inline struct class_member * class__find_member_by_name(const struct class *cls, const struct cu *cu, const char *name) { - return type__find_member_by_name(&cls->type, cu, name); + return type__find_member_by_name(&cls->type, name); } static inline uint16_t class__nr_members(const struct class *cls) diff --git a/dwarves_fprintf.c b/dwarves_fprintf.c index b635685..f94a83a 100644 --- a/dwarves_fprintf.c +++ b/dwarves_fprintf.c @@ -567,7 +567,7 @@ static const char *__tag__name(const struct tag *tag, const struct cu *cu, } break; case DW_TAG_member: - snprintf(bf, len, "%s", class_member__name(tag__class_member(tag), cu)); + snprintf(bf, len, "%s", class_member__name(tag__class_member(tag))); break; case DW_TAG_variable: snprintf(bf, len, "%s", variable__name(tag__variable(tag), cu)); @@ -856,7 +856,7 @@ static size_t class_member__fprintf(struct class_member *member, bool union_memb struct conf_fprintf sconf = *conf; uint32_t offset = member->byte_offset; size_t printed = 0, printed_cacheline = 0; - const char *cm_name = class_member__name(member, cu), + const char *cm_name = class_member__name(member), *name = cm_name; if (!sconf.rel_offset) { @@ -1767,7 +1767,7 @@ static size_t __class__fprintf(struct class *class, const struct cu *cu, printed += fprintf(fp, "%.*s/* first biggest size base type member: %s %u %zd */\n", cconf.indent, tabs, - class_member__name(m, cu), m->byte_offset, + class_member__name(m), m->byte_offset, m->byte_size); } diff --git a/dwarves_reorganize.c b/dwarves_reorganize.c index bae5b6e..2ffb71d 100644 --- a/dwarves_reorganize.c +++ b/dwarves_reorganize.c @@ -225,7 +225,7 @@ static bool class__move_member(struct class *class, struct class_member *dest, if (verbose) fprintf(fp, " bitfield('%s' ... ", - class_member__name(from, cu)); + class_member__name(from)); class__for_each_member_safe_from(class, from, pos, tmp) { /* * Have we reached the end of the bitfield? @@ -241,10 +241,10 @@ static bool class__move_member(struct class *class, struct class_member *dest, list_splice(&from_list, &dest->tag.node); if (verbose) fprintf(fp, "'%s')", - class_member__name(tail_from, cu)); + class_member__name(tail_from)); } else { if (verbose) - fprintf(fp, " '%s'", class_member__name(from, cu)); + fprintf(fp, " '%s'", class_member__name(from)); /* * Remove 'from' from the list */ @@ -260,8 +260,8 @@ static bool class__move_member(struct class *class, struct class_member *dest, if (verbose) fprintf(fp, " from after '%s' to after '%s' */\n", - class_member__name(from_prev, cu), - class_member__name(dest, cu)); + class_member__name(from_prev), + class_member__name(dest)); if (from_padding) { /* @@ -279,7 +279,7 @@ static bool class__move_member(struct class *class, struct class_member *dest, if (verbose) fprintf(fp, "/* adding %zd bytes from %s to " "the padding */\n", - from_size, class_member__name(from, cu)); + from_size, class_member__name(from)); } } else if (from_was_last) { class->type.size -= from_size + class->padding; @@ -358,9 +358,9 @@ static void class__move_bit_member(struct class *class, const struct cu *cu, if (verbose) fprintf(fp, "/* Moving '%s:%u' from after '%s' to " "after '%s:%u' */\n", - class_member__name(from, cu), from->bitfield_size, - class_member__name(from_prev, cu), - class_member__name(dest, cu), dest->bitfield_size); + class_member__name(from), from->bitfield_size, + class_member__name(from_prev), + class_member__name(dest), dest->bitfield_size); /* * Remove 'from' from the list */ @@ -512,8 +512,8 @@ static int class__demote_bitfields(struct class *class, const struct cu *cu, char old_bf[64], new_bf[64]; fprintf(fp, "/* Demoting bitfield ('%s' ... '%s') " "from '%s' to '%s' */\n", - class_member__name(bitfield_head, cu), - class_member__name(member, cu), + class_member__name(bitfield_head), + class_member__name(member), base_type__name(tag__base_type(old_type_tag), cu, old_bf, sizeof(old_bf)), base_type__name(tag__base_type(new_type_tag), @@ -557,7 +557,7 @@ static int class__demote_bitfields(struct class *class, const struct cu *cu, char old_bf[64], new_bf[64]; fprintf(fp, "/* Demoting bitfield ('%s') " "from '%s' to '%s' */\n", - class_member__name(member, cu), + class_member__name(member), base_type__name(tag__base_type(old_type_tag), cu, old_bf, sizeof(old_bf)), base_type__name(tag__base_type(new_type_tag), diff --git a/pahole.c b/pahole.c index a754621..ce999d3 100644 --- a/pahole.c +++ b/pahole.c @@ -768,7 +768,7 @@ static void print_structs_with_pointer_to(struct cu *cu, uint32_t type) looked = true; } printf("%s: %s\n", str->name, - class_member__name(pos_member, cu)); + class_member__name(pos_member)); } } } @@ -1618,7 +1618,7 @@ static int __class__fprintf_value(struct tag *tag, struct cu *cu, void *instance type__for_each_member(type, member) { void *member_contents = instance + member->byte_offset; struct tag *member_type = cu__type(cu, member->tag.type); - const char *name = class_member__name(member, cu); + const char *name = class_member__name(member); if (name) printed += fprintf(fp, "\n%.*s\t.%s = ", indent, tabs, name); @@ -1803,7 +1803,7 @@ static void type_instance__delete(struct type_instance *instance) static int64_t type_instance__int_value(struct type_instance *instance, const char *member_name_orig) { struct cu *cu = instance->cu; - struct class_member *member = type__find_member_by_name(instance->type, cu, member_name_orig); + struct class_member *member = type__find_member_by_name(instance->type, member_name_orig); int byte_offset = 0; if (!member) { @@ -1824,7 +1824,7 @@ static int64_t type_instance__int_value(struct type_instance *instance, const ch *sep = 0; while (1) { - member = type__find_member_by_name(type, cu, member_name); + member = type__find_member_by_name(type, member_name); if (!member) { out_free_member_name: free(member_name_alloc); @@ -1841,7 +1841,7 @@ out_free_member_name: } - member = type__find_member_by_name(type, cu, member_name); + member = type__find_member_by_name(type, member_name); free(member_name_alloc); if (member == NULL) return -1; @@ -2196,7 +2196,7 @@ static int class_member_filter__parse(struct class_member_filter *filter, struct char before = s[1]; s[1] = '\0'; - filter->left = type__find_member_by_name(type, cu, member_name); + filter->left = type__find_member_by_name(type, member_name); if (!filter->left) { if (global_verbose) @@ -2235,7 +2235,7 @@ static int class_member_filter__parse(struct class_member_filter *filter, struct if (enumerator_value < 0) { if (global_verbose) fprintf(stderr, "Couldn't resolve right operand ('%s') in '%s' with the specified 'type=%s' and type_enum' \n", - value, sfilter, class_member__name(type->type_member, cu)); + value, sfilter, class_member__name(type->type_member)); return -1; } @@ -2556,7 +2556,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, struct type *type = tag__type(class); if (prototype->size) { - type->sizeof_member = type__find_member_by_name(type, cu, prototype->size); + type->sizeof_member = type__find_member_by_name(type, prototype->size); if (type->sizeof_member == NULL) { fprintf(stderr, "pahole: the sizeof member '%s' wasn't found in the '%s' type\n", prototype->size, prototype->name); @@ -2565,7 +2565,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, } if (prototype->type) { - type->type_member = type__find_member_by_name(type, cu, prototype->type); + type->type_member = type__find_member_by_name(type, prototype->type); if (type->type_member == NULL) { fprintf(stderr, "pahole: the type member '%s' wasn't found in the '%s' type\n", prototype->type, prototype->name);