]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/symtab: Eliminate deferred_entry
authorTom de Vries <tdevries@suse.de>
Wed, 10 Jan 2024 09:06:35 +0000 (10:06 +0100)
committerTom de Vries <tdevries@suse.de>
Wed, 10 Jan 2024 09:06:35 +0000 (10:06 +0100)
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>
gdb/dwarf2/cooked-index.c
gdb/dwarf2/cooked-index.h
gdb/dwarf2/read.c

index a4a400e8eae0a4f0dcdf5dee1980b1c21392d136..c221b8979c0bfe901e7116551778688bdfaf5dfc 100644 (file)
@@ -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
index fa0807a2cb0364919e190d32a9684b7cdccfd744..4c3b2901a0613b47142769ff29ca627ee587a3eb 100644 (file)
@@ -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 @@ private:
   /* 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 @@ public:
   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 @@ private:
                              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 @@ public:
   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);
index bfbf094b61c91224cb5d223dcdbdff0165a55956..76dbeb8d536a139325c68b37ace4927722eac67c 100644 (file)
@@ -4552,16 +4552,6 @@ private:
      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 @@ private:
      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);
     }
 }