}
};
-/* See read.h. */
-
-std::uint64_t
-stmt_list_hash_hash::operator() (const stmt_list_hash &key) const noexcept
-{
- std::uint64_t v = 0;
-
- if (key.dwo_unit != nullptr)
- v += ankerl::unordered_dense::hash<dwo_file *> () (key.dwo_unit->dwo_file);
-
- v += (ankerl::unordered_dense::hash<std::uint64_t> ()
- (to_underlying (key.line_sect_off)));
- return v;
-}
-
-/* See read.h. */
-
-bool
-stmt_list_hash::operator== (const stmt_list_hash &rhs) const noexcept
-{
- if ((this->dwo_unit != nullptr) != (rhs.dwo_unit != nullptr))
- return false;
-
- if (this->dwo_unit != nullptr
- && this->dwo_unit->dwo_file != rhs.dwo_unit->dwo_file)
- return false;
-
- return this->line_sect_off == rhs.line_sect_off;
-}
-
/* Read in CU (dwarf2_cu object) for PER_CU in the context of PER_OBJFILE. This
function is unrelated to symtabs, symtab would have to be created afterwards.
You should call age_cached_comp_units after processing the CU.
line_header_up lh;
file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
- std::optional<stmt_list_hash> stmt_list_hash_key;
+ std::optional<section_and_offset> stmt_list_key;
attribute *attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
if (attr != nullptr && attr->form_is_unsigned ())
/* We may have already read in this line header (TU line header sharing).
If we have we're done. */
- stmt_list_hash_key = {cu->dwo_unit, line_offset};
+ stmt_list_key = {get_debug_line_section (cu), line_offset};
- if (auto it = per_bfd->quick_file_names_table.find (*stmt_list_hash_key);
+ if (auto it = per_bfd->quick_file_names_table.find (*stmt_list_key);
it != per_bfd->quick_file_names_table.end ())
{
this_cu->file_names = it->second;
auto *qfn = XOBNEW (&per_bfd->obstack, quick_file_names);
/* There may not be a DW_AT_stmt_list. */
- if (stmt_list_hash_key.has_value ())
- per_bfd->quick_file_names_table.emplace (*stmt_list_hash_key, qfn);
+ if (stmt_list_key.has_value ())
+ per_bfd->quick_file_names_table.emplace (*stmt_list_key, qfn);
std::vector<const char *> include_names;
if (lh != nullptr)
/* Get the type unit group key for type unit CU. STMT_LIST is a DW_AT_stmt_list
attribute. */
-static stmt_list_hash
+static section_and_offset
get_type_unit_group_key (struct dwarf2_cu *cu, const struct attribute *stmt_list)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
++tu_stats->nr_stmt_less_type_units;
}
- return {cu->dwo_unit, static_cast<sect_offset> (line_offset)};
+ return {get_debug_line_section (cu), static_cast<sect_offset> (line_offset)};
}
/* A subclass of cooked_index_worker that handles scanning
type_unit_group_unshareable *
dwarf2_per_objfile::get_type_unit_group_unshareable
- (stmt_list_hash tu_group_key)
+ (section_and_offset tu_group_key)
{
auto [it, inserted] = m_type_units.emplace (tu_group_key, nullptr);
};
-/* 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. */
Zero is otherwise not a valid section offset. */
sect_offset type_offset_in_section {};
- /* Type units are grouped by their DW_AT_stmt_list entry so that they
- 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;
+ /* Type units are grouped by their DW_AT_stmt_list entry (i.e. which line
+ table they use) so that they can share them. This is the key of the group
+ this type unit is part of. */
+ std::optional<section_and_offset> type_unit_group_key;
/* Containing DWO unit.
This field is valid iff per_cu.reading_dwo_directly. */
sorted all the TUs into "type unit groups", grouped by their
DW_AT_stmt_list value. Therefore the only sharing done here is with a
CU and its associated TU group if there is one. */
- gdb::unordered_map<stmt_list_hash, quick_file_names *, stmt_list_hash_hash>
- quick_file_names_table;
+ unordered_section_and_offset_map<quick_file_names *> quick_file_names_table;
/* If we loaded the index from an external file, this contains the
resources associated to the open file, memory mapping, etc. */
/* 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
- (stmt_list_hash tu_group_key);
+ (section_and_offset tu_group_key);
struct type *get_type_for_signatured_type (signatured_type *sig_type) const;
/* Map from a type unit group key to the corresponding unshared
structure. */
- gdb::unordered_map<stmt_list_hash, type_unit_group_unshareable_up,
- stmt_list_hash_hash>
+ unordered_section_and_offset_map<type_unit_group_unshareable_up>
m_type_units;
/* Map from signatured types to the corresponding struct type. */
#ifndef GDB_DWARF2_SECTION_H
#define GDB_DWARF2_SECTION_H
+#include "gdbsupport/unordered_map.h"
+
/* A descriptor for dwarf sections.
S.ASECTION, SIZE are typically initialized when the objfile is first
sect_offset offset;
};
+/* Hash function for section_and_offset. */
+
+struct section_and_offset_hash
+{
+ template <typename T>
+ using hash = ankerl::unordered_dense::hash<T>;
+ using is_avalanching = void;
+
+ std::uint64_t operator() (const section_and_offset &sao) const noexcept
+ {
+ return (hash<const dwarf2_section_info *> () (sao.section)
+ + hash<sect_offset> () (sao.offset));
+ }
+};
+
+/* Equality function for section_and_offset. */
+
+struct section_and_offset_eq
+{
+ bool operator() (const section_and_offset &a,
+ const section_and_offset &b) const noexcept
+ { return a.section == b.section && a.offset == b.offset; }
+};
+
+template<typename Value>
+using unordered_section_and_offset_map
+ = gdb::unordered_map<section_and_offset, Value,
+ section_and_offset_hash, section_and_offset_eq>;
+
#endif /* GDB_DWARF2_SECTION_H */