mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-31 14:11:36 +08:00
gdb/dwarf: remove type_unit_group
The type_unit_group is an indirection between a stmt_list_hash (possible dwo_unit + line table section offset) and a type_unit_group_unshareable that provides no real value. In dwarf2_per_objfile, we maintain a stmt_list_hash -> type_unit_group mapping, and in dwarf2_per_objfile, we maintain a type_unit_group_unshareable mapping. The type_unit_group type is empty and only exists to have an identity and to be a link between the two mappings. This patch changes it so that we have a single stmt_list_hash -> type_unit_group_unshareable mapping. Regression tested on Debian 12 amd64 with a bunch of DWARF target boards. Change-Id: I9c5778ecb18963f353e9dd058e0f8152f7d8930c Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
parent
d87251a45b
commit
c08c2adbb0
@ -265,29 +265,6 @@ struct loclists_rnglists_header
|
||||
unsigned int offset_entry_count;
|
||||
};
|
||||
|
||||
/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
|
||||
This includes type_unit_group and quick_file_names. */
|
||||
|
||||
struct stmt_list_hash
|
||||
{
|
||||
bool operator== (const stmt_list_hash &other) const noexcept;
|
||||
|
||||
/* The DWO unit this table is from or NULL if there is none. */
|
||||
struct dwo_unit *dwo_unit;
|
||||
|
||||
/* Offset in .debug_line or .debug_line.dwo. */
|
||||
sect_offset line_sect_off;
|
||||
};
|
||||
|
||||
/* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
|
||||
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
|
||||
{
|
||||
};
|
||||
|
||||
/* These sections are what may appear in a (real or virtual) DWO file. */
|
||||
|
||||
struct dwo_sections
|
||||
@ -2552,7 +2529,7 @@ fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile *per_objfile,
|
||||
gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0
|
||||
|| (to_underlying (sig_entry->type_offset_in_section)
|
||||
== to_underlying (dwo_entry->type_offset_in_tu)));
|
||||
gdb_assert (sig_entry->type_unit_group == NULL);
|
||||
gdb_assert (!sig_entry->type_unit_group_key.has_value ());
|
||||
gdb_assert (sig_entry->dwo_unit == NULL
|
||||
|| sig_entry->dwo_unit == dwo_entry);
|
||||
|
||||
@ -3279,14 +3256,13 @@ cutu_reader::cutu_reader (dwarf2_per_cu *this_cu,
|
||||
#define NO_STMT_LIST_TYPE_UNIT_PSYMTAB (1 << 31)
|
||||
#define NO_STMT_LIST_TYPE_UNIT_PSYMTAB_SIZE 10
|
||||
|
||||
/* Look up the type_unit_group for type unit CU, and create it if necessary.
|
||||
STMT_LIST is a DW_AT_stmt_list attribute. */
|
||||
/* Get the type unit group key for type unit CU. STMT_LIST is a DW_AT_stmt_list
|
||||
attribute. */
|
||||
|
||||
static struct type_unit_group *
|
||||
get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
|
||||
static stmt_list_hash
|
||||
get_type_unit_group_key (struct dwarf2_cu *cu, const struct attribute *stmt_list)
|
||||
{
|
||||
dwarf2_per_objfile *per_objfile = cu->per_objfile;
|
||||
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
|
||||
struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
|
||||
unsigned int line_offset;
|
||||
|
||||
@ -3310,16 +3286,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
|
||||
++tu_stats->nr_stmt_less_type_units;
|
||||
}
|
||||
|
||||
stmt_list_hash key {cu->dwo_unit, static_cast<sect_offset> (line_offset)};
|
||||
auto [it, inserted] = per_bfd->type_unit_groups.emplace (key, nullptr);
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
(*it).second = std::make_unique<type_unit_group> ();
|
||||
++tu_stats->nr_symtabs;
|
||||
}
|
||||
|
||||
return it->second.get ();
|
||||
return {cu->dwo_unit, static_cast<sect_offset> (line_offset)};
|
||||
}
|
||||
|
||||
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
|
||||
@ -3424,9 +3391,6 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile,
|
||||
abbrev_table_up abbrev_table;
|
||||
sect_offset abbrev_offset;
|
||||
|
||||
/* It's up to the caller to not call us multiple times. */
|
||||
gdb_assert (per_objfile->per_bfd->type_unit_groups.empty ());
|
||||
|
||||
if (per_objfile->per_bfd->all_type_units.size () == 0)
|
||||
return;
|
||||
|
||||
@ -4753,16 +4717,15 @@ rust_union_quirks (struct dwarf2_cu *cu)
|
||||
/* See read.h. */
|
||||
|
||||
type_unit_group_unshareable *
|
||||
dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group)
|
||||
dwarf2_per_objfile::get_type_unit_group_unshareable
|
||||
(stmt_list_hash tu_group_key)
|
||||
{
|
||||
auto iter = m_type_units.find (tu_group);
|
||||
if (iter != m_type_units.end ())
|
||||
return iter->second.get ();
|
||||
auto [it, inserted] = m_type_units.emplace (tu_group_key, nullptr);
|
||||
|
||||
type_unit_group_unshareable_up uniq (new type_unit_group_unshareable);
|
||||
type_unit_group_unshareable *result = uniq.get ();
|
||||
m_type_units[tu_group] = std::move (uniq);
|
||||
return result;
|
||||
if (inserted)
|
||||
it->second = std::make_unique<type_unit_group_unshareable> ();
|
||||
|
||||
return it->second.get ();
|
||||
}
|
||||
|
||||
struct type *
|
||||
@ -5034,7 +4997,7 @@ process_full_type_unit (dwarf2_cu *cu)
|
||||
of it with end_expandable_symtab. Otherwise, complete the addition of
|
||||
this TU's symbols to the existing symtab. */
|
||||
type_unit_group_unshareable *tug_unshare =
|
||||
per_objfile->get_type_unit_group_unshareable (sig_type->type_unit_group);
|
||||
per_objfile->get_type_unit_group_unshareable (*sig_type->type_unit_group_key);
|
||||
if (tug_unshare->compunit_symtab == NULL)
|
||||
{
|
||||
buildsym_compunit *builder = cu->get_builder ();
|
||||
@ -6222,7 +6185,6 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
void
|
||||
dwarf2_cu::setup_type_unit_groups (struct die_info *die)
|
||||
{
|
||||
struct type_unit_group *tu_group;
|
||||
int first_time;
|
||||
struct attribute *attr;
|
||||
unsigned int i;
|
||||
@ -6235,16 +6197,15 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
|
||||
|
||||
/* If we're using .gdb_index (includes -readnow) then
|
||||
per_cu->type_unit_group may not have been set up yet. */
|
||||
if (sig_type->type_unit_group == NULL)
|
||||
sig_type->type_unit_group = get_type_unit_group (this, attr);
|
||||
tu_group = sig_type->type_unit_group;
|
||||
if (!sig_type->type_unit_group_key.has_value ())
|
||||
sig_type->type_unit_group_key = get_type_unit_group_key (this, attr);
|
||||
|
||||
/* If we've already processed this stmt_list there's no real need to
|
||||
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. */
|
||||
type_unit_group_unshareable *tug_unshare
|
||||
= per_objfile->get_type_unit_group_unshareable (tu_group);
|
||||
= per_objfile->get_type_unit_group_unshareable (*sig_type->type_unit_group_key);
|
||||
first_time = tug_unshare->compunit_symtab == NULL;
|
||||
|
||||
/* We have to handle the case of both a missing DW_AT_stmt_list or bad
|
||||
|
@ -55,7 +55,6 @@ struct dwarf2_per_cu;
|
||||
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. */
|
||||
@ -74,6 +73,27 @@ struct dwarf2_queue_item
|
||||
dwarf2_per_objfile *per_objfile;
|
||||
};
|
||||
|
||||
/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
|
||||
This includes type_unit_group and quick_file_names. */
|
||||
|
||||
struct stmt_list_hash
|
||||
{
|
||||
bool operator== (const stmt_list_hash &other) const noexcept;
|
||||
|
||||
/* The DWO unit this table is from or NULL if there is none. */
|
||||
struct dwo_unit *dwo_unit;
|
||||
|
||||
/* Offset in .debug_line or .debug_line.dwo. */
|
||||
sect_offset line_sect_off;
|
||||
};
|
||||
|
||||
struct stmt_list_hash_hash
|
||||
{
|
||||
using is_avalanching = void;
|
||||
|
||||
std::uint64_t operator() (const stmt_list_hash &key) const noexcept;
|
||||
};
|
||||
|
||||
/* A deleter for dwarf2_per_cu that knows to downcast to signatured_type as
|
||||
appropriate. This approach lets us avoid a virtual destructor, which saves
|
||||
a bit of space. */
|
||||
@ -376,8 +396,9 @@ struct signatured_type : public dwarf2_per_cu
|
||||
sect_offset type_offset_in_section {};
|
||||
|
||||
/* Type units are grouped by their DW_AT_stmt_list entry so that they
|
||||
can share them. This points to the containing symtab. */
|
||||
struct type_unit_group *type_unit_group = nullptr;
|
||||
can share them. This is the key of the group this type unit is part
|
||||
of. */
|
||||
std::optional<stmt_list_hash> type_unit_group_key;
|
||||
|
||||
/* Containing DWO unit.
|
||||
This field is valid iff per_cu.reading_dwo_directly. */
|
||||
@ -467,17 +488,6 @@ struct dwp_file;
|
||||
|
||||
using dwp_file_up = std::unique_ptr<dwp_file>;
|
||||
|
||||
struct stmt_list_hash;
|
||||
|
||||
struct stmt_list_hash_hash
|
||||
{
|
||||
using is_avalanching = void;
|
||||
|
||||
std::uint64_t operator() (const stmt_list_hash &key) const noexcept;
|
||||
};
|
||||
|
||||
using type_unit_group_up = std::unique_ptr<type_unit_group>;
|
||||
|
||||
/* Some DWARF data can be shared across objfiles who share the same BFD,
|
||||
this data is stored in this object.
|
||||
|
||||
@ -614,11 +624,6 @@ public:
|
||||
std::vector<dwarf2_per_cu *> all_comp_units_index_cus;
|
||||
std::vector<dwarf2_per_cu *> all_comp_units_index_tus;
|
||||
|
||||
/* Table of struct type_unit_group objects.
|
||||
The hash key is the DW_AT_stmt_list value. */
|
||||
gdb::unordered_map<stmt_list_hash, type_unit_group_up, stmt_list_hash_hash>
|
||||
type_unit_groups;
|
||||
|
||||
/* Set of signatured_types, used to look up by signature. */
|
||||
signatured_type_set signatured_types;
|
||||
|
||||
@ -828,10 +833,10 @@ struct dwarf2_per_objfile
|
||||
/* Set the compunit_symtab associated to PER_CU. */
|
||||
void set_symtab (const dwarf2_per_cu *per_cu, compunit_symtab *symtab);
|
||||
|
||||
/* Get the type_unit_group_unshareable corresponding to TU_GROUP. If one
|
||||
/* Get the type_unit_group_unshareable corresponding to TU_GROUP_KEY. If one
|
||||
does not exist, create it. */
|
||||
type_unit_group_unshareable *get_type_unit_group_unshareable
|
||||
(type_unit_group *tu_group);
|
||||
(stmt_list_hash tu_group_key);
|
||||
|
||||
struct type *get_type_for_signatured_type (signatured_type *sig_type) const;
|
||||
|
||||
@ -898,9 +903,10 @@ private:
|
||||
expanded yet. */
|
||||
std::vector<compunit_symtab *> m_symtabs;
|
||||
|
||||
/* Map from a type unit group to the corresponding unshared
|
||||
/* Map from a type unit group key to the corresponding unshared
|
||||
structure. */
|
||||
gdb::unordered_map<type_unit_group *, type_unit_group_unshareable_up>
|
||||
gdb::unordered_map<stmt_list_hash, type_unit_group_unshareable_up,
|
||||
stmt_list_hash_hash>
|
||||
m_type_units;
|
||||
|
||||
/* Map from signatured types to the corresponding struct type. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user