Split type_unit_group

type_unit_group has links to the compunit_symtab and other symtabs.
However, once this object is shared across objfiles, this will no
longer be ok.

This patch introduces a new type_unit_group_unshareable and arranges to
store a map from type unit groups to type_unit_group_unshareable objects
in dwarf2_per_objfile.

gdb/ChangeLog:

YYYY-MM-DD  Tom Tromey  <tom@tromey.com>
YYYY-MM-DD  Simon Marchi  <simon.marchi@efficios.com>

	* dwarf2/read.h (struct type_unit_group_unshareable): New.
	(struct dwarf2_per_objfile) <type_units>: New member.
	<get_type_unit_group_unshareable>: New method.
	* dwarf2/read.c (struct type_unit_group) <compunit_symtab,
	num_symtabs, symtabs>: Remove; move to
	type_unit_group_unshareable.
	(dwarf2_per_objfile::get_type_unit_group_unshareable): New.
	(process_full_type_unit, dwarf2_cu::setup_type_unit_groups)
	(dwarf2_cu::setup_type_unit_groups): Use type_unit_group_unshareable.

Change-Id: I1fec2fab59e0ec40fee3614fc821172a469c0e41
This commit is contained in:
Tom Tromey 2020-05-27 11:19:09 -04:00 committed by Simon Marchi
parent 127bbf4b50
commit 8adb84872b
3 changed files with 83 additions and 26 deletions

View File

@ -1,3 +1,16 @@
2020-05-27 Tom Tromey <tom@tromey.com>
Simon Marchi <simon.marchi@efficios.com>
* dwarf2/read.h (struct type_unit_group_unshareable): New.
(struct dwarf2_per_objfile) <type_units>: New member.
<get_type_unit_group_unshareable>: New method.
* dwarf2/read.c (struct type_unit_group) <compunit_symtab,
num_symtabs, symtabs>: Remove; move to
type_unit_group_unshareable.
(dwarf2_per_objfile::get_type_unit_group_unshareable): New.
(process_full_type_unit, dwarf2_cu::setup_type_unit_groups)
(dwarf2_cu::setup_type_unit_groups): Use type_unit_group_unshareable.
2020-05-27 Simon Marchi <simon.marchi@efficios.com>
* dwarf2/read.h (struct dwarf2_per_cu_data):

View File

@ -614,7 +614,9 @@ struct stmt_list_hash
};
/* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
an object of this type. */
an object of this type. This contains elements of type unit groups
that can be shared across objfiles. The non-shareable parts are in
type_unit_group_unshareable. */
struct type_unit_group
{
@ -629,23 +631,8 @@ struct type_unit_group
and is deleted afterwards and not used again. */
std::vector<signatured_type *> *tus;
/* The compunit symtab.
Type units in a group needn't all be defined in the same source file,
so we create an essentially anonymous symtab as the compunit symtab. */
struct compunit_symtab *compunit_symtab;
/* The data used to construct the hash key. */
struct stmt_list_hash hash;
/* The symbol tables for this TU (obtained from the files listed in
DW_AT_stmt_list).
WARNING: The order of entries here must match the order of entries
in the line header. After the first TU using this type_unit_group, the
line header for the subsequent TUs is recreated from this. This is done
because we need to use the same symtabs for each TU using the same
DW_AT_stmt_list value. Also note that symtabs may be repeated here,
there's no guarantee the line header doesn't have duplicate entries. */
struct symtab **symtabs;
};
/* These sections are what may appear in a (real or virtual) DWO file. */
@ -9628,6 +9615,21 @@ rust_union_quirks (struct dwarf2_cu *cu)
cu->rust_unions.clear ();
}
/* See read.h. */
type_unit_group_unshareable *
dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group)
{
auto iter = this->m_type_units.find (tu_group);
if (iter != this->m_type_units.end ())
return iter->second.get ();
type_unit_group_unshareable_up uniq (new type_unit_group_unshareable);
type_unit_group_unshareable *result = uniq.get ();
this->m_type_units[tu_group] = std::move (uniq);
return result;
}
/* A helper function for computing the list of all symbol tables
included by PER_CU. */
@ -9883,11 +9885,13 @@ process_full_type_unit (dwarf2_per_cu_data *per_cu,
If this is the first TU to use this symtab, complete the construction
of it with end_expandable_symtab. Otherwise, complete the addition of
this TU's symbols to the existing symtab. */
if (sig_type->type_unit_group->compunit_symtab == NULL)
type_unit_group_unshareable *tug_unshare =
dwarf2_per_objfile->get_type_unit_group_unshareable (sig_type->type_unit_group);
if (tug_unshare->compunit_symtab == NULL)
{
buildsym_compunit *builder = cu->get_builder ();
cust = builder->end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
sig_type->type_unit_group->compunit_symtab = cust;
tug_unshare->compunit_symtab = cust;
if (cust != NULL)
{
@ -9903,7 +9907,7 @@ process_full_type_unit (dwarf2_per_cu_data *per_cu,
else
{
cu->get_builder ()->augment_type_symtab ();
cust = sig_type->type_unit_group->compunit_symtab;
cust = tug_unshare->compunit_symtab;
}
dwarf2_per_objfile->set_symtab (per_cu, cust);
@ -11042,7 +11046,9 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
do it again, we could fake it and just recreate the part we need
(file name,index -> symtab mapping). If data shows this optimization
is useful we can do it then. */
first_time = tu_group->compunit_symtab == NULL;
type_unit_group_unshareable *tug_unshare
= per_objfile->get_type_unit_group_unshareable (tu_group);
first_time = tug_unshare->compunit_symtab == NULL;
/* We have to handle the case of both a missing DW_AT_stmt_list or bad
debug info. */
@ -11058,9 +11064,9 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
start_symtab ("", NULL, 0);
else
{
gdb_assert (tu_group->symtabs == NULL);
gdb_assert (tug_unshare->symtabs == NULL);
gdb_assert (m_builder == nullptr);
struct compunit_symtab *cust = tu_group->compunit_symtab;
struct compunit_symtab *cust = tug_unshare->compunit_symtab;
m_builder.reset (new struct buildsym_compunit
(COMPUNIT_OBJFILE (cust), "",
COMPUNIT_DIRNAME (cust),
@ -11083,7 +11089,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
process_full_type_unit still needs to know if this is the first
time. */
tu_group->symtabs
tug_unshare->symtabs
= XOBNEWVEC (&COMPUNIT_OBJFILE (cust)->objfile_obstack,
struct symtab *, line_header->file_names_size ());
@ -11106,13 +11112,13 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
}
fe.symtab = b->get_current_subfile ()->symtab;
tu_group->symtabs[i] = fe.symtab;
tug_unshare->symtabs[i] = fe.symtab;
}
}
else
{
gdb_assert (m_builder == nullptr);
struct compunit_symtab *cust = tu_group->compunit_symtab;
struct compunit_symtab *cust = tug_unshare->compunit_symtab;
m_builder.reset (new struct buildsym_compunit
(COMPUNIT_OBJFILE (cust), "",
COMPUNIT_DIRNAME (cust),
@ -11124,7 +11130,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
for (i = 0; i < file_names.size (); ++i)
{
file_entry &fe = file_names[i];
fe.symtab = tu_group->symtabs[i];
fe.symtab = tug_unshare->symtabs[i];
}
}

View File

@ -47,6 +47,7 @@ struct dwarf2_per_cu_data;
struct mapped_index;
struct mapped_debug_names;
struct signatured_type;
struct type_unit_group;
/* One item on the queue of compilation units to read in full symbols
for. */
@ -265,6 +266,30 @@ private:
size_t m_num_psymtabs = 0;
};
/* This is the per-objfile data associated with a type_unit_group. */
struct type_unit_group_unshareable
{
/* The compunit symtab.
Type units in a group needn't all be defined in the same source file,
so we create an essentially anonymous symtab as the compunit symtab. */
struct compunit_symtab *compunit_symtab = nullptr;
/* The number of symtabs from the line header.
The value here must match line_header.num_file_names. */
unsigned int num_symtabs = 0;
/* The symbol tables for this TU (obtained from the files listed in
DW_AT_stmt_list).
WARNING: The order of entries here must match the order of entries
in the line header. After the first TU using this type_unit_group, the
line header for the subsequent TUs is recreated from this. This is done
because we need to use the same symtabs for each TU using the same
DW_AT_stmt_list value. Also note that symtabs may be repeated here,
there's no guarantee the line header doesn't have duplicate entries. */
struct symtab **symtabs = nullptr;
};
/* Collection of data recorded per objfile.
This hangs off of dwarf2_objfile_data_key.
@ -304,6 +329,11 @@ struct dwarf2_per_objfile
/* Set the compunit_symtab associated to PER_CU. */
void set_symtab (const dwarf2_per_cu_data *per_cu, compunit_symtab *symtab);
/* Get the type_unit_group_unshareable corresponding to TU_GROUP. If one
does not exist, create it. */
type_unit_group_unshareable *get_type_unit_group_unshareable
(type_unit_group *tu_group);
/* Find an integer type SIZE_IN_BYTES bytes in size and return it.
UNSIGNED_P controls if the integer is unsigned or not. */
struct type *int_type (int size_in_bytes, bool unsigned_p) const;
@ -325,6 +355,14 @@ private:
is indexed by dwarf2_per_cu_data::index. A NULL value means
that the CU/TU has not been expanded yet. */
std::vector<compunit_symtab *> m_symtabs;
/* Map from a type unit group to the corresponding unshared
structure. */
typedef std::unique_ptr<type_unit_group_unshareable>
type_unit_group_unshareable_up;
std::unordered_map<type_unit_group *, type_unit_group_unshareable_up>
m_type_units;
};
/* Get the dwarf2_per_objfile associated to OBJFILE. */