aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/dwarf2/read.c355
-rw-r--r--gdb/dwarf2/read.h35
2 files changed, 189 insertions, 201 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index acc148a..9bc19a0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -401,7 +401,6 @@ struct dwarf2_cu
{
explicit dwarf2_cu (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile);
- ~dwarf2_cu ();
DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
@@ -468,12 +467,6 @@ public:
unit, including partial DIEs. */
auto_obstack comp_unit_obstack;
- /* When multiple dwarf2_cu structures are living in memory, this field
- chains them all together, so that they can be released efficiently.
- We will probably also want a generation counter so that most-recently-used
- compilation units are cached... */
- struct dwarf2_per_cu_data *read_in_chain = nullptr;
-
/* Backlink to our per_cu entry. */
struct dwarf2_per_cu_data *per_cu;
@@ -1553,11 +1546,6 @@ static void prepare_one_comp_unit (struct dwarf2_cu *cu,
struct die_info *comp_unit_die,
enum language pretend_language);
-static void age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
-
-static void free_one_cached_comp_unit (dwarf2_per_cu_data *target_per_cu,
- dwarf2_per_objfile *per_objfile);
-
static struct type *set_die_type (struct die_info *, struct type *,
struct dwarf2_cu *);
@@ -1581,8 +1569,6 @@ static void dwarf2_add_dependence (struct dwarf2_cu *,
static void dwarf2_mark (struct dwarf2_cu *);
-static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
-
static struct type *get_die_type_at_offset (sect_offset,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile);
@@ -1629,8 +1615,7 @@ dwarf2_queue_item::~dwarf2_queue_item ()
inconsistent state, so discard it. */
if (per_cu->queued)
{
- if (per_cu->cu != NULL)
- free_one_cached_comp_unit (per_cu, per_objfile);
+ per_objfile->remove_cu (per_cu);
per_cu->queued = 0;
}
}
@@ -1772,9 +1757,6 @@ dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
dwarf2_per_bfd::~dwarf2_per_bfd ()
{
- /* Cached DIE trees use xmalloc and the comp_unit_obstack. */
- free_cached_comp_units ();
-
for (dwarf2_per_cu_data *per_cu : all_comp_units)
per_cu->imported_symtabs_free ();
@@ -1784,21 +1766,15 @@ dwarf2_per_bfd::~dwarf2_per_bfd ()
/* Everything else should be on this->obstack. */
}
-/* See declaration. */
+/* See read.h. */
void
-dwarf2_per_bfd::free_cached_comp_units ()
+dwarf2_per_objfile::remove_all_cus ()
{
- dwarf2_per_cu_data *per_cu = read_in_chain;
- dwarf2_per_cu_data **last_chain = &read_in_chain;
- while (per_cu != NULL)
- {
- dwarf2_per_cu_data *next_cu = per_cu->cu->read_in_chain;
+ for (auto pair : m_dwarf2_cus)
+ delete pair.second;
- delete per_cu->cu;
- *last_chain = next_cu;
- per_cu = next_cu;
- }
+ m_dwarf2_cus.clear ();
}
/* A helper class that calls free_cached_comp_units on
@@ -1815,7 +1791,7 @@ public:
~free_cached_comp_units ()
{
- m_per_objfile->per_bfd->free_cached_comp_units ();
+ m_per_objfile->remove_all_cus ();
}
DISABLE_COPY_AND_ASSIGN (free_cached_comp_units);
@@ -2344,12 +2320,13 @@ load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
else
load_full_comp_unit (per_cu, per_objfile, skip_partial, language_minimal);
- if (per_cu->cu == nullptr)
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+ if (cu == nullptr)
return nullptr; /* Dummy CU. */
- dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
+ dwarf2_find_base_address (cu->dies, cu);
- return per_cu->cu;
+ return cu;
}
/* Read in the symbols for PER_CU in the context of DWARF"_PER_OBJFILE. */
@@ -2391,7 +2368,7 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
/* Age the cache, releasing compilation units that have not
been used recently. */
- age_cached_comp_units (dwarf2_per_objfile);
+ dwarf2_per_objfile->age_comp_units ();
}
/* Ensure that the symbols for PER_CU have been read in. DWARF2_PER_OBJFILE is
@@ -6427,7 +6404,7 @@ fill_in_sig_entry_from_dwo_entry (struct dwarf2_per_objfile *dwarf2_per_objfile,
/* Make sure we're not clobbering something we don't expect to. */
gdb_assert (! sig_entry->per_cu.queued);
- gdb_assert (sig_entry->per_cu.cu == NULL);
+ gdb_assert (dwarf2_per_objfile->get_cu (&sig_entry->per_cu) == NULL);
if (per_bfd->using_index)
{
gdb_assert (sig_entry->per_cu.v.quick != NULL);
@@ -6885,8 +6862,9 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
}
else
{
- /* If and existing_cu is provided, this_cu->cu must be NULL. */
- gdb_assert (this_cu->cu == NULL);
+ /* If an existing_cu is provided, a dwarf2_cu must not exist for this_cu
+ in per_objfile yet. */
+ gdb_assert (per_objfile->get_cu (this_cu) == nullptr);
m_new_cu.reset (new dwarf2_cu (this_cu, per_objfile));
cu = m_new_cu.get ();
}
@@ -6975,8 +6953,9 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
}
else
{
- /* If an existing_cu is provided, this_cu->cu must be NULL. */
- gdb_assert (this_cu->cu == NULL);
+ /* If an existing_cu is provided, a dwarf2_cu must not exist for this_cu
+ in per_objfile yet. */
+ gdb_assert (dwarf2_per_objfile->get_cu (this_cu) == nullptr);
m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
cu = m_new_cu.get ();
}
@@ -7116,16 +7095,10 @@ cutu_reader::keep ()
gdb_assert (!dummy_p);
if (m_new_cu != NULL)
{
- /* We know that m_this_cu->cu is set, since we are in the process of
- parsing the CU. */
- gdb_assert (m_this_cu->cu != nullptr);
- dwarf2_per_objfile *dwarf2_per_objfile = m_this_cu->cu->per_objfile;
-
- /* Link this CU into read_in_chain. */
- m_this_cu->cu->read_in_chain = dwarf2_per_objfile->per_bfd->read_in_chain;
- dwarf2_per_objfile->per_bfd->read_in_chain = m_this_cu;
- /* The chain owns it now. */
- m_new_cu.release ();
+ /* Save this dwarf2_cu in the per_objfile. The per_objfile owns it
+ now. */
+ dwarf2_per_objfile *per_objfile = m_new_cu->per_objfile;
+ per_objfile->set_cu (m_this_cu, m_new_cu.release ());
}
}
@@ -7163,7 +7136,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
this_cu->is_debug_types ? "type" : "comp",
sect_offset_str (this_cu->sect_off));
- gdb_assert (this_cu->cu == NULL);
+ gdb_assert (dwarf2_per_objfile->get_cu (this_cu) == nullptr);
abbrev_section = (dwo_file != NULL
? &dwo_file->sections.abbrev
@@ -7525,8 +7498,7 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
necessary because we skipped some symbols when we first
read in the compilation unit (see load_partial_dies).
This problem could be avoided, but the benefit is unclear. */
- if (this_cu->cu != NULL)
- free_one_cached_comp_unit (this_cu, per_objfile);
+ per_objfile->remove_cu (this_cu);
cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false);
@@ -7555,10 +7527,10 @@ process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
reader.comp_unit_die,
pretend_language);
- this_cu->lang = this_cu->cu->language;
+ this_cu->lang = reader.cu->language;
/* Age out any secondary CUs. */
- age_cached_comp_units (per_objfile);
+ per_objfile->age_comp_units ();
}
/* Reader function for build_type_psymtabs. */
@@ -8913,7 +8885,9 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
not queue PER_CU, just tell our caller to load its DIEs. */
if (per_cu->per_bfd->reading_partial_symbols)
{
- if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+
+ if (cu == NULL || cu->dies == NULL)
return 1;
return 0;
}
@@ -8929,9 +8903,10 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
/* If the compilation unit is already loaded, just mark it as
used. */
- if (per_cu->cu != NULL)
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+ if (cu != nullptr)
{
- per_cu->cu->last_used = 0;
+ cu->last_used = 0;
return 0;
}
@@ -8958,47 +8933,51 @@ process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile)
while (!dwarf2_per_objfile->per_bfd->queue.empty ())
{
dwarf2_queue_item &item = dwarf2_per_objfile->per_bfd->queue.front ();
+ dwarf2_per_cu_data *per_cu = item.per_cu;
- if (!dwarf2_per_objfile->symtab_set_p (item.per_cu)
- /* Skip dummy CUs. */
- && item.per_cu->cu != NULL)
+ if (!dwarf2_per_objfile->symtab_set_p (per_cu))
{
- struct dwarf2_per_cu_data *per_cu = item.per_cu;
- unsigned int debug_print_threshold;
- char buf[100];
+ dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
- if (per_cu->is_debug_types)
- {
- struct signatured_type *sig_type =
- (struct signatured_type *) per_cu;
-
- sprintf (buf, "TU %s at offset %s",
- hex_string (sig_type->signature),
- sect_offset_str (per_cu->sect_off));
- /* There can be 100s of TUs.
- Only print them in verbose mode. */
- debug_print_threshold = 2;
- }
- else
+ /* Skip dummy CUs. */
+ if (cu != nullptr)
{
- sprintf (buf, "CU at offset %s",
- sect_offset_str (per_cu->sect_off));
- debug_print_threshold = 1;
- }
+ unsigned int debug_print_threshold;
+ char buf[100];
+
+ if (per_cu->is_debug_types)
+ {
+ struct signatured_type *sig_type =
+ (struct signatured_type *) per_cu;
+
+ sprintf (buf, "TU %s at offset %s",
+ hex_string (sig_type->signature),
+ sect_offset_str (per_cu->sect_off));
+ /* There can be 100s of TUs.
+ Only print them in verbose mode. */
+ debug_print_threshold = 2;
+ }
+ else
+ {
+ sprintf (buf, "CU at offset %s",
+ sect_offset_str (per_cu->sect_off));
+ debug_print_threshold = 1;
+ }
- if (dwarf_read_debug >= debug_print_threshold)
- fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
+ if (dwarf_read_debug >= debug_print_threshold)
+ fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
- if (per_cu->is_debug_types)
- process_full_type_unit (per_cu->cu, item.pretend_language);
- else
- process_full_comp_unit (per_cu->cu, item.pretend_language);
+ if (per_cu->is_debug_types)
+ process_full_type_unit (cu, item.pretend_language);
+ else
+ process_full_comp_unit (cu, item.pretend_language);
- if (dwarf_read_debug >= debug_print_threshold)
- fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
+ if (dwarf_read_debug >= debug_print_threshold)
+ fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
+ }
}
- item.per_cu->queued = 0;
+ per_cu->queued = 0;
dwarf2_per_objfile->per_bfd->queue.pop ();
}
@@ -9074,7 +9053,8 @@ load_full_comp_unit (dwarf2_per_cu_data *this_cu,
{
gdb_assert (! this_cu->is_debug_types);
- cutu_reader reader (this_cu, per_objfile, NULL, this_cu->cu, skip_partial);
+ dwarf2_cu *existing_cu = per_objfile->get_cu (this_cu);
+ cutu_reader reader (this_cu, per_objfile, NULL, existing_cu, skip_partial);
if (reader.dummy_p)
return;
@@ -18653,7 +18633,6 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
{
struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
if (offset_in_dwz == cu->per_cu->is_dwz
@@ -18664,7 +18643,6 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
return { cu, pd };
/* We missed recording what we needed.
Load all dies and try again. */
- per_cu = cu->per_cu;
}
else
{
@@ -18676,22 +18654,26 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
sect_offset_str (cu->header.sect_off), sect_offset_str (sect_off),
bfd_get_filename (objfile->obfd));
}
- per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
- dwarf2_per_objfile);
+ dwarf2_per_cu_data *per_cu
+ = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
+ dwarf2_per_objfile);
- if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
- load_partial_comp_unit (per_cu, cu->per_objfile, nullptr);
+ cu = dwarf2_per_objfile->get_cu (per_cu);
+ if (cu == NULL || cu->partial_dies == NULL)
+ load_partial_comp_unit (per_cu, dwarf2_per_objfile, nullptr);
- per_cu->cu->last_used = 0;
- pd = per_cu->cu->find_partial_die (sect_off);
+ cu = dwarf2_per_objfile->get_cu (per_cu);
+
+ cu->last_used = 0;
+ pd = cu->find_partial_die (sect_off);
}
/* If we didn't find it, and not all dies have been loaded,
load them all and try again. */
- if (pd == NULL && per_cu->load_all_dies == 0)
+ if (pd == NULL && cu->per_cu->load_all_dies == 0)
{
- per_cu->load_all_dies = 1;
+ cu->per_cu->load_all_dies = 1;
/* This is nasty. When we reread the DIEs, somewhere up the call chain
THIS_CU->cu may already be in use. So we can't just free it and
@@ -18699,9 +18681,9 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
DIEs alone (which can still be in use, e.g. in scan_partial_symbols),
and clobber THIS_CU->cu->partial_dies with the hash table for the new
set. */
- load_partial_comp_unit (per_cu, cu->per_objfile, cu);
+ load_partial_comp_unit (cu->per_cu, dwarf2_per_objfile, cu);
- pd = per_cu->cu->find_partial_die (sect_off);
+ pd = cu->find_partial_die (sect_off);
}
if (pd == NULL)
@@ -18709,7 +18691,7 @@ find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
_("could not find partial DIE %s "
"in cache [from module %s]\n"),
sect_offset_str (sect_off), bfd_get_filename (objfile->obfd));
- return { per_cu->cu, pd };
+ return { cu, pd };
}
/* See if we can figure out if the class lives in a namespace. We do
@@ -19389,7 +19371,7 @@ dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *dwarf2_per_objfile,
unsigned int addr_index)
{
- struct dwarf2_cu *cu = per_cu->cu;
+ struct dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
gdb::optional<ULONGEST> addr_base;
int addr_size;
@@ -22230,7 +22212,7 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
if (maybe_queue_comp_unit (cu, per_cu, dwarf2_per_objfile, cu->language))
load_full_comp_unit (per_cu, dwarf2_per_objfile, false, cu->language);
- target_cu = per_cu->cu;
+ target_cu = dwarf2_per_objfile->get_cu (per_cu);
}
else if (cu->dies == NULL)
{
@@ -22290,7 +22272,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
struct dwarf2_locexpr_baton retval;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- dwarf2_cu *cu = per_cu->cu;
+ dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
if (cu == nullptr)
cu = load_cu (per_cu, dwarf2_per_objfile, false);
@@ -22375,7 +22357,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
retval.per_objfile = dwarf2_per_objfile;
retval.per_cu = cu->per_cu;
- age_cached_comp_units (dwarf2_per_objfile);
+ dwarf2_per_objfile->age_comp_units ();
return retval;
}
@@ -22431,7 +22413,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
enum bfd_endian byte_order;
struct objfile *objfile = per_objfile->objfile;
- dwarf2_cu *cu = per_cu->cu;
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
if (cu == nullptr)
cu = load_cu (per_cu, per_objfile, false);
@@ -22554,7 +22536,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
{
struct die_info *die;
- dwarf2_cu *cu = per_cu->cu;
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
if (cu == nullptr)
cu = load_cu (per_cu, per_objfile, false);
@@ -22604,7 +22586,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
language_minimal))
read_signatured_type (sig_type, dwarf2_per_objfile);
- sig_cu = sig_type->per_cu.cu;
+ sig_cu = dwarf2_per_objfile->get_cu (&sig_type->per_cu);
gdb_assert (sig_cu != NULL);
gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
temp_die.sect_off = sig_type->type_offset_in_section;
@@ -22778,11 +22760,11 @@ load_full_type_unit (dwarf2_per_cu_data *per_cu,
gdb_assert (per_cu->is_debug_types);
sig_type = (struct signatured_type *) per_cu;
- gdb_assert (per_cu->cu == NULL);
+ gdb_assert (per_objfile->get_cu (per_cu) == nullptr);
read_signatured_type (sig_type, per_objfile);
- gdb_assert (per_cu->cu != NULL);
+ gdb_assert (per_objfile->get_cu (per_cu) != nullptr);
}
/* Read in a signatured type and build its CU and DIEs.
@@ -22796,7 +22778,7 @@ read_signatured_type (signatured_type *sig_type,
struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu;
gdb_assert (per_cu->is_debug_types);
- gdb_assert (per_cu->cu == NULL);
+ gdb_assert (per_objfile->get_cu (per_cu) == nullptr);
cutu_reader reader (per_cu, per_objfile, nullptr, nullptr, false);
@@ -23503,14 +23485,6 @@ dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
producer_is_codewarrior (false),
processing_has_namespace_info (false)
{
- per_cu->cu = this;
-}
-
-/* Destroy a dwarf2_cu. */
-
-dwarf2_cu::~dwarf2_cu ()
-{
- per_cu->cu = NULL;
}
/* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE. */
@@ -23534,72 +23508,80 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
}
-/* Increase the age counter on each cached compilation unit, and free
- any that are too old. */
+/* See read.h. */
-static void
-age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
+dwarf2_cu *
+dwarf2_per_objfile::get_cu (dwarf2_per_cu_data *per_cu)
{
- struct dwarf2_per_cu_data *per_cu, **last_chain;
+ auto it = m_dwarf2_cus.find (per_cu);
+ if (it == m_dwarf2_cus.end ())
+ return nullptr;
- dwarf2_clear_marks (dwarf2_per_objfile->per_bfd->read_in_chain);
- per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
- while (per_cu != NULL)
+ return it->second;
+}
+
+/* See read.h. */
+
+void
+dwarf2_per_objfile::set_cu (dwarf2_per_cu_data *per_cu, dwarf2_cu *cu)
+{
+ gdb_assert (this->get_cu (per_cu) == nullptr);
+
+ m_dwarf2_cus[per_cu] = cu;
+}
+
+/* See read.h. */
+
+void
+dwarf2_per_objfile::age_comp_units ()
+{
+ /* Start by clearing all marks. */
+ for (auto pair : m_dwarf2_cus)
+ pair.second->mark = false;
+
+ /* Traverse all CUs, mark them and their dependencies if used recently
+ enough. */
+ for (auto pair : m_dwarf2_cus)
{
- per_cu->cu->last_used ++;
- if (per_cu->cu->last_used <= dwarf_max_cache_age)
- dwarf2_mark (per_cu->cu);
- per_cu = per_cu->cu->read_in_chain;
+ dwarf2_cu *cu = pair.second;
+
+ cu->last_used++;
+ if (cu->last_used <= dwarf_max_cache_age)
+ dwarf2_mark (cu);
}
- per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
- last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
- while (per_cu != NULL)
+ /* Delete all CUs still not marked. */
+ for (auto it = m_dwarf2_cus.begin (); it != m_dwarf2_cus.end ();)
{
- struct dwarf2_per_cu_data *next_cu;
+ dwarf2_cu *cu = it->second;
- next_cu = per_cu->cu->read_in_chain;
-
- if (!per_cu->cu->mark)
+ if (!cu->mark)
{
- delete per_cu->cu;
- *last_chain = next_cu;
+ delete cu;
+ it = m_dwarf2_cus.erase (it);
}
else
- last_chain = &per_cu->cu->read_in_chain;
-
- per_cu = next_cu;
+ it++;
}
}
-/* Remove a single compilation unit from the cache. */
+/* See read.h. */
-static void
-free_one_cached_comp_unit (dwarf2_per_cu_data *target_per_cu,
- dwarf2_per_objfile *dwarf2_per_objfile)
+void
+dwarf2_per_objfile::remove_cu (dwarf2_per_cu_data *per_cu)
{
- struct dwarf2_per_cu_data *per_cu, **last_chain;
-
- per_cu = dwarf2_per_objfile->per_bfd->read_in_chain;
- last_chain = &dwarf2_per_objfile->per_bfd->read_in_chain;
- while (per_cu != NULL)
- {
- struct dwarf2_per_cu_data *next_cu;
+ auto it = m_dwarf2_cus.find (per_cu);
+ if (it == m_dwarf2_cus.end ())
+ return;
- next_cu = per_cu->cu->read_in_chain;
+ delete it->second;
- if (per_cu == target_per_cu)
- {
- delete per_cu->cu;
- per_cu->cu = NULL;
- *last_chain = next_cu;
- break;
- }
- else
- last_chain = &per_cu->cu->read_in_chain;
+ m_dwarf2_cus.erase (it);
+}
- per_cu = next_cu;
- }
+dwarf2_per_objfile::~dwarf2_per_objfile ()
+{
+ remove_all_cus ();
}
/* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer.
@@ -23801,27 +23783,30 @@ dwarf2_add_dependence (struct dwarf2_cu *cu,
/* Subroutine of dwarf2_mark to pass to htab_traverse.
Set the mark field in every compilation unit in the
- cache that we must keep because we are keeping CU. */
+ cache that we must keep because we are keeping CU.
+
+ DATA is the dwarf2_per_objfile object in which to look up CUs. */
static int
dwarf2_mark_helper (void **slot, void *data)
{
- struct dwarf2_per_cu_data *per_cu;
-
- per_cu = (struct dwarf2_per_cu_data *) *slot;
+ dwarf2_per_cu_data *per_cu = (dwarf2_per_cu_data *) *slot;
+ dwarf2_per_objfile *per_objfile = (dwarf2_per_objfile *) data;
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
/* cu->dependencies references may not yet have been ever read if QUIT aborts
reading of the chain. As such dependencies remain valid it is not much
useful to track and undo them during QUIT cleanups. */
- if (per_cu->cu == NULL)
+ if (cu == nullptr)
return 1;
- if (per_cu->cu->mark)
+ if (cu->mark)
return 1;
- per_cu->cu->mark = true;
- if (per_cu->cu->dependencies != NULL)
- htab_traverse (per_cu->cu->dependencies, dwarf2_mark_helper, NULL);
+ cu->mark = true;
+
+ if (cu->dependencies != nullptr)
+ htab_traverse (cu->dependencies, dwarf2_mark_helper, per_objfile);
return 1;
}
@@ -23834,19 +23819,11 @@ dwarf2_mark (struct dwarf2_cu *cu)
{
if (cu->mark)
return;
+
cu->mark = true;
- if (cu->dependencies != NULL)
- htab_traverse (cu->dependencies, dwarf2_mark_helper, NULL);
-}
-static void
-dwarf2_clear_marks (struct dwarf2_per_cu_data *per_cu)
-{
- while (per_cu)
- {
- per_cu->cu->mark = false;
- per_cu = per_cu->cu->read_in_chain;
- }
+ if (cu->dependencies != nullptr)
+ htab_traverse (cu->dependencies, dwarf2_mark_helper, cu->per_objfile);
}
/* Trivial hash function for partial_die_info: the hash value of a DIE
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index b75be31..996cf55 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -43,6 +43,7 @@ struct tu_stats
int nr_all_type_units_reallocs;
};
+struct dwarf2_cu;
struct dwarf2_debug_sections;
struct dwarf2_per_cu_data;
struct mapped_index;
@@ -115,9 +116,6 @@ struct dwarf2_per_bfd
TU. */
signatured_type *get_tu (int index);
- /* Free all cached compilation units. */
- void free_cached_comp_units ();
-
/* A convenience function to allocate a dwarf2_per_cu_data. The
returned object has its "index" field set properly. The object
is allocated on the dwarf2_per_bfd obstack. */
@@ -189,10 +187,6 @@ public:
are doing. */
struct tu_stats tu_stats {};
- /* A chain of compilation units that are currently read in, so that
- they can be freed later. */
- dwarf2_per_cu_data *read_in_chain = NULL;
-
/* A table mapping DW_AT_dwo_name values to struct dwo_file objects.
This is NULL if the table hasn't been allocated yet. */
htab_up dwo_files;
@@ -303,6 +297,8 @@ struct dwarf2_per_objfile
: objfile (objfile), per_bfd (per_bfd)
{}
+ ~dwarf2_per_objfile ();
+
/* Return pointer to string at .debug_line_str offset as read from BUF.
BUF is assumed to be in a compilation unit described by CU_HEADER.
Return *BYTES_READ_PTR count of bytes read from BUF. */
@@ -344,6 +340,22 @@ struct dwarf2_per_objfile
UNSIGNED_P controls if the integer is unsigned or not. */
struct type *int_type (int size_in_bytes, bool unsigned_p) const;
+ /* Get the dwarf2_cu matching PER_CU for this objfile. */
+ dwarf2_cu *get_cu (dwarf2_per_cu_data *per_cu);
+
+ /* Set the dwarf2_cu matching PER_CU for this objfile. */
+ void set_cu (dwarf2_per_cu_data *per_cu, dwarf2_cu *cu);
+
+ /* Remove/free the dwarf2_cu matching PER_CU for this objfile. */
+ void remove_cu (dwarf2_per_cu_data *per_cu);
+
+ /* Free all cached compilation units. */
+ void remove_all_cus ();
+
+ /* Increase the age counter on each CU compilation unit and free
+ any that are too old. */
+ void age_comp_units ();
+
/* Back link. */
struct objfile *objfile;
@@ -372,6 +384,10 @@ private:
/* Map from signatured types to the corresponding struct type. */
std::unordered_map<signatured_type *, struct type *> m_type_map;
+
+ /* Map from the objfile-independent dwarf2_per_cu_data instances to the
+ corresponding objfile-dependent dwarf2_cu instances. */
+ std::unordered_map<dwarf2_per_cu_data *, dwarf2_cu *> m_dwarf2_cus;
};
/* Get the dwarf2_per_objfile associated to OBJFILE. */
@@ -455,11 +471,6 @@ struct dwarf2_per_cu_data
not the DWO file. */
struct dwarf2_section_info *section;
- /* Set to non-NULL iff this CU is currently loaded. When it gets freed out
- of the CU cache it gets reset to NULL again. This is left as NULL for
- dummy CUs (a CU header, but nothing else). */
- struct dwarf2_cu *cu;
-
/* The unit type of this CU. */
enum dwarf_unit_type unit_type;