summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Biesinger <cbiesinger@google.com>2019-10-30 15:10:23 -0500
committerChristian Biesinger <cbiesinger@google.com>2019-11-18 17:51:10 -0600
commit12f4dc41bf9f018ecc1042830d5534de941f329e (patch)
tree550e34221781f792ddf1ed9c45ce5eed56362e13
parent6f509f24899f79095673698b611e81f980806fb5 (diff)
downloadbinutils-gdb-users/cbiesinger/all-perf-patches.tar.gz
[RFC] Don't block on finishing demangling msymbolsusers/cbiesinger/all-perf-patches
Instead, do it all on a background thread and only block when we actually need the result. Note, this is a speedup but not quite as much as I was expecting; still looking into what causes the waits. However, let me know if you have thoughts on the concept! Change-Id: I9d871917459ece0b41d31670b3c56600757aea66
-rw-r--r--gdb/minsyms.c127
-rw-r--r--gdb/objfiles.h18
2 files changed, 91 insertions, 54 deletions
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index be529235c80..253e75d3493 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -157,15 +157,15 @@ add_minsym_to_hash_table (struct minimal_symbol *sym,
TABLE. */
static void
add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
- struct objfile *objfile,
+ struct objfile_per_bfd_storage *per_bfd,
unsigned int hash_value)
{
if (sym->demangled_hash_next == NULL)
{
- objfile->per_bfd->demangled_hash_languages.set (MSYMBOL_LANGUAGE (sym));
+ per_bfd->demangled_hash_languages.set (MSYMBOL_LANGUAGE (sym));
struct minimal_symbol **table
- = objfile->per_bfd->msymbol_demangled_hash;
+ = per_bfd->msymbol_demangled_hash;
unsigned int hash_index = hash_value % MINIMAL_SYMBOL_HASH_SIZE;
sym->demangled_hash_next = table[hash_index];
table[hash_index] = sym;
@@ -341,6 +341,7 @@ lookup_minimal_symbol (const char *name, const char *sfile,
objfile_debug_name (objfile));
}
+ objfile->per_bfd->wait_for_msymbols ();
/* Do two passes: the first over the ordinary hash table,
and the second over the demangled hash table. */
lookup_minimal_symbol_mangled (name, sfile, objfile,
@@ -477,6 +478,7 @@ iterate_over_minimal_symbols
(struct objfile *objf, const lookup_name_info &lookup_name,
gdb::function_view<bool (struct minimal_symbol *)> callback)
{
+ objf->per_bfd->wait_for_msymbols ();
/* The first pass is over the ordinary hash table. */
{
const char *name = linkage_name_str (lookup_name);
@@ -529,6 +531,7 @@ lookup_minimal_symbol_linkage (const char *name, struct objfile *objf)
for (objfile *objfile : objf->separate_debug_objfiles ())
{
+ objfile->per_bfd->wait_for_msymbols ();
for (minimal_symbol *msymbol = objfile->per_bfd->msymbol_hash[hash];
msymbol != NULL;
msymbol = msymbol->hash_next)
@@ -562,6 +565,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
if (objf == NULL || objf == objfile
|| objf == objfile->separate_debug_objfile_backlink)
{
+ objfile->per_bfd->wait_for_msymbols ();
for (msymbol = objfile->per_bfd->msymbol_hash[hash];
msymbol != NULL && found_symbol.minsym == NULL;
msymbol = msymbol->hash_next)
@@ -609,6 +613,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
if (objf == NULL || objf == objfile
|| objf == objfile->separate_debug_objfile_backlink)
{
+ objfile->per_bfd->wait_for_msymbols ();
for (msymbol = objfile->per_bfd->msymbol_hash[hash];
msymbol != NULL;
msymbol = msymbol->hash_next)
@@ -720,6 +725,7 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *sectio
/* If this objfile has a minimal symbol table, go search it
using a binary search. */
+ objfile->per_bfd->wait_for_msymbols ();
if (objfile->per_bfd->minimal_symbol_count > 0)
{
int best_zero_sized = -1;
@@ -1270,27 +1276,27 @@ struct computed_hash_values
static void
build_minimal_symbol_hash_tables
- (struct objfile *objfile,
+ (struct objfile_per_bfd_storage *per_bfd,
const std::vector<computed_hash_values>& hash_values)
{
int i;
struct minimal_symbol *msym;
/* (Re)insert the actual entries. */
- int mcount = objfile->per_bfd->minimal_symbol_count;
+ int mcount = per_bfd->minimal_symbol_count;
for ((i = 0,
- msym = objfile->per_bfd->msymbols.get ());
+ msym = per_bfd->msymbols.get ());
i < mcount;
i++, msym++)
{
msym->hash_next = 0;
- add_minsym_to_hash_table (msym, objfile->per_bfd->msymbol_hash,
+ add_minsym_to_hash_table (msym, per_bfd->msymbol_hash,
hash_values[i].minsym_hash);
msym->demangled_hash_next = 0;
if (MSYMBOL_SEARCH_NAME (msym) != MSYMBOL_LINKAGE_NAME (msym))
add_minsym_to_demangled_hash_table
- (msym, objfile, hash_values[i].minsym_demangled_hash);
+ (msym, per_bfd, hash_values[i].minsym_demangled_hash);
}
}
@@ -1311,8 +1317,11 @@ minimal_symbol_reader::install ()
if (m_objfile->per_bfd->minsyms_read)
return;
+
if (m_msym_count > 0)
{
+ m_objfile->per_bfd->wait_for_msymbols ();
+
if (symtab_create_debug)
{
fprintf_unfiltered (gdb_stdlog,
@@ -1375,63 +1384,71 @@ minimal_symbol_reader::install ()
m_objfile->per_bfd->minimal_symbol_count = mcount;
m_objfile->per_bfd->msymbols = std::move (msym_holder);
+ msymbols = m_objfile->per_bfd->msymbols.get ();
+ objfile_per_bfd_storage* per_bfd = m_objfile->per_bfd;
+
+ m_objfile->per_bfd->m_minsym_future
+ = gdb::thread_pool::g_thread_pool->post_task ([msymbols, mcount,
+ per_bfd] ()
+ {
#if CXX_STD_THREAD
- /* Mutex that is used when modifying or accessing the demangled
- hash table. */
- std::mutex demangled_mutex;
+ /* Mutex that is used when modifying or accessing the demangled
+ hash table. */
+ std::mutex demangled_mutex;
#endif
- std::vector<computed_hash_values> hash_values (mcount);
+ std::vector<computed_hash_values> hash_values (mcount);
- msymbols = m_objfile->per_bfd->msymbols.get ();
- gdb::parallel_for_each
- (&msymbols[0], &msymbols[mcount],
- [&] (minimal_symbol *start, minimal_symbol *end)
- {
- for (minimal_symbol *msym = start; msym < end; ++msym)
+ gdb::parallel_for_each
+ (&msymbols[0], &msymbols[mcount],
+ [&] (minimal_symbol *start, minimal_symbol *end)
{
- size_t idx = msym - msymbols;
- hash_values[idx].name_length = strlen (msym->name);
- if (!msym->name_set)
+ for (minimal_symbol *msym = start; msym < end; ++msym)
{
- /* This will be freed later, by symbol_set_names. */
- char *demangled_name
- = symbol_find_demangled_name (msym, msym->name);
- symbol_set_demangled_name
- (msym, demangled_name,
- &m_objfile->per_bfd->storage_obstack);
- msym->name_set = 1;
-
- hash_values[idx].mangled_name_hash
- = fast_hash (msym->name, hash_values[idx].name_length);
+ size_t idx = msym - msymbols;
+ hash_values[idx].name_length = strlen (msym->name);
+ if (!msym->name_set)
+ {
+ /* This will be freed later, by symbol_set_names. */
+ char *demangled_name
+ = symbol_find_demangled_name (msym, msym->name);
+ symbol_set_demangled_name
+ (msym, demangled_name,
+ &per_bfd->storage_obstack);
+ msym->name_set = 1;
+
+ hash_values[idx].mangled_name_hash
+ = fast_hash (msym->name, hash_values[idx].name_length);
+ }
+ hash_values[idx].minsym_hash
+ = msymbol_hash (MSYMBOL_LINKAGE_NAME (msym));
+ hash_values[idx].minsym_demangled_hash
+ = search_name_hash (MSYMBOL_LANGUAGE (msym),
+ MSYMBOL_SEARCH_NAME (msym));
}
- hash_values[idx].minsym_hash
- = msymbol_hash (MSYMBOL_LINKAGE_NAME (msym));
- hash_values[idx].minsym_demangled_hash
- = search_name_hash (MSYMBOL_LANGUAGE (msym),
- MSYMBOL_SEARCH_NAME (msym));
- }
- {
- /* To limit how long we hold the lock, we only acquire it here
- and not while we demangle the names above. */
+ {
+ /* 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);
+ std::lock_guard<std::mutex> guard (demangled_mutex);
#endif
- for (minimal_symbol *msym = start; msym < end; ++msym)
- {
- size_t idx = msym - msymbols;
- symbol_set_names
- (msym,
- gdb::string_view(msym->name,
- hash_values[idx].name_length),
- false,
- m_objfile->per_bfd,
- hash_values[idx].mangled_name_hash);
+ for (minimal_symbol *msym = start; msym < end; ++msym)
+ {
+ size_t idx = msym - msymbols;
+ symbol_set_names
+ (msym,
+ gdb::string_view(msym->name,
+ hash_values[idx].name_length),
+ false,
+ per_bfd,
+ hash_values[idx].mangled_name_hash);
+ }
}
- }
- });
+ });
- build_minimal_symbol_hash_tables (m_objfile, hash_values);
+ build_minimal_symbol_hash_tables (per_bfd, hash_values);
+ }
+ );
}
}
@@ -1518,6 +1535,8 @@ minimal_symbol_upper_bound (struct bound_minimal_symbol minsym)
other sections, to find the next symbol in this section with a
different address. */
+ minsym.objfile->per_bfd->wait_for_msymbols ();
+
struct minimal_symbol *past_the_end
= (minsym.objfile->per_bfd->msymbols.get ()
+ minsym.objfile->per_bfd->minimal_symbol_count);
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 0c044582e43..1c126c17f5e 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -30,6 +30,9 @@
#include "psymtab.h"
#include <bitset>
#include <vector>
+#if CXX_STD_THREAD
+#include <future>
+#endif
#include "gdbsupport/next-iterator.h"
#include "gdbsupport/safe-iterator.h"
#include "bcache.h"
@@ -319,6 +322,19 @@ struct objfile_per_bfd_storage
/* All the different languages of symbols found in the demangled
hash table. */
std::bitset<nr_languages> demangled_hash_languages;
+
+ void wait_for_msymbols() {
+#if CXX_STD_THREAD
+ if (m_minsym_future.valid ())
+ {
+ m_minsym_future.wait ();
+ m_minsym_future = std::future<void> ();
+ }
+#endif
+ }
+#if CXX_STD_THREAD
+ std::future<void> m_minsym_future;
+#endif
};
/* An iterator that first returns a parent objfile, and then each
@@ -439,11 +455,13 @@ struct objfile
minimal_symbol_iterator begin () const
{
+ m_objfile->per_bfd->wait_for_msymbols ();
return minimal_symbol_iterator (m_objfile->per_bfd->msymbols.get ());
}
minimal_symbol_iterator end () const
{
+ m_objfile->per_bfd->wait_for_msymbols ();
return minimal_symbol_iterator
(m_objfile->per_bfd->msymbols.get ()
+ m_objfile->per_bfd->minimal_symbol_count);