mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
Convert dwarf2_per_objfile::die_type_hash to new hash table
Convert dwarf2_per_objfile::die_type_hash, which maps debug info offsets to `type *`, to gdb::unordered_map. Change-Id: I5c174af64ee46d38a465008090e812acf03704ec
This commit is contained in:
parent
18784a7fe2
commit
ee8f65ec48
@ -21653,52 +21653,6 @@ dwarf2_per_objfile::~dwarf2_per_objfile ()
|
||||
remove_all_cus ();
|
||||
}
|
||||
|
||||
/* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer.
|
||||
We store these in a hash table separate from the DIEs, and preserve them
|
||||
when the DIEs are flushed out of cache.
|
||||
|
||||
The CU "per_cu" pointer is needed because offset alone is not enough to
|
||||
uniquely identify the type. A file may have multiple .debug_types sections,
|
||||
or the type may come from a DWO file. Furthermore, while it's more logical
|
||||
to use per_cu->section+offset, with Fission the section with the data is in
|
||||
the DWO file but we don't know that section at the point we need it.
|
||||
We have to use something in dwarf2_per_cu_data (or the pointer to it)
|
||||
because we can enter the lookup routine, get_die_type_at_offset, from
|
||||
outside this file, and thus won't necessarily have PER_CU->cu.
|
||||
Fortunately, PER_CU is stable for the life of the objfile. */
|
||||
|
||||
struct dwarf2_per_cu_offset_and_type
|
||||
{
|
||||
const struct dwarf2_per_cu_data *per_cu;
|
||||
sect_offset sect_off;
|
||||
struct type *type;
|
||||
};
|
||||
|
||||
/* Hash function for a dwarf2_per_cu_offset_and_type. */
|
||||
|
||||
static hashval_t
|
||||
per_cu_offset_and_type_hash (const void *item)
|
||||
{
|
||||
const struct dwarf2_per_cu_offset_and_type *ofs
|
||||
= (const struct dwarf2_per_cu_offset_and_type *) item;
|
||||
|
||||
return (uintptr_t) ofs->per_cu + to_underlying (ofs->sect_off);
|
||||
}
|
||||
|
||||
/* Equality function for a dwarf2_per_cu_offset_and_type. */
|
||||
|
||||
static int
|
||||
per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs)
|
||||
{
|
||||
const struct dwarf2_per_cu_offset_and_type *ofs_lhs
|
||||
= (const struct dwarf2_per_cu_offset_and_type *) item_lhs;
|
||||
const struct dwarf2_per_cu_offset_and_type *ofs_rhs
|
||||
= (const struct dwarf2_per_cu_offset_and_type *) item_rhs;
|
||||
|
||||
return (ofs_lhs->per_cu == ofs_rhs->per_cu
|
||||
&& ofs_lhs->sect_off == ofs_rhs->sect_off);
|
||||
}
|
||||
|
||||
/* Set the type associated with DIE to TYPE. Save it in CU's hash
|
||||
table if necessary. For convenience, return TYPE.
|
||||
|
||||
@ -21722,8 +21676,6 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
|
||||
bool skip_data_location)
|
||||
{
|
||||
dwarf2_per_objfile *per_objfile = cu->per_objfile;
|
||||
struct dwarf2_per_cu_offset_and_type **slot, ofs;
|
||||
struct objfile *objfile = per_objfile->objfile;
|
||||
struct attribute *attr;
|
||||
struct dynamic_prop prop;
|
||||
|
||||
@ -21779,24 +21731,13 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
|
||||
type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
|
||||
}
|
||||
|
||||
if (per_objfile->die_type_hash == NULL)
|
||||
per_objfile->die_type_hash
|
||||
= htab_up (htab_create_alloc (127,
|
||||
per_cu_offset_and_type_hash,
|
||||
per_cu_offset_and_type_eq,
|
||||
NULL, xcalloc, xfree));
|
||||
|
||||
ofs.per_cu = cu->per_cu;
|
||||
ofs.sect_off = die->sect_off;
|
||||
ofs.type = type;
|
||||
slot = (struct dwarf2_per_cu_offset_and_type **)
|
||||
htab_find_slot (per_objfile->die_type_hash.get (), &ofs, INSERT);
|
||||
if (*slot)
|
||||
bool inserted
|
||||
= per_objfile->die_type_hash.emplace
|
||||
(per_cu_and_offset {cu->per_cu, die->sect_off}, type).second;
|
||||
if (!inserted)
|
||||
complaint (_("A problem internal to GDB: DIE %s has type already set"),
|
||||
sect_offset_str (die->sect_off));
|
||||
*slot = XOBNEW (&objfile->objfile_obstack,
|
||||
struct dwarf2_per_cu_offset_and_type);
|
||||
**slot = ofs;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -21808,19 +21749,9 @@ get_die_type_at_offset (sect_offset sect_off,
|
||||
dwarf2_per_cu_data *per_cu,
|
||||
dwarf2_per_objfile *per_objfile)
|
||||
{
|
||||
struct dwarf2_per_cu_offset_and_type *slot, ofs;
|
||||
auto it = per_objfile->die_type_hash.find ({per_cu, sect_off});
|
||||
|
||||
if (per_objfile->die_type_hash == NULL)
|
||||
return NULL;
|
||||
|
||||
ofs.per_cu = per_cu;
|
||||
ofs.sect_off = sect_off;
|
||||
slot = ((struct dwarf2_per_cu_offset_and_type *)
|
||||
htab_find (per_objfile->die_type_hash.get (), &ofs));
|
||||
if (slot)
|
||||
return slot->type;
|
||||
else
|
||||
return NULL;
|
||||
return it != per_objfile->die_type_hash.end () ? it->second : nullptr;
|
||||
}
|
||||
|
||||
/* Look up the type for DIE in CU in die_type_hash,
|
||||
|
@ -627,6 +627,26 @@ struct type_unit_group_unshareable
|
||||
struct symtab **symtabs = nullptr;
|
||||
};
|
||||
|
||||
struct per_cu_and_offset
|
||||
{
|
||||
dwarf2_per_cu_data *per_cu;
|
||||
sect_offset offset;
|
||||
|
||||
bool operator== (const per_cu_and_offset &other) const noexcept
|
||||
{
|
||||
return this->per_cu == other.per_cu && this->offset == other.offset;
|
||||
}
|
||||
};
|
||||
|
||||
struct per_cu_and_offset_hash
|
||||
{
|
||||
std::uint64_t operator() (const per_cu_and_offset &key) const noexcept
|
||||
{
|
||||
return (std::hash<dwarf2_per_cu_data *> () (key.per_cu)
|
||||
+ std::hash<sect_offset> () (key.offset));
|
||||
}
|
||||
};
|
||||
|
||||
/* Collection of data recorded per objfile.
|
||||
This hangs off of dwarf2_objfile_data_key.
|
||||
|
||||
@ -701,10 +721,22 @@ struct dwarf2_per_objfile
|
||||
other objfiles backed by the same BFD. */
|
||||
struct dwarf2_per_bfd *per_bfd;
|
||||
|
||||
/* Table mapping type DIEs to their struct type *.
|
||||
This is nullptr if not allocated yet.
|
||||
The mapping is done via (CU/TU + DIE offset) -> type. */
|
||||
htab_up die_type_hash;
|
||||
/* A mapping of (CU "per_cu" pointer, DIE offset) to GDB type pointer.
|
||||
|
||||
We store these in a hash table separate from the DIEs, and preserve them
|
||||
when the DIEs are flushed out of cache.
|
||||
|
||||
The CU "per_cu" pointer is needed because offset alone is not enough to
|
||||
uniquely identify the type. A file may have multiple .debug_types sections,
|
||||
or the type may come from a DWO file. Furthermore, while it's more logical
|
||||
to use per_cu->section+offset, with Fission the section with the data is in
|
||||
the DWO file but we don't know that section at the point we need it.
|
||||
We have to use something in dwarf2_per_cu_data (or the pointer to it)
|
||||
because we can enter the lookup routine, get_die_type_at_offset, from
|
||||
outside this file, and thus won't necessarily have PER_CU->cu.
|
||||
Fortunately, PER_CU is stable for the life of the objfile. */
|
||||
gdb::unordered_map<per_cu_and_offset, type *, per_cu_and_offset_hash>
|
||||
die_type_hash;
|
||||
|
||||
/* Table containing line_header indexed by offset and offset_in_dwz. */
|
||||
htab_up line_header_hash;
|
||||
|
Loading…
Reference in New Issue
Block a user