[13/38] Remove DWARF queue-related globals
Commit Message
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-01-22 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 | 17 +++++++++
gdb/dwarf2/read.c | 96 ++++++++++++++++++-----------------------------
gdb/dwarf2/read.h | 23 ++++++++++++
3 files changed, 76 insertions(+), 60 deletions(-)
@@ -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
@@ -1818,35 +1806,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. */
@@ -2582,7 +2573,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
@@ -9188,20 +9179,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.
@@ -9256,8 +9235,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,
@@ -9267,15 +9244,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];
@@ -9302,21 +9281,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",
@@ -20,6 +20,7 @@
#ifndef DWARF2READ_H
#define DWARF2READ_H
+#include <queue>
#include <unordered_map>
#include "dwarf2/index-cache.h"
#include "dwarf2/section.h"
@@ -43,10 +44,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. */
@@ -214,6 +234,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. */