From e18f4db208baa84800cf304d7e15f2ee7343cd05 Mon Sep 17 00:00:00 2001 From: shafik Date: Wed, 6 Nov 2019 15:57:52 -0800 Subject: [LLDB] Adding caching to libc++ std::function formatter for lookups that require scanning symbols Performance issues lead to the libc++ std::function formatter to be disabled. This change is the first of two changes that should address the performance issues and allow us to enable the formatter again. In some cases we end up scanning the symbol table for the callable wrapped by std::function for those cases we will now cache the results and used the cache in subsequent look-ups. This still leaves a large cost for the initial lookup which will be addressed in the next change. Differential Revision: https://reviews.llvm.org/D67111 --- .../CPlusPlus/CPPLanguageRuntime.cpp | 40 +++++++++++++++------- .../LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h | 8 +++++ 2 files changed, 35 insertions(+), 13 deletions(-) (limited to 'lldb/source/Plugins/LanguageRuntime/CPlusPlus') diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp index f38014505a8..379b0ba1b4d 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -192,14 +192,33 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( function_address_resolved, eSymbolContextEverything, sc); symbol = sc.symbol; } + + auto contains_lambda_identifier = []( llvm::StringRef & str_ref ) { + return str_ref.contains("$_") || str_ref.contains("'lambda'"); + }; - auto get_name = [&first_template_parameter, &symbol]() { + // Case 4 or 5 + // We eliminate these cases early because they don't need the potentially + // expensive lookup through the symbol table. + if (symbol && !symbol->GetName().GetStringRef().startswith("vtable for") && + !contains_lambda_identifier(first_template_parameter) && + !symbol->GetName().GetStringRef().contains("__invoke")) { + optional_info.callable_case = + LibCppStdFunctionCallableCase::FreeOrMemberFunction; + optional_info.callable_address = function_address_resolved; + optional_info.callable_symbol = *symbol; + + return optional_info; + } + + auto get_name = [&first_template_parameter, &symbol, contains_lambda_identifier]() { // Given case 1: // // main::$_0 + // Bar::add_num2(int)::'lambda'(int) // // we want to append ::operator()() - if (first_template_parameter.contains("$_")) + if (contains_lambda_identifier(first_template_parameter)) return llvm::Regex::escape(first_template_parameter.str()) + R"(::operator\(\)\(.*\))"; @@ -228,6 +247,10 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( std::string func_to_match = get_name(); + auto it = CallableLookupCache.find(func_to_match); + if (it != CallableLookupCache.end()) + return it->second; + SymbolContextList scl; target.GetImages().FindSymbolsMatchingRegExAndType( @@ -248,7 +271,7 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( LineEntry line_entry; addr.CalculateSymbolContextLineEntry(line_entry); - if (first_template_parameter.contains("$_") || + if (contains_lambda_identifier(first_template_parameter) || (symbol != nullptr && symbol->GetName().GetStringRef().contains("__invoke"))) { // Case 1 and 2 @@ -262,19 +285,10 @@ CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( optional_info.callable_symbol = *symbol; optional_info.callable_line_entry = line_entry; optional_info.callable_address = addr; - return optional_info; } } - // Case 4 or 5 - if (symbol && !symbol->GetName().GetStringRef().startswith("vtable for")) { - optional_info.callable_case = - LibCppStdFunctionCallableCase::FreeOrMemberFunction; - optional_info.callable_address = function_address_resolved; - optional_info.callable_symbol = *symbol; - - return optional_info; - } + CallableLookupCache[func_to_match] = optional_info; return optional_info; } diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h index 28526361efc..abdd79fcd7b 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h @@ -10,6 +10,9 @@ #define liblldb_CPPLanguageRuntime_h_ #include + +#include "llvm/ADT/StringMap.h" + #include "lldb/Core/PluginInterface.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/lldb-private.h" @@ -82,6 +85,11 @@ protected: CPPLanguageRuntime(Process *process); private: + using OperatorStringToCallableInfoMap = + llvm::StringMap; + + OperatorStringToCallableInfoMap CallableLookupCache; + DISALLOW_COPY_AND_ASSIGN(CPPLanguageRuntime); }; -- cgit v1.2.3