aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2023-12-03 12:34:49 -0700
committerTom Tromey <tom@tromey.com>2024-01-18 08:20:16 -0700
commit47efef8f2d8a10b63d2c6125aded1d2da69d8a04 (patch)
treefc94ec0ca473443e1218e1af36e4cb3fea5f44ef /gdb/dwarf2/read.c
parent6e53356b77887974e554ae07f9d76b83cd211700 (diff)
downloadbinutils-47efef8f2d8a10b63d2c6125aded1d2da69d8a04.zip
binutils-47efef8f2d8a10b63d2c6125aded1d2da69d8a04.tar.gz
binutils-47efef8f2d8a10b63d2c6125aded1d2da69d8a04.tar.bz2
Change cooked_index_worker to abstract base class
This changes cooked_index_worker to be an abstract base class. The base class implementation is moved to cooked-index.c, and a concrete subclass is added to read.c. This change is preparation for the new .debug_names reader, which will supply its own concrete implementation of the worker.
Diffstat (limited to 'gdb/dwarf2/read.c')
-rw-r--r--gdb/dwarf2/read.c186
1 files changed, 49 insertions, 137 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 8010c01..7691fe0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -4824,32 +4824,58 @@ process_skeletonless_type_units (dwarf2_per_objfile *per_objfile,
}
}
-cooked_index_worker::cooked_index_worker (dwarf2_per_objfile *per_objfile)
- : m_per_objfile (per_objfile)
+/* A subclass of cooked_index_worker that handles scanning
+ .debug_info. */
+
+class cooked_index_debug_info : public cooked_index_worker
{
- gdb_assert (is_main_thread ());
+public:
+ cooked_index_debug_info (dwarf2_per_objfile *per_objfile)
+ : cooked_index_worker (per_objfile)
+ {
+ gdb_assert (is_main_thread ());
- struct objfile *objfile = per_objfile->objfile;
- dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
+ struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
- dwarf_read_debug_printf ("Building psymtabs of objfile %s ...",
- objfile_name (objfile));
+ dwarf_read_debug_printf ("Building psymtabs of objfile %s ...",
+ objfile_name (objfile));
- per_bfd->map_info_sections (objfile);
-}
+ per_bfd->map_info_sections (objfile);
+ }
-void
-cooked_index_worker::start ()
-{
- gdb::thread_pool::g_thread_pool->post_task ([=] ()
+private:
+
+ void do_reading () override;
+
+ void print_stats () override
{
- this->start_reading ();
- });
-}
+ if (dwarf_read_debug > 0)
+ print_tu_stats (m_per_objfile);
+ }
+
+ /* After the last DWARF-reading task has finished, this function
+ does the remaining work to finish the scan. */
+ void done_reading ();
+
+ /* An iterator for the comp units. */
+ typedef std::vector<dwarf2_per_cu_data_up>::iterator unit_iterator;
+
+ /* Process a batch of CUs. This may be called multiple times in
+ separate threads. TASK_NUMBER indicates which task this is --
+ the result is stored in that slot of M_RESULTS. */
+ void process_cus (size_t task_number, unit_iterator first,
+ unit_iterator end);
+
+ /* A storage object for "leftovers" -- see the 'start' method, but
+ essentially things not parsed during the normal CU parsing
+ passes. */
+ cooked_index_storage m_index_storage;
+};
void
-cooked_index_worker::process_cus (size_t task_number, unit_iterator first,
- unit_iterator end)
+cooked_index_debug_info::process_cus (size_t task_number, unit_iterator first,
+ unit_iterator end)
{
SCOPE_EXIT { bfd_thread_cleanup (); };
@@ -4877,7 +4903,7 @@ cooked_index_worker::process_cus (size_t task_number, unit_iterator first,
}
void
-cooked_index_worker::done_reading ()
+cooked_index_debug_info::done_reading ()
{
/* Only handle the scanning results here. Complaints and exceptions
can only be dealt with on the main thread. */
@@ -4899,23 +4925,7 @@ cooked_index_worker::done_reading ()
}
void
-cooked_index_worker::start_reading ()
-{
- SCOPE_EXIT { bfd_thread_cleanup (); };
-
- try
- {
- do_reading ();
- }
- catch (const gdb_exception &exc)
- {
- m_failed = exc;
- set (cooked_state::CACHE_DONE);
- }
-}
-
-void
-cooked_index_worker::do_reading ()
+cooked_index_debug_info::do_reading ()
{
dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd;
@@ -4986,106 +4996,6 @@ cooked_index_worker::do_reading ()
workers.start ();
}
-bool
-cooked_index_worker::wait (cooked_state desired_state, bool allow_quit)
-{
- bool done;
-#if CXX_STD_THREAD
- {
- std::unique_lock<std::mutex> lock (m_mutex);
-
- /* This may be called from a non-main thread -- this functionality
- is needed for the index cache -- but in this case we require
- that the desired state already have been attained. */
- gdb_assert (is_main_thread () || desired_state <= m_state);
-
- while (desired_state > m_state)
- {
- if (allow_quit)
- {
- std::chrono::milliseconds duration { 15 };
- if (m_cond.wait_for (lock, duration) == std::cv_status::timeout)
- QUIT;
- }
- else
- m_cond.wait (lock);
- }
- done = m_state == cooked_state::CACHE_DONE;
- }
-#else
- /* Without threads, all the work is done immediately on the main
- thread, and there is never anything to wait for. */
- done = true;
-#endif /* CXX_STD_THREAD */
-
- /* Only the main thread is allowed to report complaints and the
- like. */
- if (!is_main_thread ())
- return false;
-
- if (m_reported)
- return done;
- m_reported = true;
-
- /* Emit warnings first, maybe they were emitted before an exception
- (if any) was thrown. */
- m_warnings.emit ();
-
- if (m_failed.has_value ())
- {
- /* start_reading failed -- report it. */
- exception_print (gdb_stderr, *m_failed);
- m_failed.reset ();
- return done;
- }
-
- /* Only show a given exception a single time. */
- std::unordered_set<gdb_exception> seen_exceptions;
- for (auto &one_result : m_results)
- {
- re_emit_complaints (std::get<1> (one_result));
- for (auto &one_exc : std::get<2> (one_result))
- if (seen_exceptions.insert (one_exc).second)
- exception_print (gdb_stderr, one_exc);
- }
-
- if (dwarf_read_debug > 0)
- print_tu_stats (m_per_objfile);
-
- struct objfile *objfile = m_per_objfile->objfile;
- dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd;
- cooked_index *table
- = (gdb::checked_static_cast<cooked_index *>
- (per_bfd->index_table.get ()));
-
- auto_obstack temp_storage;
- enum language lang = language_unknown;
- const char *main_name = table->get_main_name (&temp_storage, &lang);
- if (main_name != nullptr)
- set_objfile_main_name (objfile, main_name, lang);
-
- dwarf_read_debug_printf ("Done building psymtabs of %s",
- objfile_name (objfile));
-
- return done;
-}
-
-void
-cooked_index_worker::set (cooked_state desired_state)
-{
- gdb_assert (desired_state != cooked_state::INITIAL);
-
-#if CXX_STD_THREAD
- std::lock_guard<std::mutex> guard (m_mutex);
- gdb_assert (desired_state > m_state);
- m_state = desired_state;
- m_cond.notify_one ();
-#else
- /* Without threads, all the work is done immediately on the main
- thread, and there is never anything to do. */
-#endif /* CXX_STD_THREAD */
-}
-
static void
read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
struct dwarf2_section_info *section,
@@ -16818,7 +16728,9 @@ start_debug_info_reader (dwarf2_per_objfile *per_objfile)
/* Set the index table early so that sharing works even while
scanning; and then start the scanning. */
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
- cooked_index *idx = new cooked_index (per_objfile);
+ std::unique_ptr<cooked_index_worker> worker
+ (new cooked_index_debug_info (per_objfile));
+ cooked_index *idx = new cooked_index (per_objfile, std::move (worker));
per_bfd->index_table.reset (idx);
/* Don't start reading until after 'index_table' is set. This
avoids races. */