diff options
Diffstat (limited to 'gdb/minsyms.c')
-rw-r--r-- | gdb/minsyms.c | 141 |
1 files changed, 81 insertions, 60 deletions
diff --git a/gdb/minsyms.c b/gdb/minsyms.c index c4a0fa8..c23d170 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -51,13 +51,10 @@ #include "cli/cli-utils.h" #include "gdbsupport/symbol.h" #include <algorithm> +#include "gdbsupport/cxx-thread.h" #include "gdbsupport/parallel-for.h" #include "inferior.h" -#if CXX_STD_THREAD -#include <mutex> -#endif - /* Return true if MINSYM is a cold clone symbol. Recognize f.i. these symbols (mangled/demangled): - _ZL3foov.cold @@ -1390,6 +1387,79 @@ build_minimal_symbol_hash_tables } } +/* gdb::parallel_for_each worker to compute minimal symbol names and hashes. */ + +class minimal_symbol_install_worker +{ +public: + minimal_symbol_install_worker + (minimal_symbol *msymbols, + gdb::array_view<computed_hash_values> hash_values, + objfile_per_bfd_storage *per_bfd, + gdb::mutex &demangled_mutex) + : m_time_it ("minsym install worker"), + m_msymbols (msymbols), + m_hash_values (hash_values), + m_per_bfd (per_bfd), + m_demangled_mutex (demangled_mutex) + {} + + void operator() (iterator_range<minimal_symbol *> msym_range) noexcept + { + for (minimal_symbol &msym : msym_range) + { + size_t idx = &msym - m_msymbols; + m_hash_values[idx].name_length = strlen (msym.linkage_name ()); + + if (!msym.name_set) + { + /* This will be freed later, by compute_and_set_names. */ + gdb::unique_xmalloc_ptr<char> demangled_name + = symbol_find_demangled_name (&msym, msym.linkage_name ()); + msym.set_demangled_name (demangled_name.release (), + &m_per_bfd->storage_obstack); + msym.name_set = 1; + } + + /* This mangled_name_hash computation has to be outside of + the name_set check, or compute_and_set_names below will + be called with an invalid hash value. */ + m_hash_values[idx].mangled_name_hash + = fast_hash (msym.linkage_name (), m_hash_values[idx].name_length); + m_hash_values[idx].minsym_hash = msymbol_hash (msym.linkage_name ()); + + /* We only use this hash code if the search name differs + from the linkage name. See the code in + build_minimal_symbol_hash_tables. */ + if (msym.search_name () != msym.linkage_name ()) + m_hash_values[idx].minsym_demangled_hash + = search_name_hash (msym.language (), msym.search_name ()); + } + + { + /* To limit how long we hold the lock, we only acquire it here + and not while we demangle the names above. */ + gdb::lock_guard<gdb::mutex> guard (m_demangled_mutex); + for (minimal_symbol &msym : msym_range) + { + size_t idx = &msym - m_msymbols; + std::string_view name (msym.linkage_name (), + m_hash_values[idx].name_length); + hashval_t hashval = m_hash_values[idx].mangled_name_hash; + + msym.compute_and_set_names (name, false, m_per_bfd, hashval); + } + } + } + +private: + scoped_time_it m_time_it; + minimal_symbol *m_msymbols; + gdb::array_view<computed_hash_values> m_hash_values; + objfile_per_bfd_storage *m_per_bfd; + gdb::mutex &m_demangled_mutex; +}; + /* Add the minimal symbols in the existing bunches to the objfile's official minimal symbol table. In most cases there is no minimal symbol table yet for this objfile, and the existing bunches are used to create one. Once @@ -1467,68 +1537,19 @@ minimal_symbol_reader::install () m_objfile->per_bfd->minimal_symbol_count = mcount; m_objfile->per_bfd->msymbols = std::move (msym_holder); -#if CXX_STD_THREAD /* Mutex that is used when modifying or accessing the demangled hash table. */ - std::mutex demangled_mutex; -#endif + gdb::mutex demangled_mutex; std::vector<computed_hash_values> hash_values (mcount); msymbols = m_objfile->per_bfd->msymbols.get (); - /* Arbitrarily require at least 10 elements in a thread. */ - gdb::parallel_for_each<10> (&msymbols[0], &msymbols[mcount], - [&] (minimal_symbol *start, minimal_symbol *end) - { - scoped_time_it time_it ("minsyms install worker"); - - for (minimal_symbol *msym = start; msym < end; ++msym) - { - size_t idx = msym - msymbols; - hash_values[idx].name_length = strlen (msym->linkage_name ()); - if (!msym->name_set) - { - /* This will be freed later, by compute_and_set_names. */ - gdb::unique_xmalloc_ptr<char> demangled_name - = symbol_find_demangled_name (msym, msym->linkage_name ()); - msym->set_demangled_name - (demangled_name.release (), - &m_objfile->per_bfd->storage_obstack); - msym->name_set = 1; - } - /* This mangled_name_hash computation has to be outside of - the name_set check, or compute_and_set_names below will - be called with an invalid hash value. */ - hash_values[idx].mangled_name_hash - = fast_hash (msym->linkage_name (), - hash_values[idx].name_length); - hash_values[idx].minsym_hash - = msymbol_hash (msym->linkage_name ()); - /* We only use this hash code if the search name differs - from the linkage name. See the code in - build_minimal_symbol_hash_tables. */ - if (msym->search_name () != msym->linkage_name ()) - hash_values[idx].minsym_demangled_hash - = search_name_hash (msym->language (), msym->search_name ()); - } - { - /* To limit how long we hold the lock, we only acquire it here - and not while we demangle the names above. */ -#if CXX_STD_THREAD - std::lock_guard<std::mutex> guard (demangled_mutex); -#endif - for (minimal_symbol *msym = start; msym < end; ++msym) - { - size_t idx = msym - msymbols; - msym->compute_and_set_names - (std::string_view (msym->linkage_name (), - hash_values[idx].name_length), - false, - m_objfile->per_bfd, - hash_values[idx].mangled_name_hash); - } - } - }); + + gdb::parallel_for_each<1000, minimal_symbol *, minimal_symbol_install_worker> + (&msymbols[0], &msymbols[mcount], msymbols, + gdb::array_view<computed_hash_values> (hash_values), + m_objfile->per_bfd, + demangled_mutex); build_minimal_symbol_hash_tables (m_objfile, hash_values); } |