Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -14,6 +14,7 @@ // C++ Includes #include #include +#include #include #include @@ -265,32 +266,16 @@ DWARFDebugRanges* DebugRanges(); + const DWARFDebugRanges* DebugRanges() const; - virtual const lldb_private::DWARFDataExtractor& - GetCachedSectionData (uint32_t got_flag, - lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data); - static bool SupportedVersion(uint16_t version); DWARFDIE GetDeclContextDIEContainingDIE (const DWARFDIE &die); - lldb_private::Flags& - GetFlags () - { - return m_flags; - } - - const lldb_private::Flags& - GetFlags () const - { - return m_flags; - } - bool HasForwardDeclForClangType (const lldb_private::CompilerType &compiler_type); @@ -326,27 +311,25 @@ typedef llvm::DenseMap DIEToClangType; typedef llvm::DenseMap ClangTypeToDIE; - enum + struct DWARFDataSegment { - flagsGotDebugAbbrevData = (1 << 0), - flagsGotDebugAddrData = (1 << 1), - flagsGotDebugArangesData = (1 << 2), - flagsGotDebugFrameData = (1 << 3), - flagsGotDebugInfoData = (1 << 4), - flagsGotDebugLineData = (1 << 5), - flagsGotDebugLocData = (1 << 6), - flagsGotDebugMacInfoData = (1 << 7), - flagsGotDebugPubNamesData = (1 << 8), - flagsGotDebugPubTypesData = (1 << 9), - flagsGotDebugRangesData = (1 << 10), - flagsGotDebugStrData = (1 << 11), - flagsGotDebugStrOffsetsData = (1 << 12), - flagsGotAppleNamesData = (1 << 13), - flagsGotAppleTypesData = (1 << 14), - flagsGotAppleNamespacesData = (1 << 15), - flagsGotAppleObjCData = (1 << 16) + DWARFDataSegment() : + m_is_set (false) + {} + + lldb_private::DWARFDataExtractor m_data; + std::atomic_bool m_is_set; + std::mutex m_mutex; }; - + + DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF); + + const lldb_private::DWARFDataExtractor& + GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment); + + virtual const lldb_private::DWARFDataExtractor& + GetSectionDataNoLock (lldb::SectionType sect_type, DWARFDataSegment& data_segment); + bool DeclContextMatchesThisSymbolFile (const lldb_private::CompilerDeclContext *decl_ctx); @@ -354,8 +337,6 @@ DIEInDeclContext (const lldb_private::CompilerDeclContext *parent_decl_ctx, const DWARFDIE &die); - DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF); - virtual DWARFCompileUnit* GetDWARFCompileUnit (lldb_private::CompileUnit *comp_unit); @@ -542,22 +523,22 @@ lldb::ModuleWP m_debug_map_module_wp; SymbolFileDWARFDebugMap * m_debug_map_symfile; - lldb_private::Flags m_flags; - lldb_private::DWARFDataExtractor m_dwarf_data; - lldb_private::DWARFDataExtractor m_data_debug_abbrev; - lldb_private::DWARFDataExtractor m_data_debug_addr; - lldb_private::DWARFDataExtractor m_data_debug_aranges; - lldb_private::DWARFDataExtractor m_data_debug_frame; - lldb_private::DWARFDataExtractor m_data_debug_info; - lldb_private::DWARFDataExtractor m_data_debug_line; - lldb_private::DWARFDataExtractor m_data_debug_loc; - lldb_private::DWARFDataExtractor m_data_debug_ranges; - lldb_private::DWARFDataExtractor m_data_debug_str; - lldb_private::DWARFDataExtractor m_data_debug_str_offsets; - lldb_private::DWARFDataExtractor m_data_apple_names; - lldb_private::DWARFDataExtractor m_data_apple_types; - lldb_private::DWARFDataExtractor m_data_apple_namespaces; - lldb_private::DWARFDataExtractor m_data_apple_objc; + + DWARFDataSegment m_dwarf_data; + DWARFDataSegment m_data_debug_abbrev; + DWARFDataSegment m_data_debug_addr; + DWARFDataSegment m_data_debug_aranges; + DWARFDataSegment m_data_debug_frame; + DWARFDataSegment m_data_debug_info; + DWARFDataSegment m_data_debug_line; + DWARFDataSegment m_data_debug_loc; + DWARFDataSegment m_data_debug_ranges; + DWARFDataSegment m_data_debug_str; + DWARFDataSegment m_data_debug_str_offsets; + DWARFDataSegment m_data_apple_names; + DWARFDataSegment m_data_apple_types; + DWARFDataSegment m_data_apple_namespaces; + DWARFDataSegment m_data_apple_objc; // The unique pointer items below are generated on demand if and when someone accesses // them through a non const version of this class. Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -429,7 +429,6 @@ UserID (0), // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID m_debug_map_module_wp (), m_debug_map_symfile (NULL), - m_flags(), m_data_debug_abbrev (), m_data_debug_aranges (), m_data_debug_frame (), @@ -509,47 +508,62 @@ if (module_sp) { const SectionList *section_list = module_sp->GetSectionList(); - const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get(); // Memory map the DWARF mach-o segment so we have everything mmap'ed // to keep our heap memory usage down. if (section) - m_obj_file->MemoryMapSectionData(section, m_dwarf_data); + { + std::lock_guard lock(m_dwarf_data.m_mutex); + m_obj_file->MemoryMapSectionData(section, m_dwarf_data.m_data); + } } - get_apple_names_data(); - if (m_data_apple_names.GetByteSize() > 0) + + const DWARFDataExtractor& data_apple_names = get_apple_names_data(); + if (data_apple_names.GetByteSize() > 0) { - m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names")); + std::lock_guard lock(m_data_apple_names.m_mutex); + m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names.m_data, + get_debug_str_data(), + ".apple_names")); if (m_apple_names_ap->IsValid()) m_using_apple_tables = true; else m_apple_names_ap.reset(); } - get_apple_types_data(); - if (m_data_apple_types.GetByteSize() > 0) + const DWARFDataExtractor& data_apple_types = get_apple_types_data(); + if (data_apple_types.GetByteSize() > 0) { - m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types")); + std::lock_guard lock(m_data_apple_types.m_mutex); + m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types.m_data, + get_debug_str_data(), + ".apple_types")); if (m_apple_types_ap->IsValid()) m_using_apple_tables = true; else m_apple_types_ap.reset(); } - get_apple_namespaces_data(); - if (m_data_apple_namespaces.GetByteSize() > 0) + const DWARFDataExtractor& data_apple_namespaces = get_apple_namespaces_data(); + if (data_apple_namespaces.GetByteSize() > 0) { - m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces")); + std::lock_guard lock(m_data_apple_namespaces.m_mutex); + m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces.m_data, + get_debug_str_data(), + ".apple_namespaces")); if (m_apple_namespaces_ap->IsValid()) m_using_apple_tables = true; else m_apple_namespaces_ap.reset(); } - get_apple_objc_data(); - if (m_data_apple_objc.GetByteSize() > 0) + const DWARFDataExtractor& data_apple_objc = get_apple_objc_data(); + if (data_apple_objc.GetByteSize() > 0) { - m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc")); + std::lock_guard lock(m_data_apple_objc.m_mutex); + m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc.m_data, + get_debug_str_data(), + ".apple_objc")); if (m_apple_objc_ap->IsValid()) m_using_apple_tables = true; else @@ -592,45 +606,37 @@ if (section) debug_abbrev_file_size = section->GetFileSize(); else - m_flags.Set (flagsGotDebugAbbrevData); + m_data_debug_abbrev.m_is_set.store(true); section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get(); if (!section) - m_flags.Set (flagsGotDebugArangesData); + m_data_debug_aranges.m_is_set.store(true); section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get(); if (!section) - m_flags.Set (flagsGotDebugFrameData); + m_data_debug_frame.m_is_set.store(true); section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get(); if (section) debug_line_file_size = section->GetFileSize(); else - m_flags.Set (flagsGotDebugLineData); + m_data_debug_line.m_is_set.store(true); section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get(); if (!section) - m_flags.Set (flagsGotDebugLocData); + m_data_debug_loc.m_is_set.store(true); section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get(); - if (!section) - m_flags.Set (flagsGotDebugMacInfoData); - section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get(); - if (!section) - m_flags.Set (flagsGotDebugPubNamesData); - section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get(); - if (!section) - m_flags.Set (flagsGotDebugPubTypesData); section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get(); if (!section) - m_flags.Set (flagsGotDebugRangesData); + m_data_debug_ranges.m_is_set.store(true); section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get(); if (!section) - m_flags.Set (flagsGotDebugStrData); + m_data_debug_str.m_is_set.store(true); } else { @@ -665,116 +671,133 @@ } const DWARFDataExtractor& -SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data) +SymbolFileDWARF::GetCachedSectionData (lldb::SectionType sect_type, DWARFDataSegment& data_segment) { - if (m_flags.IsClear (got_flag)) + // Return the data without locking the mutex if it is already set + if (data_segment.m_is_set.load()) + return data_segment.m_data; + + std::lock_guard lock(data_segment.m_mutex); + + // Check again if the data is set as it can be loaded while we were waiting for the mutex + if (data_segment.m_is_set.load()) + return data_segment.m_data; + + return GetSectionDataNoLock (sect_type, data_segment); +} + +const DWARFDataExtractor& +SymbolFileDWARF::GetSectionDataNoLock (lldb::SectionType sect_type, DWARFDataSegment& data_segment) +{ + ModuleSP module_sp (m_obj_file->GetModule()); + const SectionList *section_list = module_sp->GetSectionList(); + if (section_list) { - ModuleSP module_sp (m_obj_file->GetModule()); - m_flags.Set (got_flag); - const SectionList *section_list = module_sp->GetSectionList(); - if (section_list) + SectionSP section_sp (section_list->FindSectionByType(sect_type, true)); + if (section_sp) { - SectionSP section_sp (section_list->FindSectionByType(sect_type, true)); - if (section_sp) + // See if we memory mapped the DWARF segment? + std::lock_guard dwarf_data_lock(m_dwarf_data.m_mutex); + if (m_dwarf_data.m_data.GetByteSize()) { - // See if we memory mapped the DWARF segment? - if (m_dwarf_data.GetByteSize()) - { - data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize()); - } - else - { - if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0) - data.Clear(); - } + data_segment.m_data.SetData(m_dwarf_data.m_data, + section_sp->GetOffset (), + section_sp->GetFileSize()); + } + else + { + if (m_obj_file->ReadSectionData (section_sp.get(), data_segment.m_data) == 0) + data_segment.m_data.Clear(); } } } - return data; + data_segment.m_is_set.store(true); + + return data_segment.m_data; } const DWARFDataExtractor& SymbolFileDWARF::get_debug_abbrev_data() { - return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); + return GetCachedSectionData (eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_addr_data() { - return GetCachedSectionData (flagsGotDebugAddrData, eSectionTypeDWARFDebugAddr, m_data_debug_addr); + return GetCachedSectionData (eSectionTypeDWARFDebugAddr, m_data_debug_addr); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_aranges_data() { - return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges); + return GetCachedSectionData (eSectionTypeDWARFDebugAranges, m_data_debug_aranges); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_frame_data() { - return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame); + return GetCachedSectionData (eSectionTypeDWARFDebugFrame, m_data_debug_frame); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_info_data() { - return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info); + return GetCachedSectionData (eSectionTypeDWARFDebugInfo, m_data_debug_info); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_line_data() { - return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line); + return GetCachedSectionData (eSectionTypeDWARFDebugLine, m_data_debug_line); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_loc_data() { - return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc); + return GetCachedSectionData (eSectionTypeDWARFDebugLoc, m_data_debug_loc); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_ranges_data() { - return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges); + return GetCachedSectionData (eSectionTypeDWARFDebugRanges, m_data_debug_ranges); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_str_data() { - return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str); + return GetCachedSectionData (eSectionTypeDWARFDebugStr, m_data_debug_str); } const DWARFDataExtractor& SymbolFileDWARF::get_debug_str_offsets_data() { - return GetCachedSectionData (flagsGotDebugStrOffsetsData, eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets); + return GetCachedSectionData (eSectionTypeDWARFDebugStrOffsets, m_data_debug_str_offsets); } const DWARFDataExtractor& SymbolFileDWARF::get_apple_names_data() { - return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names); + return GetCachedSectionData (eSectionTypeDWARFAppleNames, m_data_apple_names); } const DWARFDataExtractor& SymbolFileDWARF::get_apple_types_data() { - return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types); + return GetCachedSectionData (eSectionTypeDWARFAppleTypes, m_data_apple_types); } const DWARFDataExtractor& SymbolFileDWARF::get_apple_namespaces_data() { - return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces); + return GetCachedSectionData (eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces); } const DWARFDataExtractor& SymbolFileDWARF::get_apple_objc_data() { - return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc); + return GetCachedSectionData (eSectionTypeDWARFAppleObjC, m_data_apple_objc); } Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -23,11 +23,6 @@ ~SymbolFileDWARFDwo() override = default; - const lldb_private::DWARFDataExtractor& - GetCachedSectionData(uint32_t got_flag, - lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) override; - lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) override; @@ -44,6 +39,9 @@ GetTypeSystemForLanguage(lldb::LanguageType language) override; protected: + const lldb_private::DWARFDataExtractor& + GetSectionDataNoLock(lldb::SectionType sect_type, DWARFDataSegment& data_segment) override; + DIEToTypePtr& GetDIEToType() override; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -28,13 +28,9 @@ } const lldb_private::DWARFDataExtractor& -SymbolFileDWARFDwo::GetCachedSectionData(uint32_t got_flag, - lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) +SymbolFileDWARFDwo::GetSectionDataNoLock(lldb::SectionType sect_type, + DWARFDataSegment& data_segment) { - if (!m_flags.IsClear (got_flag)) - return data; - const SectionList* section_list = m_obj_file->GetSectionList(false /* update_module_section_list */); if (section_list) { @@ -42,23 +38,27 @@ if (section_sp) { // See if we memory mapped the DWARF segment? - if (m_dwarf_data.GetByteSize()) + std::lock_guard dwarf_data_lock(m_dwarf_data.m_mutex); + if (m_dwarf_data.m_data.GetByteSize()) { - data.SetData(m_dwarf_data, section_sp->GetOffset(), section_sp->GetFileSize()); - m_flags.Set (got_flag); - return data; + data_segment.m_data.SetData(m_dwarf_data.m_data, + section_sp->GetOffset (), + section_sp->GetFileSize()); + data_segment.m_is_set.store(true); + return data_segment.m_data; } - if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) + if (m_obj_file->ReadSectionData(section_sp.get(), data_segment.m_data) != 0) { - m_flags.Set (got_flag); - return data; + data_segment.m_is_set.store(true); + return data_segment.m_data; } - data.Clear(); + data_segment.m_data.Clear(); } } - return SymbolFileDWARF::GetCachedSectionData(got_flag, sect_type, data); + + return SymbolFileDWARF::GetSectionDataNoLock(sect_type, data_segment); } lldb::CompUnitSP