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:
parent
3e22507450
commit
39856def4f
|
@ -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.
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue