Remove DWARF queue-related globals
authorTom Tromey <tom@tromey.com>
Sat, 8 Feb 2020 20:40:54 +0000 (13:40 -0700)
committerTom Tromey <tom@tromey.com>
Sat, 8 Feb 2020 20:41:00 +0000 (13:41 -0700)
This removes some queue-related globals from the DWARF reader, in
favor of a new member on dwarf2_per_objfile.  Globals must be avoided
in this code, because they prevent multi-threading the reader.

gdb/ChangeLog
2020-02-08  Tom Tromey  <tom@tromey.com>

* dwarf2/read.h (struct dwarf2_queue_item): Move from
dwarf2/read.c.  Remove "next" member.  Add constructor ntad
destructor.
(struct dwarf2_per_objfile) <queue>: New member.
* dwarf2/read.c (struct dwarf2_queue_item): Move to
dwarf2/read.h.
(dwarf2_queue, dwarf2_queue_tail): Remove.
(class dwarf2_queue_guard): Add parameter to constructor.  Use
DISABLE_COPY_AND_ASSIGN.
<m_per_objfile>: New member.
<~dwarf2_queue_guard>: Rewrite.
(dw2_do_instantiate_symtab, queue_comp_unit, process_queue):
Update.
(~dwarf2_queue_item): New.

Change-Id: Ied1f6ff3691352a66c4709b0b2cba0588f49f79a

gdb/ChangeLog
gdb/dwarf2/read.c
gdb/dwarf2/read.h

index b08ca9868a47cd71b21fe7034eedac7f42e443d2..cae5468ba766468865ed1c9e50be081c454dbc22 100644 (file)
@@ -1,3 +1,20 @@
+2020-02-08  Tom Tromey  <tom@tromey.com>
+
+       * dwarf2/read.h (struct dwarf2_queue_item): Move from
+       dwarf2/read.c.  Remove "next" member.  Add constructor ntad
+       destructor.
+       (struct dwarf2_per_objfile) <queue>: New member.
+       * dwarf2/read.c (struct dwarf2_queue_item): Move to
+       dwarf2/read.h.
+       (dwarf2_queue, dwarf2_queue_tail): Remove.
+       (class dwarf2_queue_guard): Add parameter to constructor.  Use
+       DISABLE_COPY_AND_ASSIGN.
+       <m_per_objfile>: New member.
+       <~dwarf2_queue_guard>: Rewrite.
+       (dw2_do_instantiate_symtab, queue_comp_unit, process_queue):
+       Update.
+       (~dwarf2_queue_item): New.
+
 2020-02-08  Tom Tromey  <tom@tromey.com>
 
        * dwarf2/read.c (struct die_info) <has_children>: New member.
index 9a1f7957feb24eaf0e9d9348eed0b49de9405349..527ed2e4221aa1eb32aa4c81e15c8f0ee5e6d059 100644 (file)
@@ -1335,18 +1335,6 @@ struct field_info
     std::vector<struct decl_field> nested_types_list;
   };
 
-/* One item on the queue of compilation units to read in full symbols
-   for.  */
-struct dwarf2_queue_item
-{
-  struct dwarf2_per_cu_data *per_cu;
-  enum language pretend_language;
-  struct dwarf2_queue_item *next;
-};
-
-/* The current queue.  */
-static struct dwarf2_queue_item *dwarf2_queue, *dwarf2_queue_tail;
-
 /* Loaded secondary compilation units are kept in memory until they
    have not been referenced for the processing of this many
    compilation units.  Set this to zero to disable caching.  Cache
@@ -1813,35 +1801,38 @@ static struct type *dwarf2_per_cu_int_type
 class dwarf2_queue_guard
 {
 public:
-  dwarf2_queue_guard () = default;
+  explicit dwarf2_queue_guard (dwarf2_per_objfile *per_objfile)
+    : m_per_objfile (per_objfile)
+  {
+  }
 
   /* Free any entries remaining on the queue.  There should only be
      entries left if we hit an error while processing the dwarf.  */
   ~dwarf2_queue_guard ()
   {
-    struct dwarf2_queue_item *item, *last;
-
-    item = dwarf2_queue;
-    while (item)
-      {
-       /* Anything still marked queued is likely to be in an
-          inconsistent state, so discard it.  */
-       if (item->per_cu->queued)
-         {
-           if (item->per_cu->cu != NULL)
-             free_one_cached_comp_unit (item->per_cu);
-           item->per_cu->queued = 0;
-         }
+    /* Ensure that no memory is allocated by the queue.  */
+    std::queue<dwarf2_queue_item> empty;
+    std::swap (m_per_objfile->queue, empty);
+  }
 
-       last = item;
-       item = item->next;
-       xfree (last);
-      }
+  DISABLE_COPY_AND_ASSIGN (dwarf2_queue_guard);
 
-    dwarf2_queue = dwarf2_queue_tail = NULL;
-  }
+private:
+  dwarf2_per_objfile *m_per_objfile;
 };
 
+dwarf2_queue_item::~dwarf2_queue_item ()
+{
+  /* Anything still marked queued is likely to be in an
+     inconsistent state, so discard it.  */
+  if (per_cu->queued)
+    {
+      if (per_cu->cu != NULL)
+       free_one_cached_comp_unit (per_cu);
+      per_cu->queued = 0;
+    }
+}
+
 /* The return type of find_file_and_directory.  Note, the enclosed
    string pointers are only valid while this object is valid.  */
 
@@ -2577,7 +2568,7 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
   /* The destructor of dwarf2_queue_guard frees any entries left on
      the queue.  After this point we're guaranteed to leave this function
      with the dwarf queue empty.  */
-  dwarf2_queue_guard q_guard;
+  dwarf2_queue_guard q_guard (dwarf2_per_objfile);
 
   if (dwarf2_per_objfile->using_index
       ? per_cu->v.quick->compunit_symtab == NULL
@@ -9161,20 +9152,8 @@ static void
 queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
                 enum language pretend_language)
 {
-  struct dwarf2_queue_item *item;
-
   per_cu->queued = 1;
-  item = XNEW (struct dwarf2_queue_item);
-  item->per_cu = per_cu;
-  item->pretend_language = pretend_language;
-  item->next = NULL;
-
-  if (dwarf2_queue == NULL)
-    dwarf2_queue = item;
-  else
-    dwarf2_queue_tail->next = item;
-
-  dwarf2_queue_tail = item;
+  per_cu->dwarf2_per_objfile->queue.emplace (per_cu, pretend_language);
 }
 
 /* If PER_CU is not yet queued, add it to the queue.
@@ -9229,8 +9208,6 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
 static void
 process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 {
-  struct dwarf2_queue_item *item, *next_item;
-
   if (dwarf_read_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
@@ -9240,15 +9217,17 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   /* The queue starts out with one item, but following a DIE reference
      may load a new CU, adding it to the end of the queue.  */
-  for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item)
+  while (!dwarf2_per_objfile->queue.empty ())
     {
+      dwarf2_queue_item &item = dwarf2_per_objfile->queue.front ();
+
       if ((dwarf2_per_objfile->using_index
-          ? !item->per_cu->v.quick->compunit_symtab
-          : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin))
+          ? !item.per_cu->v.quick->compunit_symtab
+          : (item.per_cu->v.psymtab && !item.per_cu->v.psymtab->readin))
          /* Skip dummy CUs.  */
-         && item->per_cu->cu != NULL)
+         && item.per_cu->cu != NULL)
        {
-         struct dwarf2_per_cu_data *per_cu = item->per_cu;
+         struct dwarf2_per_cu_data *per_cu = item.per_cu;
          unsigned int debug_print_threshold;
          char buf[100];
 
@@ -9275,21 +9254,18 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
            fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
 
          if (per_cu->is_debug_types)
-           process_full_type_unit (per_cu, item->pretend_language);
+           process_full_type_unit (per_cu, item.pretend_language);
          else
-           process_full_comp_unit (per_cu, item->pretend_language);
+           process_full_comp_unit (per_cu, item.pretend_language);
 
          if (dwarf_read_debug >= debug_print_threshold)
            fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
        }
 
-      item->per_cu->queued = 0;
-      next_item = item->next;
-      xfree (item);
+      item.per_cu->queued = 0;
+      dwarf2_per_objfile->queue.pop ();
     }
 
-  dwarf2_queue_tail = NULL;
-
   if (dwarf_read_debug)
     {
       fprintf_unfiltered (gdb_stdlog, "Done expanding symtabs of %s.\n",
index 46256d0e14ddf5f2beda58636a5183381117e1ab..13b5878ca23759c3cfe3be315170774bc3bce2bd 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef DWARF2READ_H
 #define DWARF2READ_H
 
+#include <queue>
 #include <unordered_map>
 #include "dwarf2/index-cache.h"
 #include "dwarf2/section.h"
@@ -44,10 +45,29 @@ struct tu_stats
 };
 
 struct dwarf2_debug_sections;
+struct dwarf2_per_cu_data;
 struct mapped_index;
 struct mapped_debug_names;
 struct signatured_type;
 
+/* One item on the queue of compilation units to read in full symbols
+   for.  */
+struct dwarf2_queue_item
+{
+  dwarf2_queue_item (dwarf2_per_cu_data *cu, enum language lang)
+    : per_cu (cu),
+      pretend_language (lang)
+  {
+  }
+
+  ~dwarf2_queue_item ();
+
+  DISABLE_COPY_AND_ASSIGN (dwarf2_queue_item);
+
+  struct dwarf2_per_cu_data *per_cu;
+  enum language pretend_language;
+};
+
 /* Collection of data recorded per objfile.
    This hangs off of dwarf2_objfile_data_key.  */
 
@@ -215,6 +235,9 @@ public:
   std::unordered_map<sect_offset, std::vector<sect_offset>,
                     gdb::hash_enum<sect_offset>>
     abstract_to_concrete;
+
+  /* CUs that are queued to be read.  */
+  std::queue<dwarf2_queue_item> queue;
 };
 
 /* Get the dwarf2_per_objfile associated to OBJFILE.  */