}
/* Helper for dw2_expand_matching symtabs. Called on each symbol
- matched, to expand corresponding CUs that were marked. IDX is the
- index of the symbol name that matched. */
+ matched, to expand corresponding CUs (unless the CU is to be
+ skipped). IDX is the index of the symbol name that matched. */
static bool
dw2_expand_marked_cus (dwarf2_per_objfile *per_objfile, offset_type idx,
+ auto_bool_vector &cus_to_skip,
expand_symtabs_file_matcher file_matcher,
expand_symtabs_expansion_listener expansion_notify,
block_search_flags search_flags,
dwarf2_per_cu *per_cu = index.units[cu_index];
- if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
- expansion_notify, lang_matcher))
+ if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, cus_to_skip,
+ file_matcher, expansion_notify,
+ lang_matcher))
return false;
}
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
+ auto_bool_vector cus_to_skip;
+ dw_expand_symtabs_matching_file_matcher (per_objfile, cus_to_skip,
+ file_matcher);
/* This invariant is documented in quick-functions.h. */
gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
QUIT;
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
- file_matcher,
+ cus_to_skip, file_matcher,
expansion_notify,
lang_matcher))
return false;
symbol_matcher,
[&] (offset_type idx)
{
- if (!dw2_expand_marked_cus (per_objfile, idx, file_matcher,
+ if (!dw2_expand_marked_cus (per_objfile, idx, cus_to_skip, file_matcher,
expansion_notify, search_flags, domain,
lang_matcher))
return false;
dw2_expand_symtabs_matching_one
(dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
+ auto_bool_vector &cus_to_skip,
expand_symtabs_file_matcher file_matcher,
expand_symtabs_expansion_listener expansion_notify,
expand_symtabs_lang_matcher lang_matcher)
{
- if (file_matcher != nullptr && !per_cu->mark)
+ /* Already visited, or intentionally skipped. */
+ if (cus_to_skip.is_set (per_cu->index))
return true;
if (lang_matcher != nullptr)
void
dw_expand_symtabs_matching_file_matcher
- (dwarf2_per_objfile *per_objfile, expand_symtabs_file_matcher file_matcher)
+ (dwarf2_per_objfile *per_objfile,
+ auto_bool_vector &cus_to_skip,
+ expand_symtabs_file_matcher file_matcher)
{
if (file_matcher == NULL)
return;
QUIT;
if (per_cu->is_debug_types)
- continue;
- per_cu->mark = 0;
+ {
+ cus_to_skip.set (per_cu->index, true);
+ continue;
+ }
/* We only need to look at symtabs not already expanded. */
if (per_objfile->symtab_set_p (per_cu.get ()))
- continue;
+ {
+ cus_to_skip.set (per_cu->index, true);
+ continue;
+ }
if (per_cu->fnd != nullptr)
{
file_and_directory *fnd = per_cu->fnd.get ();
if (file_matcher (fnd->get_name (), false))
- {
- per_cu->mark = 1;
- continue;
- }
+ continue;
/* Before we invoke realpath, which can get expensive when many
files are involved, do a quick comparison of the basenames. */
if ((basenames_may_differ
|| file_matcher (lbasename (fnd->get_name ()), true))
&& file_matcher (fnd->get_fullname (), false))
- {
- per_cu->mark = 1;
- continue;
- }
+ continue;
}
quick_file_names *file_data = dw2_get_file_names (per_cu.get (),
per_objfile);
if (file_data == NULL)
- continue;
+ {
+ cus_to_skip.set (per_cu->index, true);
+ continue;
+ }
if (visited_not_found.contains (file_data))
- continue;
- else if (visited_found.contains (file_data))
{
- per_cu->mark = 1;
+ cus_to_skip.set (per_cu->index, true);
continue;
}
+ else if (visited_found.contains (file_data))
+ continue;
+ bool matched = false;
for (int j = 0; j < file_data->num_file_names; ++j)
{
const char *this_real_name;
if (file_matcher (file_data->file_names[j], false))
{
- per_cu->mark = 1;
+ matched = true;
break;
}
this_real_name = dw2_get_real_path (per_objfile, file_data, j);
if (file_matcher (this_real_name, false))
{
- per_cu->mark = 1;
+ matched = true;
break;
}
}
- if (per_cu->mark)
+ if (matched)
visited_found.insert (file_data);
else
- visited_not_found.insert (file_data);
+ {
+ cus_to_skip.set (per_cu->index, true);
+ visited_not_found.insert (file_data);
+ }
}
}
cooked_index *table = wait (objfile, true);
- dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
+ auto_bool_vector cus_to_skip;
+ dw_expand_symtabs_matching_file_matcher (per_objfile, cus_to_skip,
+ file_matcher);
/* This invariant is documented in quick-functions.h. */
gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
QUIT;
if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
- file_matcher,
+ cus_to_skip, file_matcher,
expansion_notify,
lang_matcher))
return false;
if (per_objfile->symtab_set_p (entry->per_cu))
continue;
- /* If file-matching was done, we don't need to consider
- symbols from unmarked CUs. */
- if (file_matcher != nullptr && !entry->per_cu->mark)
+ /* We don't need to consider symbols from some CUs. */
+ if (cus_to_skip.is_set (entry->per_cu->index))
continue;
/* See if the symbol matches the type filter. */
}
if (!dw2_expand_symtabs_matching_one (entry->per_cu, per_objfile,
- file_matcher,
+ cus_to_skip, file_matcher,
expansion_notify, nullptr))
return false;
}
lto_artificial (false),
queued (false),
m_header_read_in (false),
- mark (false),
files_read (false),
scanned (false),
section (section),
it private at the moment. */
mutable packed<bool, 1> m_header_read_in;
- /* A temporary mark bit used when iterating over all CUs in
- expand_symtabs_matching. */
- packed<unsigned int, 1> mark;
-
/* True if we've tried to read the file table. There will be no
point in trying to read it again next time. */
packed<bool, 1> files_read;
bool need_fullname) override;
};
-/* If FILE_MATCHER is NULL or if PER_CU has
- dwarf2_per_cu_quick_data::MARK set (see
- dw_expand_symtabs_matching_file_matcher), expand the CU and call
- EXPANSION_NOTIFY on it. */
+/* This is used to track whether a CU has already been visited during
+ symbol expansion. It is an auto-resizing bool vector. */
+class auto_bool_vector
+{
+public:
+
+ auto_bool_vector () = default;
+
+ /* Return true if element I is set. */
+ bool is_set (size_t i) const
+ {
+ if (i < m_vec.size ())
+ return m_vec[i];
+ return false;
+ }
+
+ /* Set a value in this vector, growing it automatically. */
+ void set (size_t i, bool value)
+ {
+ if (m_vec.size () < i + 1)
+ m_vec.resize (i + 1);
+ m_vec[i] = value;
+ }
+
+private:
+ std::vector<bool> m_vec;
+};
+
+/* If FILE_MATCHER is NULL and if CUS_TO_SKIP does not include the
+ CU's index, expand the CU and call EXPANSION_NOTIFY on it. */
extern bool dw2_expand_symtabs_matching_one
(dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
+ auto_bool_vector &cus_to_skip,
expand_symtabs_file_matcher file_matcher,
expand_symtabs_expansion_listener expansion_notify,
expand_symtabs_lang_matcher lang_matcher);
-/* If FILE_MATCHER is non-NULL, set all the
- dwarf2_per_cu_quick_data::MARK of the current DWARF2_PER_OBJFILE
- that match FILE_MATCHER. */
+/* If FILE_MATCHER is non-NULL, update CUS_TO_SKIP as appropriate
+ based on FILE_MATCHER. */
extern void dw_expand_symtabs_matching_file_matcher
(dwarf2_per_objfile *per_objfile,
+ auto_bool_vector &cus_to_skip,
expand_symtabs_file_matcher file_matcher);
/* Return pointer to string at .debug_str offset STR_OFFSET. */