Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -319,6 +319,8 @@ static lldb::LanguageType GetLanguage(DWARFUnit &unit); + typedef std::pair FileSpecMapKey; + typedef std::map FileSpecMap; protected: typedef llvm::DenseMap DIEToTypePtr; @@ -517,6 +519,7 @@ llvm::DenseMap m_type_unit_support_files; std::vector m_lldb_cu_to_dwarf_unit; + FileSpecMap m_file_spec_map; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -224,6 +224,7 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module, const llvm::DWARFDebugLine::Prologue &prologue, FileSpec::Style style, + SymbolFileDWARF::FileSpecMap &file_spec_map, llvm::StringRef compile_dir = {}) { FileSpecList support_files; size_t first_file = 0; @@ -237,13 +238,29 @@ const size_t number_of_files = prologue.FileNames.size(); for (size_t idx = first_file; idx <= number_of_files; ++idx) { - std::string remapped_file; - if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) - if (!module->RemapSourceFile(llvm::StringRef(*file_path), remapped_file)) - remapped_file = std::move(*file_path); + FileSpec remapped_file; + // Constructing the paths and then validating when constructing the FileSpec has + // proven to be expensive in large C++ projects with lots of include files, so + // first we check if we've cached the FileSpec. + auto entry = prologue.getFileNameEntry(idx); + auto name = entry.Name.getAsCString(); + if (name) { + SymbolFileDWARF::FileSpecMapKey key = {entry.DirIdx, *name}; + auto map_entry = file_spec_map.find(key); + if (map_entry != file_spec_map.end()) { + remapped_file = map_entry->second; + } else if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) { + std::string remapped_file_name; + if (module->RemapSourceFile(llvm::StringRef(*file_path), remapped_file_name)) + remapped_file = FileSpec(remapped_file_name, style); + else + remapped_file = FileSpec(std::move(*file_path), style); + file_spec_map.emplace(key, remapped_file); + } + } // Unconditionally add an entry, so the indices match up. - support_files.EmplaceBack(remapped_file, style); + support_files.EmplaceBack(remapped_file); } return support_files; @@ -895,7 +912,7 @@ return false; comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( - comp_unit.GetModule(), prologue, dwarf_cu->GetPathStyle(), + comp_unit.GetModule(), prologue, dwarf_cu->GetPathStyle(), m_file_spec_map, dwarf_cu->GetCompilationDirectory().GetCString())); return true; @@ -942,7 +959,7 @@ report(std::move(error)); } else { list = ParseSupportFilesFromPrologue(GetObjectFile()->GetModule(), - prologue, tu.GetPathStyle()); + prologue, tu.GetPathStyle(), m_file_spec_map); } } return list;