GNU Binutils with patches for OS216
Révision | 12f4dc41bf9f018ecc1042830d5534de941f329e (tree) |
---|---|
l'heure | 2019-11-19 08:51:10 |
Auteur | Christian Biesinger <cbiesinger@goog...> |
Commiter | Christian Biesinger |
[RFC] Don't block on finishing demangling msymbols
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
@@ -157,15 +157,15 @@ add_minsym_to_hash_table (struct minimal_symbol *sym, | ||
157 | 157 | TABLE. */ |
158 | 158 | static void |
159 | 159 | add_minsym_to_demangled_hash_table (struct minimal_symbol *sym, |
160 | - struct objfile *objfile, | |
160 | + struct objfile_per_bfd_storage *per_bfd, | |
161 | 161 | unsigned int hash_value) |
162 | 162 | { |
163 | 163 | if (sym->demangled_hash_next == NULL) |
164 | 164 | { |
165 | - objfile->per_bfd->demangled_hash_languages.set (MSYMBOL_LANGUAGE (sym)); | |
165 | + per_bfd->demangled_hash_languages.set (MSYMBOL_LANGUAGE (sym)); | |
166 | 166 | |
167 | 167 | struct minimal_symbol **table |
168 | - = objfile->per_bfd->msymbol_demangled_hash; | |
168 | + = per_bfd->msymbol_demangled_hash; | |
169 | 169 | unsigned int hash_index = hash_value % MINIMAL_SYMBOL_HASH_SIZE; |
170 | 170 | sym->demangled_hash_next = table[hash_index]; |
171 | 171 | table[hash_index] = sym; |
@@ -341,6 +341,7 @@ lookup_minimal_symbol (const char *name, const char *sfile, | ||
341 | 341 | objfile_debug_name (objfile)); |
342 | 342 | } |
343 | 343 | |
344 | + objfile->per_bfd->wait_for_msymbols (); | |
344 | 345 | /* Do two passes: the first over the ordinary hash table, |
345 | 346 | and the second over the demangled hash table. */ |
346 | 347 | lookup_minimal_symbol_mangled (name, sfile, objfile, |
@@ -477,6 +478,7 @@ iterate_over_minimal_symbols | ||
477 | 478 | (struct objfile *objf, const lookup_name_info &lookup_name, |
478 | 479 | gdb::function_view<bool (struct minimal_symbol *)> callback) |
479 | 480 | { |
481 | + objf->per_bfd->wait_for_msymbols (); | |
480 | 482 | /* The first pass is over the ordinary hash table. */ |
481 | 483 | { |
482 | 484 | const char *name = linkage_name_str (lookup_name); |
@@ -529,6 +531,7 @@ lookup_minimal_symbol_linkage (const char *name, struct objfile *objf) | ||
529 | 531 | |
530 | 532 | for (objfile *objfile : objf->separate_debug_objfiles ()) |
531 | 533 | { |
534 | + objfile->per_bfd->wait_for_msymbols (); | |
532 | 535 | for (minimal_symbol *msymbol = objfile->per_bfd->msymbol_hash[hash]; |
533 | 536 | msymbol != NULL; |
534 | 537 | msymbol = msymbol->hash_next) |
@@ -562,6 +565,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf) | ||
562 | 565 | if (objf == NULL || objf == objfile |
563 | 566 | || objf == objfile->separate_debug_objfile_backlink) |
564 | 567 | { |
568 | + objfile->per_bfd->wait_for_msymbols (); | |
565 | 569 | for (msymbol = objfile->per_bfd->msymbol_hash[hash]; |
566 | 570 | msymbol != NULL && found_symbol.minsym == NULL; |
567 | 571 | msymbol = msymbol->hash_next) |
@@ -609,6 +613,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name, | ||
609 | 613 | if (objf == NULL || objf == objfile |
610 | 614 | || objf == objfile->separate_debug_objfile_backlink) |
611 | 615 | { |
616 | + objfile->per_bfd->wait_for_msymbols (); | |
612 | 617 | for (msymbol = objfile->per_bfd->msymbol_hash[hash]; |
613 | 618 | msymbol != NULL; |
614 | 619 | msymbol = msymbol->hash_next) |
@@ -720,6 +725,7 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc_in, struct obj_section *sectio | ||
720 | 725 | /* If this objfile has a minimal symbol table, go search it |
721 | 726 | using a binary search. */ |
722 | 727 | |
728 | + objfile->per_bfd->wait_for_msymbols (); | |
723 | 729 | if (objfile->per_bfd->minimal_symbol_count > 0) |
724 | 730 | { |
725 | 731 | int best_zero_sized = -1; |
@@ -1270,27 +1276,27 @@ struct computed_hash_values | ||
1270 | 1276 | |
1271 | 1277 | static void |
1272 | 1278 | build_minimal_symbol_hash_tables |
1273 | - (struct objfile *objfile, | |
1279 | + (struct objfile_per_bfd_storage *per_bfd, | |
1274 | 1280 | const std::vector<computed_hash_values>& hash_values) |
1275 | 1281 | { |
1276 | 1282 | int i; |
1277 | 1283 | struct minimal_symbol *msym; |
1278 | 1284 | |
1279 | 1285 | /* (Re)insert the actual entries. */ |
1280 | - int mcount = objfile->per_bfd->minimal_symbol_count; | |
1286 | + int mcount = per_bfd->minimal_symbol_count; | |
1281 | 1287 | for ((i = 0, |
1282 | - msym = objfile->per_bfd->msymbols.get ()); | |
1288 | + msym = per_bfd->msymbols.get ()); | |
1283 | 1289 | i < mcount; |
1284 | 1290 | i++, msym++) |
1285 | 1291 | { |
1286 | 1292 | msym->hash_next = 0; |
1287 | - add_minsym_to_hash_table (msym, objfile->per_bfd->msymbol_hash, | |
1293 | + add_minsym_to_hash_table (msym, per_bfd->msymbol_hash, | |
1288 | 1294 | hash_values[i].minsym_hash); |
1289 | 1295 | |
1290 | 1296 | msym->demangled_hash_next = 0; |
1291 | 1297 | if (MSYMBOL_SEARCH_NAME (msym) != MSYMBOL_LINKAGE_NAME (msym)) |
1292 | 1298 | add_minsym_to_demangled_hash_table |
1293 | - (msym, objfile, hash_values[i].minsym_demangled_hash); | |
1299 | + (msym, per_bfd, hash_values[i].minsym_demangled_hash); | |
1294 | 1300 | } |
1295 | 1301 | } |
1296 | 1302 |
@@ -1311,8 +1317,11 @@ minimal_symbol_reader::install () | ||
1311 | 1317 | if (m_objfile->per_bfd->minsyms_read) |
1312 | 1318 | return; |
1313 | 1319 | |
1320 | + | |
1314 | 1321 | if (m_msym_count > 0) |
1315 | 1322 | { |
1323 | + m_objfile->per_bfd->wait_for_msymbols (); | |
1324 | + | |
1316 | 1325 | if (symtab_create_debug) |
1317 | 1326 | { |
1318 | 1327 | fprintf_unfiltered (gdb_stdlog, |
@@ -1375,63 +1384,71 @@ minimal_symbol_reader::install () | ||
1375 | 1384 | m_objfile->per_bfd->minimal_symbol_count = mcount; |
1376 | 1385 | m_objfile->per_bfd->msymbols = std::move (msym_holder); |
1377 | 1386 | |
1387 | + msymbols = m_objfile->per_bfd->msymbols.get (); | |
1388 | + objfile_per_bfd_storage* per_bfd = m_objfile->per_bfd; | |
1389 | + | |
1390 | + m_objfile->per_bfd->m_minsym_future | |
1391 | + = gdb::thread_pool::g_thread_pool->post_task ([msymbols, mcount, | |
1392 | + per_bfd] () | |
1393 | + { | |
1378 | 1394 | #if CXX_STD_THREAD |
1379 | - /* Mutex that is used when modifying or accessing the demangled | |
1380 | - hash table. */ | |
1381 | - std::mutex demangled_mutex; | |
1395 | + /* Mutex that is used when modifying or accessing the demangled | |
1396 | + hash table. */ | |
1397 | + std::mutex demangled_mutex; | |
1382 | 1398 | #endif |
1383 | 1399 | |
1384 | - std::vector<computed_hash_values> hash_values (mcount); | |
1400 | + std::vector<computed_hash_values> hash_values (mcount); | |
1385 | 1401 | |
1386 | - msymbols = m_objfile->per_bfd->msymbols.get (); | |
1387 | - gdb::parallel_for_each | |
1388 | - (&msymbols[0], &msymbols[mcount], | |
1389 | - [&] (minimal_symbol *start, minimal_symbol *end) | |
1390 | - { | |
1391 | - for (minimal_symbol *msym = start; msym < end; ++msym) | |
1402 | + gdb::parallel_for_each | |
1403 | + (&msymbols[0], &msymbols[mcount], | |
1404 | + [&] (minimal_symbol *start, minimal_symbol *end) | |
1392 | 1405 | { |
1393 | - size_t idx = msym - msymbols; | |
1394 | - hash_values[idx].name_length = strlen (msym->name); | |
1395 | - if (!msym->name_set) | |
1406 | + for (minimal_symbol *msym = start; msym < end; ++msym) | |
1396 | 1407 | { |
1397 | - /* This will be freed later, by symbol_set_names. */ | |
1398 | - char *demangled_name | |
1399 | - = symbol_find_demangled_name (msym, msym->name); | |
1400 | - symbol_set_demangled_name | |
1401 | - (msym, demangled_name, | |
1402 | - &m_objfile->per_bfd->storage_obstack); | |
1403 | - msym->name_set = 1; | |
1404 | - | |
1405 | - hash_values[idx].mangled_name_hash | |
1406 | - = fast_hash (msym->name, hash_values[idx].name_length); | |
1408 | + size_t idx = msym - msymbols; | |
1409 | + hash_values[idx].name_length = strlen (msym->name); | |
1410 | + if (!msym->name_set) | |
1411 | + { | |
1412 | + /* This will be freed later, by symbol_set_names. */ | |
1413 | + char *demangled_name | |
1414 | + = symbol_find_demangled_name (msym, msym->name); | |
1415 | + symbol_set_demangled_name | |
1416 | + (msym, demangled_name, | |
1417 | + &per_bfd->storage_obstack); | |
1418 | + msym->name_set = 1; | |
1419 | + | |
1420 | + hash_values[idx].mangled_name_hash | |
1421 | + = fast_hash (msym->name, hash_values[idx].name_length); | |
1422 | + } | |
1423 | + hash_values[idx].minsym_hash | |
1424 | + = msymbol_hash (MSYMBOL_LINKAGE_NAME (msym)); | |
1425 | + hash_values[idx].minsym_demangled_hash | |
1426 | + = search_name_hash (MSYMBOL_LANGUAGE (msym), | |
1427 | + MSYMBOL_SEARCH_NAME (msym)); | |
1407 | 1428 | } |
1408 | - hash_values[idx].minsym_hash | |
1409 | - = msymbol_hash (MSYMBOL_LINKAGE_NAME (msym)); | |
1410 | - hash_values[idx].minsym_demangled_hash | |
1411 | - = search_name_hash (MSYMBOL_LANGUAGE (msym), | |
1412 | - MSYMBOL_SEARCH_NAME (msym)); | |
1413 | - } | |
1414 | - { | |
1415 | - /* To limit how long we hold the lock, we only acquire it here | |
1416 | - and not while we demangle the names above. */ | |
1429 | + { | |
1430 | + /* To limit how long we hold the lock, we only acquire it here | |
1431 | + and not while we demangle the names above. */ | |
1417 | 1432 | #if CXX_STD_THREAD |
1418 | - std::lock_guard<std::mutex> guard (demangled_mutex); | |
1433 | + std::lock_guard<std::mutex> guard (demangled_mutex); | |
1419 | 1434 | #endif |
1420 | - for (minimal_symbol *msym = start; msym < end; ++msym) | |
1421 | - { | |
1422 | - size_t idx = msym - msymbols; | |
1423 | - symbol_set_names | |
1424 | - (msym, | |
1425 | - gdb::string_view(msym->name, | |
1426 | - hash_values[idx].name_length), | |
1427 | - false, | |
1428 | - m_objfile->per_bfd, | |
1429 | - hash_values[idx].mangled_name_hash); | |
1435 | + for (minimal_symbol *msym = start; msym < end; ++msym) | |
1436 | + { | |
1437 | + size_t idx = msym - msymbols; | |
1438 | + symbol_set_names | |
1439 | + (msym, | |
1440 | + gdb::string_view(msym->name, | |
1441 | + hash_values[idx].name_length), | |
1442 | + false, | |
1443 | + per_bfd, | |
1444 | + hash_values[idx].mangled_name_hash); | |
1445 | + } | |
1430 | 1446 | } |
1431 | - } | |
1432 | - }); | |
1447 | + }); | |
1433 | 1448 | |
1434 | - build_minimal_symbol_hash_tables (m_objfile, hash_values); | |
1449 | + build_minimal_symbol_hash_tables (per_bfd, hash_values); | |
1450 | + } | |
1451 | + ); | |
1435 | 1452 | } |
1436 | 1453 | } |
1437 | 1454 |
@@ -1518,6 +1535,8 @@ minimal_symbol_upper_bound (struct bound_minimal_symbol minsym) | ||
1518 | 1535 | other sections, to find the next symbol in this section with a |
1519 | 1536 | different address. */ |
1520 | 1537 | |
1538 | + minsym.objfile->per_bfd->wait_for_msymbols (); | |
1539 | + | |
1521 | 1540 | struct minimal_symbol *past_the_end |
1522 | 1541 | = (minsym.objfile->per_bfd->msymbols.get () |
1523 | 1542 | + minsym.objfile->per_bfd->minimal_symbol_count); |
@@ -30,6 +30,9 @@ | ||
30 | 30 | #include "psymtab.h" |
31 | 31 | #include <bitset> |
32 | 32 | #include <vector> |
33 | +#if CXX_STD_THREAD | |
34 | +#include <future> | |
35 | +#endif | |
33 | 36 | #include "gdbsupport/next-iterator.h" |
34 | 37 | #include "gdbsupport/safe-iterator.h" |
35 | 38 | #include "bcache.h" |
@@ -319,6 +322,19 @@ struct objfile_per_bfd_storage | ||
319 | 322 | /* All the different languages of symbols found in the demangled |
320 | 323 | hash table. */ |
321 | 324 | std::bitset<nr_languages> demangled_hash_languages; |
325 | + | |
326 | + void wait_for_msymbols() { | |
327 | +#if CXX_STD_THREAD | |
328 | + if (m_minsym_future.valid ()) | |
329 | + { | |
330 | + m_minsym_future.wait (); | |
331 | + m_minsym_future = std::future<void> (); | |
332 | + } | |
333 | +#endif | |
334 | + } | |
335 | +#if CXX_STD_THREAD | |
336 | + std::future<void> m_minsym_future; | |
337 | +#endif | |
322 | 338 | }; |
323 | 339 | |
324 | 340 | /* An iterator that first returns a parent objfile, and then each |
@@ -439,11 +455,13 @@ struct objfile | ||
439 | 455 | |
440 | 456 | minimal_symbol_iterator begin () const |
441 | 457 | { |
458 | + m_objfile->per_bfd->wait_for_msymbols (); | |
442 | 459 | return minimal_symbol_iterator (m_objfile->per_bfd->msymbols.get ()); |
443 | 460 | } |
444 | 461 | |
445 | 462 | minimal_symbol_iterator end () const |
446 | 463 | { |
464 | + m_objfile->per_bfd->wait_for_msymbols (); | |
447 | 465 | return minimal_symbol_iterator |
448 | 466 | (m_objfile->per_bfd->msymbols.get () |
449 | 467 | + m_objfile->per_bfd->minimal_symbol_count); |