core: Make namespace->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 namespace->name case we get the bonus of removing another
user of dwarves__active_loader.

This covers unions, enums, structs and classes.

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 379a73c6eb
commit b99c4008ac
6 changed files with 30 additions and 39 deletions

View File

@ -748,14 +748,13 @@ static int32_t btf_encoder__add_struct_type(struct btf_encoder *encoder, struct
{
struct type *type = tag__type(tag);
struct class_member *pos;
const char *name;
const char *name = type__name(type, cu);
int32_t type_id;
uint8_t kind;
kind = (tag->tag == DW_TAG_union_type) ?
BTF_KIND_UNION : BTF_KIND_STRUCT;
name = dwarves__active_loader->strings__ptr(cu, type->namespace.name);
type_id = btf_encoder__add_struct(encoder, kind, name, type->size);
if (type_id < 0)
return type_id;
@ -790,10 +789,9 @@ static int32_t btf_encoder__add_enum_type(struct btf_encoder *encoder, struct cu
{
struct type *etype = tag__type(tag);
struct enumerator *pos;
const char *name;
const char *name = type__name(etype, cu);
int32_t type_id;
name = dwarves__active_loader->strings__ptr(cu, etype->namespace.name);
type_id = btf_encoder__add_enum(encoder, name, etype->size);
if (type_id < 0)
return type_id;
@ -829,12 +827,12 @@ static int btf_encoder__encode_tag(struct btf_encoder *encoder, struct cu *cu, s
case DW_TAG_volatile_type:
return btf_encoder__add_ref_type(encoder, BTF_KIND_VOLATILE, ref_type_id, NULL, false);
case DW_TAG_typedef:
name = dwarves__active_loader->strings__ptr(cu, tag__namespace(tag)->name);
name = namespace__name(tag__namespace(tag));
return btf_encoder__add_ref_type(encoder, BTF_KIND_TYPEDEF, ref_type_id, name, false);
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type:
name = dwarves__active_loader->strings__ptr(cu, tag__namespace(tag)->name);
name = namespace__name(tag__namespace(tag));
if (tag__type(tag)->declaration)
return btf_encoder__add_ref_type(encoder, BTF_KIND_FWD, 0, name, tag->tag == DW_TAG_union_type);
else

View File

@ -117,8 +117,7 @@ static struct base_type *base_type__new(const char *name, uint32_t attrs,
return bt;
}
static void type__init(struct type *type, uint32_t tag,
strings_t name, size_t size)
static void type__init(struct type *type, uint32_t tag, const char *name, size_t size)
{
__type__init(type);
INIT_LIST_HEAD(&type->namespace.tags);
@ -128,7 +127,7 @@ static void type__init(struct type *type, uint32_t tag,
type->namespace.sname = 0;
}
static struct type *type__new(uint16_t tag, strings_t name, size_t size)
static struct type *type__new(uint16_t tag, const char *name, size_t size)
{
struct type *type = tag__alloc(sizeof(*type));
@ -138,7 +137,7 @@ static struct type *type__new(uint16_t tag, strings_t name, size_t size)
return type;
}
static struct class *class__new(strings_t name, size_t size, bool is_union)
static struct class *class__new(const char *name, size_t size, bool is_union)
{
struct class *class = tag__alloc(sizeof(*class));
uint32_t tag = is_union ? DW_TAG_union_type : DW_TAG_structure_type;
@ -246,7 +245,7 @@ static int create_members(struct cu *cu, const struct btf_type *tp, struct type
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);
struct class *class = class__new(cu__btf_str(cu, tp->name_off), tp->size, false);
int member_size = create_members(cu, tp, &class->type);
if (member_size < 0)
@ -262,7 +261,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);
struct type *un = type__new(DW_TAG_union_type, cu__btf_str(cu, tp->name_off), tp->size);
int member_size = create_members(cu, tp, un);
if (member_size < 0)
@ -294,7 +293,7 @@ static int create_new_enumeration(struct cu *cu, const struct btf_type *tp, uint
struct btf_enum *ep = btf_enum(tp);
uint16_t i, vlen = btf_vlen(tp);
struct type *enumeration = type__new(DW_TAG_enumeration_type,
tp->name_off,
cu__btf_str(cu, tp->name_off),
tp->size ? tp->size * 8 : (sizeof(int) * 8));
if (enumeration == NULL)
@ -331,7 +330,7 @@ static int create_new_subroutine_type(struct cu *cu, const struct btf_type *tp,
static int create_new_forward_decl(struct cu *cu, const struct btf_type *tp, uint32_t id)
{
struct class *fwd = class__new(tp->name_off, 0, btf_kflag(tp));
struct class *fwd = class__new(cu__btf_str(cu, tp->name_off), 0, btf_kflag(tp));
if (fwd == NULL)
return -ENOMEM;
@ -342,7 +341,7 @@ static int create_new_forward_decl(struct cu *cu, const struct btf_type *tp, uin
static int create_new_typedef(struct cu *cu, const struct btf_type *tp, uint32_t id)
{
struct type *type = type__new(DW_TAG_typedef, tp->name_off, 0);
struct type *type = type__new(DW_TAG_typedef, cu__btf_str(cu, tp->name_off), 0);
if (type == NULL)
return -ENOMEM;

View File

@ -167,8 +167,7 @@ static struct base_type *base_type__new(const char *name, uint32_t attrs,
return bt;
}
static void type__init(struct type *type, uint16_t tag,
strings_t name, size_t size)
static void type__init(struct type *type, uint16_t tag, const char *name, size_t size)
{
__type__init(type);
INIT_LIST_HEAD(&type->namespace.tags);
@ -178,7 +177,7 @@ static void type__init(struct type *type, uint16_t tag,
type->namespace.sname = 0;
}
static struct type *type__new(uint16_t tag, strings_t name, size_t size)
static struct type *type__new(uint16_t tag, const char *name, size_t size)
{
struct type *type = tag__alloc(sizeof(*type));
@ -188,7 +187,7 @@ static struct type *type__new(uint16_t tag, strings_t name, size_t size)
return type;
}
static struct class *class__new(strings_t name, size_t size)
static struct class *class__new(const char *name, size_t size)
{
struct class *class = tag__alloc(sizeof(*class));
@ -331,7 +330,7 @@ static int create_new_class(struct ctf *ctf, void *ptr,
uint64_t size, uint32_t id)
{
int member_size;
strings_t name = ctf__get32(ctf, &tp->base.ctf_name);
const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
struct class *class = class__new(name, size);
if (size >= CTF_SHORT_MEMBER_LIMIT) {
@ -356,7 +355,7 @@ static int create_new_union(struct ctf *ctf, void *ptr,
uint64_t size, uint32_t id)
{
int member_size;
strings_t name = ctf__get32(ctf, &tp->base.ctf_name);
const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
struct type *un = type__new(DW_TAG_union_type, name, size);
if (size >= CTF_SHORT_MEMBER_LIMIT) {
@ -395,10 +394,8 @@ static int create_new_enumeration(struct ctf *ctf, void *ptr,
{
struct ctf_enum *ep = ptr;
uint16_t i;
struct type *enumeration = type__new(DW_TAG_enumeration_type,
ctf__get32(ctf,
&tp->base.ctf_name),
size ?: (sizeof(int) * 8));
const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
struct type *enumeration = type__new(DW_TAG_enumeration_type, name, size ?: (sizeof(int) * 8));
if (enumeration == NULL)
return -ENOMEM;
@ -425,7 +422,7 @@ out_free:
static int create_new_forward_decl(struct ctf *ctf, struct ctf_full_type *tp,
uint64_t size, uint32_t id)
{
strings_t name = ctf__get32(ctf, &tp->base.ctf_name);
const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
struct class *fwd = class__new(name, size);
if (fwd == NULL)
@ -438,7 +435,7 @@ static int create_new_forward_decl(struct ctf *ctf, struct ctf_full_type *tp,
static int create_new_typedef(struct ctf *ctf, struct ctf_full_type *tp,
uint64_t size, uint32_t id)
{
strings_t name = ctf__get32(ctf, &tp->base.ctf_name);
const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
unsigned int type_id = ctf__get16(ctf, &tp->base.ctf_type);
struct type *type = type__new(DW_TAG_typedef, name, size);

View File

@ -580,7 +580,7 @@ static void namespace__init(struct namespace *namespace, Dwarf_Die *die,
tag__init(&namespace->tag, cu, die);
INIT_LIST_HEAD(&namespace->tags);
namespace->sname = 0;
namespace->name = strings__add(strings, attr_string(die, DW_AT_name));
namespace->name = strdup_attr_string(die, DW_AT_name);
namespace->nr_tags = 0;
namespace->shared_tags = 0;
}
@ -715,8 +715,7 @@ static int tag__recode_dwarf_bitfield(struct tag *tag, struct cu *cu, uint16_t b
type_id_t short_id;
struct tag *recoded;
/* in all the cases the name is at the same offset */
strings_t sname = tag__namespace(tag)->name;
const char *name = strings__ptr(strings, sname);
const char *name = namespace__name(tag__namespace(tag));
switch (tag->tag) {
case DW_TAG_typedef: {
@ -816,7 +815,7 @@ static int tag__recode_dwarf_bitfield(struct tag *tag, struct cu *cu, uint16_t b
*/
new_enum->namespace.tags.next = &alias->namespace.tags;
new_enum->namespace.shared_tags = 1;
new_enum->namespace.name = sname;
new_enum->namespace.name = strdup(name);
new_enum->size = bit_size;
break;
default:

View File

@ -586,7 +586,7 @@ static inline struct ptr_to_member_type *
*/
struct namespace {
struct tag tag;
strings_t name;
const char *name;
uint16_t nr_tags;
uint8_t shared_tags;
char * sname;
@ -1136,16 +1136,15 @@ static inline struct list_head *class__tags(struct class *cls)
return &cls->type.namespace.tags;
}
static __pure inline const char *namespace__name(const struct namespace *nspace,
const struct cu *cu)
static __pure inline const char *namespace__name(const struct namespace *nspace)
{
return nspace->sname ?: cu__string(cu, nspace->name);
return nspace->name;
}
static __pure inline const char *type__name(const struct type *type,
const struct cu *cu)
{
return namespace__name(&type->namespace, cu);
return namespace__name(&type->namespace);
}
static __pure inline const char *class__name(struct class *cls,

View File

@ -365,7 +365,7 @@ static size_t imported_module__fprintf(const struct tag *tag,
const char *name = "<IMPORTED MODULE ERROR!>";
if (tag__is_namespace(module))
name = namespace__name(tag__namespace(module), cu);
name = namespace__name(tag__namespace(module));
return fprintf(fp, "using namespace %s", name);
}
@ -1830,8 +1830,7 @@ static size_t namespace__fprintf(const struct tag *tag, const struct cu *cu,
{
struct namespace *space = tag__namespace(tag);
struct conf_fprintf cconf = *conf;
size_t printed = fprintf(fp, "namespace %s {\n",
namespace__name(space, cu));
size_t printed = fprintf(fp, "namespace %s {\n", namespace__name(space));
struct tag *pos;
++cconf.indent;