Remove DWARF queue-related globals

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
This commit is contained in:
Tom Tromey 2020-02-08 13:40:54 -07:00
parent 3e22507450
commit 39856def4f
3 changed files with 77 additions and 61 deletions

View 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.

View 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;
}
last = item;
item = item->next;
xfree (last);
}
dwarf2_queue = dwarf2_queue_tail = NULL;
/* Ensure that no memory is allocated by the queue. */
std::queue<dwarf2_queue_item> empty;
std::swap (m_per_objfile->queue, empty);
}
DISABLE_COPY_AND_ASSIGN (dwarf2_queue_guard);
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",

View 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. */