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 <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2021-06-24 10:01:27 -03:00
parent 3280cb4176
commit 379a73c6eb
11 changed files with 52 additions and 57 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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),

View File

@ -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);