[10/13,gdb/symtab] Resolve deferred entries, intra-shard case

Message ID 20231002125051.29911-11-tdevries@suse.de
State Superseded
Headers
Series Fix gdb.cp/breakpoint-locs.exp |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed

Commit Message

Tom de Vries Oct. 2, 2023, 12:50 p.m. UTC
  In a previous patch we've solved the generic case of handling deferred
entries.

Now add an optimization that handles deferred entries with an intra-shard
dependency in the parallel for.

By using "maint set worker-threads 0" we force a single shard, and the
resulting debug_handle_deferred_entries is:
...
$ gdb -q -batch -iex "maint set worker-threads 0" forward-spec
handle_deferred_entries, intra-shard case
parent map
  0x00000000000000ca 0x2934500 (deferred)
  0x00000000000000cb 0x0
  0x00000000000000dd 0x37d79d0 (0xdc)
  0x00000000000000e8 0x0
parent valid map
  0x000000000000002e 0x1
  0x0000000000000045 0x0
  0x0000000000000062 0x1
  0x0000000000000084 0x0
  0x00000000000000ca 0x1
  0x00000000000000e9 0x0
  0x0000000000000121 0x1
  0x00000000000002ac 0x0
Resolve deferred: 0xca -> 0xe0: 0xdc
handle_deferred_entries, inter-shard case
  0x00000000000000ca 0x2934500 (deferred)
  0x00000000000000cb 0x0
  0x00000000000000dd 0x37d79d0 (0xdc)
  0x00000000000000e8 0x0
...

Tested on x86_64-linux.
---
 gdb/dwarf2/cooked-index.c | 59 +++++++++++++++++++++++++++++++++++++--
 gdb/dwarf2/cooked-index.h |  7 +++++
 gdb/dwarf2/read.c         | 10 +++++++
 3 files changed, 74 insertions(+), 2 deletions(-)
  

Patch

diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 478c66a24c4..f09ab594d8f 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -452,6 +452,7 @@  cooked_index_shard::wait (bool allow_quit) const
 cooked_index::cooked_index (vec_type &&vec)
   : m_vector (std::move (vec))
 {
+  /* Handle deferred entries, inter-cu case.  */
   handle_deferred_entries ();
 
   for (auto &idx : m_vector)
@@ -662,6 +663,57 @@  const static bool debug_handle_deferred_entries = false;
 
 /* See cooked-index.h.  */
 
+const cooked_index_entry *
+cooked_index_shard::find_parent_deferred_entry
+  (const cooked_index_shard::deferred_entry &entry) const
+{
+  const cooked_index_entry *parent_entry = nullptr;
+
+  auto res = find_parent (entry.spec_offset);
+  if (res != nullptr)
+    {
+      /* We currently assume that no derrered entry is
+	 dependent on another deferred entry.  If that turns
+	 out to be not the case, detect it here.  */
+      gdb_assert (res != &parent_map::deferred);
+      parent_entry = res;
+    }
+
+  return parent_entry;
+}
+
+/* See cooked-index.h.  */
+
+void
+cooked_index_shard::handle_deferred_entries ()
+{
+
+  if (debug_handle_deferred_entries)
+    {
+      gdb_printf ("handle_deferred_entries, intra-shard case\n");
+      gdb_printf ("parent map\n");
+      m_die_range_map->dump ();
+      gdb_printf ("parent valid map\n");
+      addrmap_dump (m_die_range_map_valid, gdb_stdlog, nullptr, nullptr);
+    }
+
+  for (auto it = m_deferred_entries->begin (); it != m_deferred_entries->end (); )
+    {
+      const deferred_entry & deferred_entry = *it;
+      if (!parent_valid (deferred_entry.spec_offset))
+	{
+	  it++;
+	  continue;
+	}
+      const cooked_index_entry *parent_entry
+	= find_parent_deferred_entry (deferred_entry);
+      resolve_deferred_entry (deferred_entry, parent_entry);
+      it = m_deferred_entries->erase (it);
+    }
+}
+
+/* See cooked-index.h.  */
+
 const cooked_index_entry *
 cooked_index_shard::resolve_deferred_entry
   (const deferred_entry &de, const cooked_index_entry *parent_entry)
@@ -713,8 +765,11 @@  void
 cooked_index::handle_deferred_entries ()
 {
   if (debug_handle_deferred_entries)
-    for (auto &shard : m_vector)
-      shard->m_die_range_map->dump ();
+    {
+      gdb_printf ("handle_deferred_entries, inter-shard case\n");
+      for (auto &shard : m_vector)
+	shard->m_die_range_map->dump ();
+    }
 
   for (auto &shard : m_vector)
     for (const auto &deferred_entry : *shard->m_deferred_entries)
diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h
index 064944aa09a..b36d5247653 100644
--- a/gdb/dwarf2/cooked-index.h
+++ b/gdb/dwarf2/cooked-index.h
@@ -396,6 +396,13 @@  class cooked_index_shard
   const cooked_index_entry *resolve_deferred_entry
     (const deferred_entry &entry, const cooked_index_entry *parent_entry);
 
+  /* Find the parent entry for deferred_entry ENTRY.  */
+  const cooked_index_entry *find_parent_deferred_entry
+    (const cooked_index_shard::deferred_entry &entry) const;
+
+  /* Create cooked_index_entries for the deferred entries.  */
+  void handle_deferred_entries ();
+
   /* Mark parents in range [START, END] as valid .  */
   void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
   {
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index b5d9103e4b2..fca83aed5f7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -4689,6 +4689,12 @@  class cooked_index_storage
     m_index->defer_entry (de);
   }
 
+  /* Handle deferred entries, intra-cu case.  */
+  void handle_deferred_entries ()
+  {
+    m_index->handle_deferred_entries ();
+  }
+
   /* Mark parents in range [START, END] as valid .  */
   void set_parent_valid (CORE_ADDR start, CORE_ADDR end)
   {
@@ -5181,6 +5187,10 @@  dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
 		errors.push_back (std::move (except));
 	      }
 	  }
+
+	/* Handle deferred entries, intra-cu case.  */
+	thread_storage.handle_deferred_entries ();
+
 	return result_type (thread_storage.release (), std::move (errors));
       }, task_size);