Skip to content

Commit c647b26

Browse files
committed
Remove redundant symbol lookups in IRExecutionUnit::FindInSymbols
1 parent 3c3df1b commit c647b26

File tree

5 files changed

+201
-50
lines changed

5 files changed

+201
-50
lines changed

lldb/include/lldb/Core/ModuleList.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,24 @@ class ModuleList {
287287
const ModuleFunctionSearchOptions &options,
288288
SymbolContextList &sc_list) const;
289289

290+
/// \see Module::FindFunctions ()
291+
///
292+
/// \param[in] search_hint
293+
/// If the value is NULL, then all modules will be searched in
294+
/// order. If the value is a valid pointer and if a module is specified in
295+
/// the symbol context, that module will be searched first followed by all
296+
/// other modules in the list.
297+
/// \param[in] partial_result_handler
298+
/// A callback that will be called for each module in which at least one
299+
/// match was found.
300+
void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask,
301+
const ModuleFunctionSearchOptions &options,
302+
const SymbolContext *search_hint,
303+
llvm::function_ref<IterationAction(
304+
const lldb::ModuleSP &module,
305+
const SymbolContextList &partial_result)>
306+
partial_result_handler) const;
307+
290308
/// \see Module::FindFunctionSymbols ()
291309
void FindFunctionSymbols(ConstString name,
292310
lldb::FunctionNameType name_type_mask,
@@ -357,6 +375,31 @@ class ModuleList {
357375
lldb::SymbolType symbol_type,
358376
SymbolContextList &sc_list) const;
359377

378+
/// Find symbols by name and SymbolType.
379+
///
380+
/// \param[in] name
381+
/// A name of the symbol we are looking for.
382+
///
383+
/// \param[in] symbol_type
384+
/// A SymbolType the symbol we are looking for.
385+
///
386+
/// \param[in] search_hint
387+
/// If the value is NULL, then all modules will be searched in
388+
/// order. If the value is a valid pointer and if a module is specified in
389+
/// the symbol context, that module will be searched first followed by all
390+
/// other modules in the list.
391+
///
392+
/// \param[in] partial_result_handler
393+
/// A callback that will be called for each module in which at least one
394+
/// match was found.
395+
void FindSymbolsWithNameAndType(ConstString name,
396+
lldb::SymbolType symbol_type,
397+
const SymbolContext *search_hint,
398+
llvm::function_ref<IterationAction(
399+
const lldb::ModuleSP &module,
400+
const SymbolContextList &partial_result)>
401+
partial_result_handler) const;
402+
360403
void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
361404
lldb::SymbolType symbol_type,
362405
SymbolContextList &sc_list) const;

lldb/include/lldb/Symbol/SymbolContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ class SymbolContextList {
471471

472472
typedef AdaptedIterable<collection, SymbolContext, vector_adapter>
473473
SymbolContextIterable;
474-
SymbolContextIterable SymbolContexts() {
474+
SymbolContextIterable SymbolContexts() const {
475475
return SymbolContextIterable(m_symbol_contexts);
476476
}
477477
};

lldb/source/Core/ModuleList.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,48 @@ void ModuleList::FindFunctions(ConstString name,
466466
}
467467
}
468468

469+
void ModuleList::FindFunctions(
470+
ConstString name, lldb::FunctionNameType name_type_mask,
471+
const ModuleFunctionSearchOptions &options,
472+
const SymbolContext *search_hint,
473+
llvm::function_ref<IterationAction(const lldb::ModuleSP &module,
474+
const SymbolContextList &partial_result)>
475+
partial_result_handler) const {
476+
SymbolContextList sc_list_partial{};
477+
auto FindInModule = [&](const ModuleSP &module) {
478+
if (!module)
479+
return IterationAction::Continue;
480+
module->FindFunctions(name, CompilerDeclContext(), name_type_mask, options,
481+
sc_list_partial);
482+
if (!sc_list_partial.IsEmpty()) {
483+
auto iteration_action = partial_result_handler(module, sc_list_partial);
484+
sc_list_partial.Clear();
485+
return iteration_action;
486+
}
487+
return IterationAction::Continue;
488+
};
489+
490+
std::vector<ModuleSP> modules_copy;
491+
{
492+
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
493+
modules_copy = m_modules;
494+
}
495+
496+
auto hinted_module = search_hint ? search_hint->module_sp : nullptr;
497+
if (hinted_module) {
498+
assert(std::find(modules_copy.begin(), modules_copy.end(), hinted_module) !=
499+
modules_copy.end());
500+
if (FindInModule(hinted_module) == IterationAction::Stop)
501+
return;
502+
}
503+
for (const ModuleSP &module_sp : modules_copy) {
504+
if (module_sp != hinted_module) {
505+
if (FindInModule(module_sp) == IterationAction::Stop)
506+
return;
507+
}
508+
}
509+
}
510+
469511
void ModuleList::FindFunctionSymbols(ConstString name,
470512
lldb::FunctionNameType name_type_mask,
471513
SymbolContextList &sc_list) {
@@ -532,6 +574,44 @@ void ModuleList::FindSymbolsWithNameAndType(ConstString name,
532574
module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
533575
}
534576

577+
void ModuleList::FindSymbolsWithNameAndType(
578+
ConstString name, lldb::SymbolType symbol_type,
579+
const SymbolContext *search_hint,
580+
llvm::function_ref<IterationAction(const ModuleSP &,
581+
const SymbolContextList &)>
582+
partial_result_handler) const {
583+
SymbolContextList sc_list_partial{};
584+
auto FindInModule = [&](const ModuleSP &module) {
585+
module->FindSymbolsWithNameAndType(name, symbol_type, sc_list_partial);
586+
if (!sc_list_partial.IsEmpty()) {
587+
auto iteration_action = partial_result_handler(module, sc_list_partial);
588+
sc_list_partial.Clear();
589+
return iteration_action;
590+
}
591+
return IterationAction::Continue;
592+
};
593+
594+
595+
std::vector<ModuleSP> modules_copy;
596+
{
597+
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
598+
modules_copy = m_modules;
599+
}
600+
auto hinted_module = search_hint ? search_hint->module_sp : nullptr;
601+
if (hinted_module) {
602+
assert(std::find(modules_copy.begin(), modules_copy.end(), hinted_module) !=
603+
modules_copy.end());
604+
if (FindInModule(hinted_module) == IterationAction::Stop)
605+
return;
606+
}
607+
for (const ModuleSP &module_sp : modules_copy) {
608+
if (module_sp != hinted_module) {
609+
if (FindInModule(module_sp) == IterationAction::Stop)
610+
return;
611+
}
612+
}
613+
}
614+
535615
void ModuleList::FindSymbolsMatchingRegExAndType(
536616
const RegularExpression &regex, lldb::SymbolType symbol_type,
537617
SymbolContextList &sc_list) const {

lldb/source/Expression/IRExecutionUnit.cpp

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ class LoadAddressResolver {
704704
LoadAddressResolver(Target *target, bool &symbol_was_missing_weak)
705705
: m_target(target), m_symbol_was_missing_weak(symbol_was_missing_weak) {}
706706

707-
std::optional<lldb::addr_t> Resolve(SymbolContextList &sc_list) {
707+
std::optional<lldb::addr_t> Resolve(const SymbolContextList &sc_list) {
708708
if (sc_list.IsEmpty())
709709
return std::nullopt;
710710

@@ -791,31 +791,36 @@ IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names,
791791
function_options.include_symbols = true;
792792
function_options.include_inlines = false;
793793

794-
for (const ConstString &name : names) {
795-
if (sc.module_sp) {
796-
SymbolContextList sc_list;
797-
sc.module_sp->FindFunctions(name, CompilerDeclContext(),
798-
lldb::eFunctionNameTypeFull, function_options,
799-
sc_list);
800-
if (auto load_addr = resolver.Resolve(sc_list))
801-
return *load_addr;
802-
}
803-
804-
if (sc.target_sp) {
805-
SymbolContextList sc_list;
806-
sc.target_sp->GetImages().FindFunctions(name, lldb::eFunctionNameTypeFull,
807-
function_options, sc_list);
808-
if (auto load_addr = resolver.Resolve(sc_list))
809-
return *load_addr;
810-
}
794+
const ModuleList &images = target->GetImages();
811795

812-
if (sc.target_sp) {
813-
SymbolContextList sc_list;
814-
sc.target_sp->GetImages().FindSymbolsWithNameAndType(
815-
name, lldb::eSymbolTypeAny, sc_list);
816-
if (auto load_addr = resolver.Resolve(sc_list))
817-
return *load_addr;
818-
}
796+
for (const ConstString &name : names) {
797+
lldb::addr_t result_addr = LLDB_INVALID_ADDRESS;
798+
799+
images.FindFunctions(
800+
name, lldb::eFunctionNameTypeFull, function_options, &sc,
801+
[&](const lldb::ModuleSP &module,
802+
const SymbolContextList &partial_result) {
803+
if (auto load_addr = resolver.Resolve(partial_result)) {
804+
result_addr = *load_addr;
805+
return IterationAction::Stop;
806+
}
807+
return IterationAction::Continue;
808+
});
809+
if (result_addr != LLDB_INVALID_ADDRESS)
810+
return result_addr;
811+
812+
images.FindSymbolsWithNameAndType(
813+
name, lldb::eSymbolTypeAny, &sc,
814+
[&](const lldb::ModuleSP &module,
815+
const SymbolContextList &partial_result) {
816+
if (auto load_addr = resolver.Resolve(partial_result)) {
817+
result_addr = *load_addr;
818+
return IterationAction::Stop;
819+
}
820+
return IterationAction::Continue;
821+
});
822+
if (result_addr != LLDB_INVALID_ADDRESS)
823+
return result_addr;
819824

820825
lldb::addr_t best_internal_load_address =
821826
resolver.GetBestInternalLoadAddress();

lldb/source/Symbol/SymbolContext.cpp

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -895,31 +895,54 @@ const Symbol *SymbolContext::FindBestGlobalDataSymbol(ConstString name,
895895
}
896896
};
897897

898-
if (module) {
899-
SymbolContextList sc_list;
900-
module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
901-
const Symbol *const module_symbol = ProcessMatches(sc_list, error);
902-
903-
if (!error.Success()) {
904-
return nullptr;
905-
} else if (module_symbol) {
906-
return module_symbol;
907-
}
908-
}
909-
910-
{
911-
SymbolContextList sc_list;
912-
target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny,
913-
sc_list);
914-
const Symbol *const target_symbol = ProcessMatches(sc_list, error);
915-
916-
if (!error.Success()) {
917-
return nullptr;
918-
} else if (target_symbol) {
919-
return target_symbol;
920-
}
921-
}
898+
const Symbol *result_symbol = nullptr;
899+
target.GetImages().FindSymbolsWithNameAndType(
900+
name, eSymbolTypeAny, this,
901+
[&error, ProcessMatches, &result_symbol, &target, name,
902+
this](const lldb::ModuleSP &module,
903+
const SymbolContextList &partial_result) {
904+
const Symbol *const processed_symbol =
905+
ProcessMatches(partial_result, error);
906+
if (!error.Success()) {
907+
return IterationAction::Stop;
908+
}
909+
if (!processed_symbol)
910+
return IterationAction::Continue;
911+
if (module == this->module_sp) {
912+
// When the found symbol is in the hinted module use it even
913+
// if it's an internal one.
914+
result_symbol = processed_symbol;
915+
return IterationAction::Stop;
916+
}
917+
if (!result_symbol) {
918+
result_symbol = processed_symbol;
919+
return IterationAction::Continue;
920+
}
921+
if (result_symbol->IsExternal() == processed_symbol->IsExternal()) {
922+
assert(processed_symbol != result_symbol &&
923+
"The same symbol is found in two modules");
924+
StreamString ss;
925+
bool areBothExternal = result_symbol->IsExternal();
926+
ss.Printf("Multiple %s symbols found for '%s'\n",
927+
areBothExternal ? "external" : "internal",
928+
name.AsCString());
929+
result_symbol->GetDescription(&ss, eDescriptionLevelVerbose, &target);
930+
ss.PutChar('\n');
931+
processed_symbol->GetDescription(&ss, eDescriptionLevelVerbose,
932+
&target);
933+
ss.PutChar('\n');
934+
error.SetErrorString(ss.GetData());
935+
return IterationAction::Stop;
936+
}
937+
if (!result_symbol->IsExternal() && processed_symbol->IsExternal())
938+
result_symbol = processed_symbol;
939+
return IterationAction::Continue;
940+
});
922941

942+
if (!error.Success())
943+
return nullptr;
944+
if (result_symbol)
945+
return result_symbol;
923946
return nullptr; // no error; we just didn't find anything
924947
}
925948

0 commit comments

Comments
 (0)