mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-23 13:21:43 +08:00
gdb/symtab: Eliminate deferred_entry
Currently cooked_index entry creation is either: - done immediately if the parent_entry is known, or - deferred if the parent_entry is not yet known, and done later while resolving the deferred entries. Instead, create all cooked_index entries immediately, and keep track of which entries have a parent_entry that needs resolving later using the new IS_PARENT_DEFERRED flag. Tested on x86_64-linux. Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
parent
850fce8baf
commit
42bd6b5fd4
@ -51,6 +51,7 @@ to_string (cooked_index_flag flags)
|
||||
MAP_ENUM_FLAG (IS_ENUM_CLASS),
|
||||
MAP_ENUM_FLAG (IS_LINKAGE),
|
||||
MAP_ENUM_FLAG (IS_TYPE_DECLARATION),
|
||||
MAP_ENUM_FLAG (IS_PARENT_DEFERRED),
|
||||
};
|
||||
|
||||
return flags.to_string (mapping);
|
||||
@ -248,7 +249,7 @@ cooked_index_entry::write_scope (struct obstack *storage,
|
||||
cooked_index_entry *
|
||||
cooked_index_shard::add (sect_offset die_offset, enum dwarf_tag tag,
|
||||
cooked_index_flag flags, const char *name,
|
||||
const cooked_index_entry *parent_entry,
|
||||
cooked_index_entry_ref parent_entry,
|
||||
dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
cooked_index_entry *result = create (die_offset, tag, flags, name,
|
||||
@ -259,7 +260,8 @@ cooked_index_shard::add (sect_offset die_offset, enum dwarf_tag tag,
|
||||
implicit "main" discovery. */
|
||||
if ((flags & IS_MAIN) != 0)
|
||||
m_main = result;
|
||||
else if (parent_entry == nullptr
|
||||
else if ((flags & IS_PARENT_DEFERRED) == 0
|
||||
&& parent_entry.resolved == nullptr
|
||||
&& m_main == nullptr
|
||||
&& language_may_use_plain_main (per_cu->lang ())
|
||||
&& strcmp (name, "main") == 0)
|
||||
@ -638,7 +640,10 @@ cooked_index::dump (gdbarch *arch)
|
||||
gdb_printf (" flags: %s\n", to_string (entry->flags).c_str ());
|
||||
gdb_printf (" DIE offset: %s\n", sect_offset_str (entry->die_offset));
|
||||
|
||||
if (entry->get_parent () != nullptr)
|
||||
if ((entry->flags & IS_PARENT_DEFERRED) != 0)
|
||||
gdb_printf (" parent: deferred (%" PRIx64 ")\n",
|
||||
entry->get_deferred_parent ());
|
||||
else if (entry->get_parent () != nullptr)
|
||||
gdb_printf (" parent: ((cooked_index_entry *) %p) [%s]\n",
|
||||
entry->get_parent (), entry->get_parent ()->name);
|
||||
else
|
||||
|
@ -48,6 +48,7 @@
|
||||
struct dwarf2_per_cu_data;
|
||||
struct dwarf2_per_bfd;
|
||||
struct index_cache_store_context;
|
||||
struct cooked_index_entry;
|
||||
|
||||
/* Flags that describe an entry in the index. */
|
||||
enum cooked_index_flag_enum : unsigned char
|
||||
@ -63,9 +64,30 @@ enum cooked_index_flag_enum : unsigned char
|
||||
/* True if this entry is just for the declaration of a type, not the
|
||||
definition. */
|
||||
IS_TYPE_DECLARATION = 16,
|
||||
/* True is parent_entry.deferred has a value rather than parent_entry
|
||||
.resolved. */
|
||||
IS_PARENT_DEFERRED = 32,
|
||||
};
|
||||
DEF_ENUM_FLAGS_TYPE (enum cooked_index_flag_enum, cooked_index_flag);
|
||||
|
||||
/* Type representing either a resolved or deferred cooked_index_entry. */
|
||||
|
||||
union cooked_index_entry_ref
|
||||
{
|
||||
cooked_index_entry_ref (CORE_ADDR deferred_)
|
||||
{
|
||||
deferred = deferred_;
|
||||
}
|
||||
|
||||
cooked_index_entry_ref (const cooked_index_entry *resolved_)
|
||||
{
|
||||
resolved = resolved_;
|
||||
}
|
||||
|
||||
const cooked_index_entry *resolved;
|
||||
CORE_ADDR deferred;
|
||||
};
|
||||
|
||||
/* Return a string representation of FLAGS. */
|
||||
|
||||
std::string to_string (cooked_index_flag flags);
|
||||
@ -88,7 +110,7 @@ struct cooked_index_entry : public allocate_on_obstack
|
||||
{
|
||||
cooked_index_entry (sect_offset die_offset_, enum dwarf_tag tag_,
|
||||
cooked_index_flag flags_, const char *name_,
|
||||
const cooked_index_entry *parent_entry_,
|
||||
cooked_index_entry_ref parent_entry_,
|
||||
dwarf2_per_cu_data *per_cu_)
|
||||
: name (name_),
|
||||
tag (tag_),
|
||||
@ -223,13 +245,30 @@ struct cooked_index_entry : public allocate_on_obstack
|
||||
/* Set parent entry to PARENT. */
|
||||
void set_parent (const cooked_index_entry *parent)
|
||||
{
|
||||
m_parent_entry = parent;
|
||||
gdb_assert ((flags & IS_PARENT_DEFERRED) == 0);
|
||||
m_parent_entry.resolved = parent;
|
||||
}
|
||||
|
||||
/* Resolve deferred parent entry to PARENT. */
|
||||
void resolve_parent (const cooked_index_entry *parent)
|
||||
{
|
||||
gdb_assert ((flags & IS_PARENT_DEFERRED) != 0);
|
||||
flags = flags & ~IS_PARENT_DEFERRED;
|
||||
m_parent_entry.resolved = parent;
|
||||
}
|
||||
|
||||
/* Return parent entry. */
|
||||
const cooked_index_entry *get_parent () const
|
||||
{
|
||||
return m_parent_entry;
|
||||
gdb_assert ((flags & IS_PARENT_DEFERRED) == 0);
|
||||
return m_parent_entry.resolved;
|
||||
}
|
||||
|
||||
/* Return deferred parent entry. */
|
||||
CORE_ADDR get_deferred_parent () const
|
||||
{
|
||||
gdb_assert ((flags & IS_PARENT_DEFERRED) != 0);
|
||||
return m_parent_entry.deferred;
|
||||
}
|
||||
|
||||
/* The name as it appears in DWARF. This always points into one of
|
||||
@ -260,7 +299,7 @@ struct cooked_index_entry : public allocate_on_obstack
|
||||
/* The parent entry. This is NULL for top-level entries.
|
||||
Otherwise, it points to the parent entry, such as a namespace or
|
||||
class. */
|
||||
const cooked_index_entry *m_parent_entry;
|
||||
cooked_index_entry_ref m_parent_entry;
|
||||
};
|
||||
|
||||
class cooked_index;
|
||||
@ -283,7 +322,7 @@ class cooked_index_shard
|
||||
cooked_index_entry *add (sect_offset die_offset, enum dwarf_tag tag,
|
||||
cooked_index_flag flags,
|
||||
const char *name,
|
||||
const cooked_index_entry *parent_entry,
|
||||
cooked_index_entry_ref parent_entry,
|
||||
dwarf2_per_cu_data *per_cu);
|
||||
|
||||
/* Install a new fixed addrmap from the given mutable addrmap. */
|
||||
@ -334,7 +373,7 @@ class cooked_index_shard
|
||||
enum dwarf_tag tag,
|
||||
cooked_index_flag flags,
|
||||
const char *name,
|
||||
const cooked_index_entry *parent_entry,
|
||||
cooked_index_entry_ref parent_entry,
|
||||
dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
return new (&m_storage) cooked_index_entry (die_offset, tag, flags,
|
||||
@ -399,7 +438,7 @@ class cooked_index_storage
|
||||
cooked_index_entry *add (sect_offset die_offset, enum dwarf_tag tag,
|
||||
cooked_index_flag flags,
|
||||
const char *name,
|
||||
const cooked_index_entry *parent_entry,
|
||||
cooked_index_entry_ref parent_entry,
|
||||
dwarf2_per_cu_data *per_cu)
|
||||
{
|
||||
return m_index->add (die_offset, tag, flags, name, parent_entry, per_cu);
|
||||
|
@ -4552,16 +4552,6 @@ class cooked_indexer
|
||||
understand this. */
|
||||
addrmap_mutable m_die_range_map;
|
||||
|
||||
/* A single deferred entry. */
|
||||
struct deferred_entry
|
||||
{
|
||||
sect_offset die_offset;
|
||||
const char *name;
|
||||
CORE_ADDR spec_offset;
|
||||
dwarf_tag tag;
|
||||
cooked_index_flag flags;
|
||||
};
|
||||
|
||||
/* The generated DWARF can sometimes have the declaration for a
|
||||
method in a class (or perhaps namespace) scope, with the
|
||||
definition appearing outside this scope... just one of the many
|
||||
@ -4569,7 +4559,7 @@ class cooked_indexer
|
||||
defer certain entries until the end of scanning, at which point
|
||||
we'll know the containing context of all the DIEs that we might
|
||||
have scanned. This vector stores these deferred entries. */
|
||||
std::vector<deferred_entry> m_deferred_entries;
|
||||
std::vector<cooked_index_entry *> m_deferred_entries;
|
||||
};
|
||||
|
||||
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
|
||||
@ -16540,17 +16530,21 @@ cooked_indexer::index_dies (cutu_reader *reader,
|
||||
name = nullptr;
|
||||
}
|
||||
|
||||
const cooked_index_entry *this_entry = nullptr;
|
||||
cooked_index_entry *this_entry = nullptr;
|
||||
if (name != nullptr)
|
||||
{
|
||||
if (defer != 0)
|
||||
m_deferred_entries.push_back ({
|
||||
this_die, name, defer, abbrev->tag, flags
|
||||
});
|
||||
{
|
||||
this_entry
|
||||
= m_index_storage->add (this_die, abbrev->tag,
|
||||
flags | IS_PARENT_DEFERRED, name,
|
||||
defer, m_per_cu);
|
||||
m_deferred_entries.push_back (this_entry);
|
||||
}
|
||||
else
|
||||
this_entry = m_index_storage->add (this_die, abbrev->tag, flags,
|
||||
name, this_parent_entry,
|
||||
m_per_cu);
|
||||
this_entry
|
||||
= m_index_storage->add (this_die, abbrev->tag, flags, name,
|
||||
this_parent_entry, m_per_cu);
|
||||
}
|
||||
|
||||
if (linkage_name != nullptr)
|
||||
@ -16651,10 +16645,9 @@ cooked_indexer::make_index (cutu_reader *reader)
|
||||
|
||||
for (const auto &entry : m_deferred_entries)
|
||||
{
|
||||
void *obj = m_die_range_map.find (entry.spec_offset);
|
||||
void *obj = m_die_range_map.find (entry->get_deferred_parent ());
|
||||
cooked_index_entry *parent = static_cast<cooked_index_entry *> (obj);
|
||||
m_index_storage->add (entry.die_offset, entry.tag, entry.flags,
|
||||
entry.name, parent, m_per_cu);
|
||||
entry->resolve_parent (parent);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user