public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Split type_unit_group
@ 2020-05-27 15:52 Simon Marchi
  0 siblings, 0 replies; only message in thread
From: Simon Marchi @ 2020-05-27 15:52 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8adb84872b7b039c70f5448f6cf5fe7dfc79d367

commit 8adb84872b7b039c70f5448f6cf5fe7dfc79d367
Author: Tom Tromey <tom@tromey.com>
Date:   Wed May 27 11:19:09 2020 -0400

    Split type_unit_group
    
    type_unit_group has links to the compunit_symtab and other symtabs.
    However, once this object is shared across objfiles, this will no
    longer be ok.
    
    This patch introduces a new type_unit_group_unshareable and arranges to
    store a map from type unit groups to type_unit_group_unshareable objects
    in dwarf2_per_objfile.
    
    gdb/ChangeLog:
    
    YYYY-MM-DD  Tom Tromey  <tom@tromey.com>
    YYYY-MM-DD  Simon Marchi  <simon.marchi@efficios.com>
    
            * dwarf2/read.h (struct type_unit_group_unshareable): New.
            (struct dwarf2_per_objfile) <type_units>: New member.
            <get_type_unit_group_unshareable>: New method.
            * dwarf2/read.c (struct type_unit_group) <compunit_symtab,
            num_symtabs, symtabs>: Remove; move to
            type_unit_group_unshareable.
            (dwarf2_per_objfile::get_type_unit_group_unshareable): New.
            (process_full_type_unit, dwarf2_cu::setup_type_unit_groups)
            (dwarf2_cu::setup_type_unit_groups): Use type_unit_group_unshareable.
    
    Change-Id: I1fec2fab59e0ec40fee3614fc821172a469c0e41

Diff:
---
 gdb/ChangeLog     | 13 +++++++++++++
 gdb/dwarf2/read.c | 58 ++++++++++++++++++++++++++++++-------------------------
 gdb/dwarf2/read.h | 38 ++++++++++++++++++++++++++++++++++++
 3 files changed, 83 insertions(+), 26 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 64e5da9987c..f8213706243 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2020-05-27  Tom Tromey  <tom@tromey.com>
+	    Simon Marchi  <simon.marchi@efficios.com>
+
+	* dwarf2/read.h (struct type_unit_group_unshareable): New.
+	(struct dwarf2_per_objfile) <type_units>: New member.
+	<get_type_unit_group_unshareable>: New method.
+	* dwarf2/read.c (struct type_unit_group) <compunit_symtab,
+	num_symtabs, symtabs>: Remove; move to
+	type_unit_group_unshareable.
+	(dwarf2_per_objfile::get_type_unit_group_unshareable): New.
+	(process_full_type_unit, dwarf2_cu::setup_type_unit_groups)
+	(dwarf2_cu::setup_type_unit_groups): Use type_unit_group_unshareable.
+
 2020-05-27  Simon Marchi  <simon.marchi@efficios.com>
 
 	* dwarf2/read.h (struct dwarf2_per_cu_data):
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 88ab164d5b4..53def0c87eb 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -614,7 +614,9 @@ struct stmt_list_hash
 };
 
 /* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
-   an object of this type.  */
+   an object of this type.  This contains elements of type unit groups
+   that can be shared across objfiles.  The non-shareable parts are in
+   type_unit_group_unshareable.  */
 
 struct type_unit_group
 {
@@ -629,23 +631,8 @@ struct type_unit_group
      and is deleted afterwards and not used again.  */
   std::vector<signatured_type *> *tus;
 
-  /* The compunit symtab.
-     Type units in a group needn't all be defined in the same source file,
-     so we create an essentially anonymous symtab as the compunit symtab.  */
-  struct compunit_symtab *compunit_symtab;
-
   /* The data used to construct the hash key.  */
   struct stmt_list_hash hash;
-
-  /* The symbol tables for this TU (obtained from the files listed in
-     DW_AT_stmt_list).
-     WARNING: The order of entries here must match the order of entries
-     in the line header.  After the first TU using this type_unit_group, the
-     line header for the subsequent TUs is recreated from this.  This is done
-     because we need to use the same symtabs for each TU using the same
-     DW_AT_stmt_list value.  Also note that symtabs may be repeated here,
-     there's no guarantee the line header doesn't have duplicate entries.  */
-  struct symtab **symtabs;
 };
 
 /* These sections are what may appear in a (real or virtual) DWO file.  */
@@ -9628,6 +9615,21 @@ rust_union_quirks (struct dwarf2_cu *cu)
   cu->rust_unions.clear ();
 }
 
+/* See read.h.  */
+
+type_unit_group_unshareable *
+dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group)
+{
+  auto iter = this->m_type_units.find (tu_group);
+  if (iter != this->m_type_units.end ())
+    return iter->second.get ();
+
+  type_unit_group_unshareable_up uniq (new type_unit_group_unshareable);
+  type_unit_group_unshareable *result = uniq.get ();
+  this->m_type_units[tu_group] = std::move (uniq);
+  return result;
+}
+
 /* A helper function for computing the list of all symbol tables
    included by PER_CU.  */
 
@@ -9883,11 +9885,13 @@ process_full_type_unit (dwarf2_per_cu_data *per_cu,
      If this is the first TU to use this symtab, complete the construction
      of it with end_expandable_symtab.  Otherwise, complete the addition of
      this TU's symbols to the existing symtab.  */
-  if (sig_type->type_unit_group->compunit_symtab == NULL)
+  type_unit_group_unshareable *tug_unshare =
+    dwarf2_per_objfile->get_type_unit_group_unshareable (sig_type->type_unit_group);
+  if (tug_unshare->compunit_symtab == NULL)
     {
       buildsym_compunit *builder = cu->get_builder ();
       cust = builder->end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
-      sig_type->type_unit_group->compunit_symtab = cust;
+      tug_unshare->compunit_symtab = cust;
 
       if (cust != NULL)
 	{
@@ -9903,7 +9907,7 @@ process_full_type_unit (dwarf2_per_cu_data *per_cu,
   else
     {
       cu->get_builder ()->augment_type_symtab ();
-      cust = sig_type->type_unit_group->compunit_symtab;
+      cust = tug_unshare->compunit_symtab;
     }
 
   dwarf2_per_objfile->set_symtab (per_cu, cust);
@@ -11042,7 +11046,9 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
      do it again, we could fake it and just recreate the part we need
      (file name,index -> symtab mapping).  If data shows this optimization
      is useful we can do it then.  */
-  first_time = tu_group->compunit_symtab == NULL;
+  type_unit_group_unshareable *tug_unshare
+    = per_objfile->get_type_unit_group_unshareable (tu_group);
+  first_time = tug_unshare->compunit_symtab == NULL;
 
   /* We have to handle the case of both a missing DW_AT_stmt_list or bad
      debug info.  */
@@ -11058,9 +11064,9 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 	start_symtab ("", NULL, 0);
       else
 	{
-	  gdb_assert (tu_group->symtabs == NULL);
+	  gdb_assert (tug_unshare->symtabs == NULL);
 	  gdb_assert (m_builder == nullptr);
-	  struct compunit_symtab *cust = tu_group->compunit_symtab;
+	  struct compunit_symtab *cust = tug_unshare->compunit_symtab;
 	  m_builder.reset (new struct buildsym_compunit
 			   (COMPUNIT_OBJFILE (cust), "",
 			    COMPUNIT_DIRNAME (cust),
@@ -11083,7 +11089,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 	 process_full_type_unit still needs to know if this is the first
 	 time.  */
 
-      tu_group->symtabs
+      tug_unshare->symtabs
 	= XOBNEWVEC (&COMPUNIT_OBJFILE (cust)->objfile_obstack,
 		     struct symtab *, line_header->file_names_size ());
 
@@ -11106,13 +11112,13 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 	    }
 
 	  fe.symtab = b->get_current_subfile ()->symtab;
-	  tu_group->symtabs[i] = fe.symtab;
+	  tug_unshare->symtabs[i] = fe.symtab;
 	}
     }
   else
     {
       gdb_assert (m_builder == nullptr);
-      struct compunit_symtab *cust = tu_group->compunit_symtab;
+      struct compunit_symtab *cust = tug_unshare->compunit_symtab;
       m_builder.reset (new struct buildsym_compunit
 		       (COMPUNIT_OBJFILE (cust), "",
 			COMPUNIT_DIRNAME (cust),
@@ -11124,7 +11130,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
       for (i = 0; i < file_names.size (); ++i)
 	{
 	  file_entry &fe = file_names[i];
-	  fe.symtab = tu_group->symtabs[i];
+	  fe.symtab = tug_unshare->symtabs[i];
 	}
     }
 
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 0a94036f4e9..13d31a97d3d 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -47,6 +47,7 @@ struct dwarf2_per_cu_data;
 struct mapped_index;
 struct mapped_debug_names;
 struct signatured_type;
+struct type_unit_group;
 
 /* One item on the queue of compilation units to read in full symbols
    for.  */
@@ -265,6 +266,30 @@ private:
   size_t m_num_psymtabs = 0;
 };
 
+/* This is the per-objfile data associated with a type_unit_group.  */
+
+struct type_unit_group_unshareable
+{
+  /* The compunit symtab.
+     Type units in a group needn't all be defined in the same source file,
+     so we create an essentially anonymous symtab as the compunit symtab.  */
+  struct compunit_symtab *compunit_symtab = nullptr;
+
+  /* The number of symtabs from the line header.
+     The value here must match line_header.num_file_names.  */
+  unsigned int num_symtabs = 0;
+
+  /* The symbol tables for this TU (obtained from the files listed in
+     DW_AT_stmt_list).
+     WARNING: The order of entries here must match the order of entries
+     in the line header.  After the first TU using this type_unit_group, the
+     line header for the subsequent TUs is recreated from this.  This is done
+     because we need to use the same symtabs for each TU using the same
+     DW_AT_stmt_list value.  Also note that symtabs may be repeated here,
+     there's no guarantee the line header doesn't have duplicate entries.  */
+  struct symtab **symtabs = nullptr;
+};
+
 /* Collection of data recorded per objfile.
    This hangs off of dwarf2_objfile_data_key.
 
@@ -304,6 +329,11 @@ struct dwarf2_per_objfile
   /* Set the compunit_symtab associated to PER_CU.  */
   void set_symtab (const dwarf2_per_cu_data *per_cu, compunit_symtab *symtab);
 
+/* Get the type_unit_group_unshareable corresponding to TU_GROUP.  If one
+   does not exist, create it.  */
+  type_unit_group_unshareable *get_type_unit_group_unshareable
+    (type_unit_group *tu_group);
+
   /* Find an integer type SIZE_IN_BYTES bytes in size and return it.
      UNSIGNED_P controls if the integer is unsigned or not.  */
   struct type *int_type (int size_in_bytes, bool unsigned_p) const;
@@ -325,6 +355,14 @@ private:
      is indexed by dwarf2_per_cu_data::index.  A NULL value means
      that the CU/TU has not been expanded yet.  */
   std::vector<compunit_symtab *> m_symtabs;
+
+  /* Map from a type unit group to the corresponding unshared
+     structure.  */
+  typedef std::unique_ptr<type_unit_group_unshareable>
+    type_unit_group_unshareable_up;
+
+  std::unordered_map<type_unit_group *, type_unit_group_unshareable_up>
+    m_type_units;
 };
 
 /* Get the dwarf2_per_objfile associated to OBJFILE.  */


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-05-27 15:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-27 15:52 [binutils-gdb] Split type_unit_group Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).