friss created this revision.
friss added reviewers: clayborg, labath, jingham.
Herald added subscribers: JDevlieghere, aprantl.

Debug information is read lazily so a lot of the state of the reader
is constructred incrementally. There's also nothing preventing symbol
queries to be performed at the same time by multiple threads. This
lead to a series of crashes where the data structures used for
bookkeeping got corrupted because of concurrent modification.

This patch uses a brute-force approach where every such data-structure
got converted to a thread-safe version. I'm happy to discuss
alternatives, and also to hear ideas about whatever preformance testing
I can do to asses the impact of this patch.


https://reviews.llvm.org/D48393

Files:
  include/lldb/Core/ThreadSafeDenseMap.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -20,12 +20,12 @@
 #include <vector>
 
 // Other libraries and framework includes
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/Support/Threading.h"
 
 #include "lldb/Utility/Flags.h"
 
 #include "lldb/Core/RangeMap.h"
+#include "lldb/Core/ThreadSafeDenseMap.h"
 #include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/Core/dwarf.h"
 #include "lldb/Expression/DWARFExpression.h"
@@ -319,14 +319,17 @@
   void Dump(lldb_private::Stream &s) override;
 
 protected:
-  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
+  typedef lldb_private::ThreadSafeDenseMap<const DWARFDebugInfoEntry *,
+                                           lldb_private::Type *>
       DIEToTypePtr;
-  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
+  typedef lldb_private::ThreadSafeDenseMap<const DWARFDebugInfoEntry *,
+                                           lldb::VariableSP>
       DIEToVariableSP;
-  typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
-                         lldb::opaque_compiler_type_t>
+  typedef lldb_private::ThreadSafeDenseMap<const DWARFDebugInfoEntry *,
+                                           lldb::opaque_compiler_type_t>
       DIEToClangType;
-  typedef llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> ClangTypeToDIE;
+  typedef lldb_private::ThreadSafeDenseMap<lldb::opaque_compiler_type_t, DIERef>
+      ClangTypeToDIE;
 
   struct DWARFDataSegment {
     llvm::once_flag m_flag;
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1413,8 +1413,9 @@
     const CompilerType &compiler_type) {
   CompilerType compiler_type_no_qualifiers =
       ClangUtil::RemoveFastQualifiers(compiler_type);
-  if (GetForwardDeclClangTypeToDie().count(
-          compiler_type_no_qualifiers.GetOpaqueQualType())) {
+  DIERef ref;
+  if (GetForwardDeclClangTypeToDie().Lookup(
+          compiler_type_no_qualifiers.GetOpaqueQualType(), ref)) {
     return true;
   }
   TypeSystem *type_system = compiler_type.GetTypeSystem();
@@ -1445,22 +1446,23 @@
   // We have a struct/union/class/enum that needs to be fully resolved.
   CompilerType compiler_type_no_qualifiers =
       ClangUtil::RemoveFastQualifiers(compiler_type);
-  auto die_it = GetForwardDeclClangTypeToDie().find(
-      compiler_type_no_qualifiers.GetOpaqueQualType());
-  if (die_it == GetForwardDeclClangTypeToDie().end()) {
+  DIERef ref;
+  if (!GetForwardDeclClangTypeToDie().Lookup(
+          compiler_type_no_qualifiers.GetOpaqueQualType(), ref)) {
     // We have already resolved this type...
     return true;
   }
 
-  DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
+  DWARFDIE dwarf_die = GetDIE(ref);
   if (dwarf_die) {
     // Once we start resolving this type, remove it from the forward
     // declaration map in case anyone child members or other types require this
     // type to get resolved. The type will get resolved when all of the calls
     // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done.
-    GetForwardDeclClangTypeToDie().erase(die_it);
+    GetForwardDeclClangTypeToDie().Erase(
+        compiler_type_no_qualifiers.GetOpaqueQualType());
 
-    Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
+    Type *type = GetDIEToType().Lookup(dwarf_die.GetDIE());
 
     Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO |
                                           DWARF_LOG_TYPE_COMPLETION));
@@ -2587,7 +2589,7 @@
                                       bool resolve_function_context) {
   TypeSP type_sp;
   if (die) {
-    Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
+    Type *type_ptr = GetDIEToType().Lookup(die.GetDIE());
     if (type_ptr == NULL) {
       CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
       assert(lldb_cu);
@@ -2764,7 +2766,7 @@
                            type_die.GetID(), type_cu->GetID());
 
               if (die)
-                GetDIEToType()[die.GetDIE()] = resolved_type;
+                GetDIEToType().Set(die.GetDIE(), resolved_type);
               type_sp = resolved_type->shared_from_this();
               break;
             }
@@ -3171,7 +3173,7 @@
   if (!die)
     return var_sp;
 
-  var_sp = GetDIEToVariable()[die.GetDIE()];
+  var_sp = GetDIEToVariable().Lookup(die.GetDIE());
   if (var_sp)
     return var_sp; // Already been parsed!
 
@@ -3570,9 +3572,9 @@
     // missing vital information to be able to be displayed in the debugger
     // (missing location due to optimization, etc)) so we don't re-parse this
     // DIE over and over later...
-    GetDIEToVariable()[die.GetDIE()] = var_sp;
+    GetDIEToVariable().Set(die.GetDIE(), var_sp);
     if (spec_die)
-      GetDIEToVariable()[spec_die.GetDIE()] = var_sp;
+      GetDIEToVariable().Set(spec_die.GetDIE(), var_sp);
   }
   return var_sp;
 }
@@ -3637,7 +3639,7 @@
     dw_tag_t tag = die.Tag();
 
     // Check to see if we have already parsed this variable or constant?
-    VariableSP var_sp = GetDIEToVariable()[die.GetDIE()];
+    VariableSP var_sp = GetDIEToVariable().Lookup(die.GetDIE());
     if (var_sp) {
       if (cc_variable_list)
         cc_variable_list->AddVariableIfUnique(var_sp);
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
@@ -20,7 +20,7 @@
 
 TypeSP DWARFASTParserOCaml::ParseBaseTypeFromDIE(const DWARFDIE &die) {
   SymbolFileDWARF *dwarf = die.GetDWARF();
-  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+  dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
   ConstString type_name;
   uint64_t byte_size = 0;
@@ -65,7 +65,7 @@
 
   SymbolFileDWARF *dwarf = die.GetDWARF();
 
-  Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
+  Type *type_ptr = dwarf->m_die_to_type.Lookup(die.GetDIE());
   if (type_ptr == DIE_IS_BEING_PARSED)
     return nullptr;
   if (type_ptr != nullptr)
@@ -112,7 +112,7 @@
     type_sp->SetSymbolContextScope(symbol_context_scope);
 
   dwarf->GetTypeList()->Insert(type_sp);
-  dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+  dwarf->m_die_to_type.Set(die.GetDIE(), type_sp.get());
 
   return type_sp;
 }
@@ -175,7 +175,7 @@
             decl_line, decl_column));
 
       SymbolFileDWARF *dwarf = die.GetDWARF();
-      Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
+      Type *func_type = dwarf->m_die_to_type.Lookup(die.GetDIE());
 
       assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
 
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
@@ -29,7 +29,7 @@
 
 TypeSP DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die) {
   SymbolFileDWARF *dwarf = die.GetDWARF();
-  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+  dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
   ConstString type_name;
   uint64_t byte_size = 0;
@@ -64,7 +64,7 @@
 
 TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) {
   SymbolFileDWARF *dwarf = die.GetDWARF();
-  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+  dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
   ConstString linkage_name;
   DWARFFormValue type_attr_value;
@@ -142,7 +142,7 @@
 
 TypeSP DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die) {
   SymbolFileDWARF *dwarf = die.GetDWARF();
-  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+  dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
   Declaration decl;
   DWARFFormValue type_attr_value;
@@ -182,7 +182,7 @@
 lldb::TypeSP DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die,
                                                        bool &is_new_type) {
   SymbolFileDWARF *dwarf = die.GetDWARF();
-  dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+  dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
   Declaration decl;
   ConstString name;
@@ -223,8 +223,8 @@
       if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1,
                                                  unique_ast_entry)) {
         if (unique_ast_entry.m_type_sp) {
-          dwarf->GetDIEToType()[die.GetDIE()] =
-              unique_ast_entry.m_type_sp.get();
+          dwarf->GetDIEToType().Set(die.GetDIE(),
+                                    unique_ast_entry.m_type_sp.get());
           is_new_type = false;
           return unique_ast_entry.m_type_sp;
         }
@@ -239,14 +239,14 @@
     TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
     if (type_sp) {
       // We found a real definition for this type elsewhere so lets use it
-      dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+      dwarf->GetDIEToType().Set(die.GetDIE(), type_sp.get());
       is_new_type = false;
       return type_sp;
     }
   }
 
   CompilerType compiler_type(
-      &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+      &m_ast, dwarf->GetForwardDeclDieToClangType().Lookup(die.GetDIE()));
   if (!compiler_type)
     compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size);
 
@@ -266,10 +266,10 @@
   if (!is_forward_declaration) {
     // Leave this as a forward declaration until we need to know the details of
     // the type
-    dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
-        compiler_type.GetOpaqueQualType();
-    dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] =
-        die.GetDIERef();
+    dwarf->GetForwardDeclDieToClangType().Set(
+        die.GetDIE(), compiler_type.GetOpaqueQualType());
+    dwarf->GetForwardDeclClangTypeToDie().Set(compiler_type.GetOpaqueQualType(),
+                                              die.GetDIERef());
   }
   return type_sp;
 }
@@ -285,7 +285,7 @@
 
   SymbolFileDWARF *dwarf = die.GetDWARF();
 
-  Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
+  Type *type_ptr = dwarf->m_die_to_type.Lookup(die.GetDIE());
   if (type_ptr == DIE_IS_BEING_PARSED)
     return nullptr;
   if (type_ptr != nullptr)
@@ -338,7 +338,7 @@
     type_sp->SetSymbolContextScope(symbol_context_scope);
 
   dwarf->GetTypeList()->Insert(type_sp);
-  dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+  dwarf->m_die_to_type.Set(die.GetDIE(), type_sp.get());
 
   return type_sp;
 }
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -64,7 +64,7 @@
           die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName());
     }
 
-    Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE());
+    Type *type_ptr = dwarf->m_die_to_type.Lookup(die.GetDIE());
     TypeList *type_list = dwarf->GetTypeList();
     if (type_ptr == NULL) {
       if (type_is_new_ptr)
@@ -93,7 +93,7 @@
       case DW_TAG_typedef:
       case DW_TAG_unspecified_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
         const size_t num_attributes = die.GetAttributes(attributes);
         lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
@@ -159,7 +159,7 @@
             if (go_kind == 0 && type->GetName() == type_name_const_str) {
               // Go emits extra typedefs as a forward declaration. Ignore
               // these.
-              dwarf->m_die_to_type[die.GetDIE()] = type;
+              dwarf->m_die_to_type.Set(die.GetDIE(), type);
               return type->shared_from_this();
             }
             impl = type->GetForwardCompilerType();
@@ -174,12 +174,12 @@
                                encoding_data_type, &decl, compiler_type,
                                resolve_state));
 
-        dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+        dwarf->m_die_to_type.Set(die.GetDIE(), type_sp.get());
       } break;
 
       case DW_TAG_structure_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
         bool byte_size_valid = false;
 
         const size_t num_attributes = die.GetAttributes(attributes);
@@ -231,7 +231,7 @@
           // compile unit.
           type_sp = unique_ast_entry_ap->m_type_sp;
           if (type_sp) {
-            dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+            dwarf->m_die_to_type.Set(die.GetDIE(), type_sp.get());
             return type_sp;
           }
         }
@@ -242,7 +242,7 @@
         bool compiler_type_was_created = false;
         compiler_type.SetCompilerType(
             &m_ast,
-            dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE()));
+            dwarf->m_forward_decl_die_to_clang_type.Lookup(die.GetDIE()));
         if (!compiler_type) {
           compiler_type_was_created = true;
           compiler_type =
@@ -278,20 +278,19 @@
             // the SymbolFile virtual function
             // "SymbolFileDWARF::CompleteType(Type *)" When the definition
             // needs to be defined.
-            dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] =
-                compiler_type.GetOpaqueQualType();
-            dwarf->m_forward_decl_clang_type_to_die[compiler_type
-                                                        .GetOpaqueQualType()] =
-                die.GetDIERef();
+            dwarf->m_forward_decl_die_to_clang_type.Set(
+                die.GetDIE(), compiler_type.GetOpaqueQualType());
+            dwarf->m_forward_decl_clang_type_to_die.Set(
+                compiler_type.GetOpaqueQualType(), die.GetDIERef());
             // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true);
           }
         }
       } break;
 
       case DW_TAG_subprogram:
       case DW_TAG_subroutine_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
         bool is_variadic = false;
         clang::StorageClass storage =
@@ -351,7 +350,7 @@
 
       case DW_TAG_array_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->m_die_to_type.Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
         lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
         int64_t first_index = 0;
@@ -449,7 +448,7 @@
         // level
         type_list->Insert(type_sp);
 
-        dwarf->m_die_to_type[die.GetDIE()] = type_sp.get();
+        dwarf->m_die_to_type.Set(die.GetDIE(), type_sp.get());
       }
     } else if (type_ptr != DIE_IS_BEING_PARSED) {
       type_sp = type_ptr->shared_from_this();
@@ -748,7 +747,7 @@
 
       SymbolFileDWARF *dwarf = die.GetDWARF();
       // Supply the type _only_ if it has already been parsed
-      Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE());
+      Type *func_type = dwarf->m_die_to_type.Lookup(die.GetDIE());
 
       assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
 
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -14,15 +14,15 @@
 // C++ Includes
 // Other libraries and framework includes
 #include "clang/AST/CharUnits.h"
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 
 // Project includes
 #include "DWARFASTParser.h"
 #include "DWARFDefines.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/ThreadSafeDenseMap.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/ClangASTImporter.h"
 
@@ -140,15 +140,18 @@
   lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
 
   typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
-  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
+  typedef lldb_private::ThreadSafeDenseMap<const DWARFDebugInfoEntry *,
+                                           clang::DeclContext *>
       DIEToDeclContextMap;
-  // typedef llvm::DenseMap<const clang::DeclContext *, DIEPointerSet>
-  // DeclContextToDIEMap;
-  typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
+  typedef std::vector<DWARFDIE> DIEList;
+  typedef lldb_private::ThreadSafeDenseMap<const clang::DeclContext *,
+                                           std::unique_ptr<DIEList>>
       DeclContextToDIEMap;
-  typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
+  typedef lldb_private::ThreadSafeDenseMap<const DWARFDebugInfoEntry *,
+                                           clang::Decl *>
       DIEToDeclMap;
-  typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap;
+  typedef lldb_private::ThreadSafeDenseMap<const clang::Decl *, DIEPointerSet>
+      DeclToDIEMap;
 
   lldb_private::ClangASTContext &m_ast;
   DIEToDeclMap m_die_to_decl;
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -189,7 +189,7 @@
       &dwo_type_sp->GetDeclaration(), type, Type::eResolveStateForward));
 
   dwarf->GetTypeList()->Insert(type_sp);
-  dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+  dwarf->GetDIEToType().Set(die.GetDIE(), type_sp.get());
   clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
   if (tag_decl)
     LinkDeclContextToDIE(tag_decl, die);
@@ -250,7 +250,7 @@
           die.GetOffset(), static_cast<void *>(context),
           context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
     }
-    Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
+    Type *type_ptr = dwarf->GetDIEToType().Lookup(die.GetDIE());
     TypeList *type_list = dwarf->GetTypeList();
     if (type_ptr == NULL) {
       if (type_is_new_ptr)
@@ -284,7 +284,7 @@
       case DW_TAG_volatile_type:
       case DW_TAG_unspecified_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->GetDIEToType().Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
         const size_t num_attributes = die.GetAttributes(attributes);
         uint32_t encoding = 0;
@@ -535,14 +535,14 @@
                      DIERef(encoding_uid).GetUID(dwarf), encoding_data_type,
                      &decl, clang_type, resolve_state));
 
-        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+        dwarf->GetDIEToType().Set(die.GetDIE(), type_sp.get());
       } break;
 
       case DW_TAG_structure_type:
       case DW_TAG_union_type:
       case DW_TAG_class_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->GetDIEToType().Set(die.GetDIE(), DIE_IS_BEING_PARSED);
         bool byte_size_valid = false;
 
         LanguageType class_language = eLanguageTypeUnknown;
@@ -648,7 +648,7 @@
                   byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
             type_sp = unique_ast_entry_ap->m_type_sp;
             if (type_sp) {
-              dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+              dwarf->GetDIEToType().Set(die.GetDIE(), type_sp.get());
               return type_sp;
             }
           }
@@ -723,7 +723,7 @@
               // We found a real definition for this type elsewhere so lets use
               // it and cache the fact that we found a complete type for this
               // die
-              dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+              dwarf->GetDIEToType().Set(die.GetDIE(), type_sp.get());
               return type_sp;
             }
           }
@@ -779,7 +779,7 @@
 
             // We found a real definition for this type elsewhere so lets use
             // it and cache the fact that we found a complete type for this die
-            dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+            dwarf->GetDIEToType().Set(die.GetDIE(), type_sp.get());
             clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
                 dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
             if (defn_decl_ctx)
@@ -790,7 +790,7 @@
         assert(tag_decl_kind != -1);
         bool clang_type_was_created = false;
         clang_type.SetCompilerType(
-            &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+            &m_ast, dwarf->GetForwardDeclDieToClangType().Lookup(die.GetDIE()));
         if (!clang_type) {
           clang::DeclContext *decl_ctx =
               GetClangDeclContextContainingDIE(die, nullptr);
@@ -949,18 +949,21 @@
             // the SymbolFile virtual function
             // "SymbolFileDWARF::CompleteType(Type *)" When the definition
             // needs to be defined.
-            assert(!dwarf->GetForwardDeclClangTypeToDie().count(
+            DIERef ref;
+            (void)ref;
+            assert(!dwarf->GetForwardDeclClangTypeToDie().Lookup(
                        ClangUtil::RemoveFastQualifiers(clang_type)
-                           .GetOpaqueQualType()) &&
+                           .GetOpaqueQualType(),
+                       ref) &&
                    "Type already in the forward declaration map!");
             // Can't assume m_ast.GetSymbolFile() is actually a
             // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
             // binaries.
-            dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
-                clang_type.GetOpaqueQualType();
-            dwarf->GetForwardDeclClangTypeToDie()
-                [ClangUtil::RemoveFastQualifiers(clang_type)
-                     .GetOpaqueQualType()] = die.GetDIERef();
+            dwarf->GetForwardDeclDieToClangType().Set(
+                die.GetDIE(), clang_type.GetOpaqueQualType());
+            dwarf->GetForwardDeclClangTypeToDie().Set(
+                ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(),
+                die.GetDIERef());
             m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
           }
         }
@@ -981,7 +984,7 @@
 
       case DW_TAG_enumeration_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->GetDIEToType().Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
         bool is_scoped = false;
         DWARFFormValue encoding_form;
@@ -1075,7 +1078,7 @@
               // We found a real definition for this type elsewhere so lets use
               // it and cache the fact that we found a complete type for this
               // die
-              dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+              dwarf->GetDIEToType().Set(die.GetDIE(), type_sp.get());
               clang::DeclContext *defn_decl_ctx =
                   GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(
                       DIERef(type_sp->GetID(), dwarf)));
@@ -1090,7 +1093,7 @@
           CompilerType enumerator_clang_type;
           clang_type.SetCompilerType(
               &m_ast,
-              dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+              dwarf->GetForwardDeclDieToClangType().Lookup(die.GetDIE()));
           if (!clang_type) {
             if (encoding_form.IsValid()) {
               Type *enumerator_type =
@@ -1148,7 +1151,7 @@
       case DW_TAG_subprogram:
       case DW_TAG_subroutine_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->GetDIEToType().Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
         DWARFFormValue type_die_form;
         bool is_variadic = false;
@@ -1421,7 +1424,7 @@
                     // don't like having stuff added to them after their
                     // definitions are complete...
 
-                    type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+                    type_ptr = dwarf->GetDIEToType().Lookup(die.GetDIE());
                     if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
                       type_sp = type_ptr->shared_from_this();
                       break;
@@ -1578,7 +1581,7 @@
                       // we need to modify the dwarf->GetDIEToType() so it
                       // doesn't think we are trying to parse this DIE
                       // anymore...
-                      dwarf->GetDIEToType()[die.GetDIE()] = NULL;
+                      dwarf->GetDIEToType().Set(die.GetDIE(), NULL);
 
                       // Now we get the full type to force our class type to
                       // complete itself using the clang::ExternalASTSource
@@ -1588,7 +1591,7 @@
 
                       // The type for this DIE should have been filled in the
                       // function call above
-                      type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+                      type_ptr = dwarf->GetDIEToType().Lookup(die.GetDIE());
                       if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
                         type_sp = type_ptr->shared_from_this();
                         break;
@@ -1677,7 +1680,7 @@
 
       case DW_TAG_array_type: {
         // Set a bit that lets us know that we are currently parsing this
-        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+        dwarf->GetDIEToType().Set(die.GetDIE(), DIE_IS_BEING_PARSED);
 
         DWARFFormValue type_die_form;
         int64_t first_index = 0;
@@ -1903,7 +1906,7 @@
         // level
         type_list->Insert(type_sp);
 
-        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+        dwarf->GetDIEToType().Set(die.GetDIE(), type_sp.get());
       }
     } else if (type_ptr != DIE_IS_BEING_PARSED) {
       type_sp = type_ptr->shared_from_this();
@@ -2514,12 +2517,11 @@
 
 std::vector<DWARFDIE> DWARFASTParserClang::GetDIEForDeclContext(
     lldb_private::CompilerDeclContext decl_context) {
-  std::vector<DWARFDIE> result;
-  for (auto it = m_decl_ctx_to_die.find(
-           (clang::DeclContext *)decl_context.GetOpaqueDeclContext());
-       it != m_decl_ctx_to_die.end(); it++)
-    result.push_back(it->second);
-  return result;
+  std::vector<DWARFDIE> res;
+  m_decl_ctx_to_die.ApplyToEntry(
+      (clang::DeclContext *)decl_context.GetOpaqueDeclContext(),
+      [&](std::unique_ptr<DIEList> &list) { res = *list; });
+  return res;
 }
 
 CompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
@@ -2752,7 +2754,7 @@
 
       SymbolFileDWARF *dwarf = die.GetDWARF();
       // Supply the type _only_ if it has already been parsed
-      Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE());
+      Type *func_type = dwarf->GetDIEToType().Lookup(die.GetDIE());
 
       assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
 
@@ -3687,22 +3689,24 @@
     return nullptr;
   }
 
-  DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE());
-  if (cache_pos != m_die_to_decl.end())
-    return cache_pos->second;
+  clang::Decl *cached_value;
+  if (m_die_to_decl.Lookup(die.GetDIE(), cached_value))
+    return cached_value;
 
   if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) {
     clang::Decl *decl = GetClangDeclForDIE(spec_die);
-    m_die_to_decl[die.GetDIE()] = decl;
-    m_decl_to_die[decl].insert(die.GetDIE());
+    m_die_to_decl.Set(die.GetDIE(), decl);
+    m_decl_to_die.ApplyToEntry(
+        decl, [=](DIEPointerSet &set) { set.insert(die.GetDIE()); });
     return decl;
   }
 
   if (DWARFDIE abstract_origin_die =
           die.GetReferencedDIE(DW_AT_abstract_origin)) {
     clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die);
-    m_die_to_decl[die.GetDIE()] = decl;
-    m_decl_to_die[decl].insert(die.GetDIE());
+    m_die_to_decl.Set(die.GetDIE(), decl);
+    m_decl_to_die.ApplyToEntry(
+        decl, [=](DIEPointerSet &set) { set.insert(die.GetDIE()); });
     return decl;
   }
 
@@ -3764,8 +3768,9 @@
     break;
   }
 
-  m_die_to_decl[die.GetDIE()] = decl;
-  m_decl_to_die[decl].insert(die.GetDIE());
+  m_die_to_decl.Set(die.GetDIE(), decl);
+  m_decl_to_die.ApplyToEntry(
+      decl, [=](DIEPointerSet &set) { set.insert(die.GetDIE()); });
 
   return decl;
 }
@@ -3878,8 +3883,8 @@
 
 clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
   if (die && die.Tag() == DW_TAG_lexical_block) {
-    clang::BlockDecl *decl =
-        llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
+    clang::BlockDecl *decl = llvm::cast_or_null<clang::BlockDecl>(
+        m_die_to_decl_ctx.Lookup(die.GetDIE()));
 
     if (!decl) {
       DWARFDIE decl_context_die;
@@ -3901,8 +3906,8 @@
   if (die && die.Tag() == DW_TAG_namespace) {
     // See if we already parsed this namespace DIE and associated it with a
     // uniqued namespace declaration
-    clang::NamespaceDecl *namespace_decl =
-        static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);
+    clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(
+        m_die_to_decl_ctx.Lookup(die.GetDIE()));
     if (namespace_decl)
       return namespace_decl;
     else {
@@ -3963,19 +3968,23 @@
 clang::DeclContext *
 DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) {
   if (die) {
-    DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE());
-    if (pos != m_die_to_decl_ctx.end())
-      return pos->second;
+    clang::DeclContext *cached_value;
+    if (m_die_to_decl_ctx.Lookup(die.GetDIE(), cached_value))
+      return cached_value;
   }
   return nullptr;
 }
 
 void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
                                                const DWARFDIE &die) {
-  m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
+  m_die_to_decl_ctx.Set(die.GetDIE(), decl_ctx);
   // There can be many DIEs for a single decl context
   // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
-  m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
+  m_decl_ctx_to_die.ApplyToEntry(decl_ctx, [=](std::unique_ptr<DIEList> &dies) {
+    if (!dies)
+      dies = llvm::make_unique<DIEList>();
+    dies->push_back(die);
+  });
 }
 
 bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
@@ -4104,7 +4113,7 @@
       dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
 
       clang::DeclContext *src_decl_ctx =
-          src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
+          src_dwarf_ast_parser->m_die_to_decl_ctx.Lookup(src_die.GetDIE());
       if (src_decl_ctx) {
         if (log)
           log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
@@ -4119,14 +4128,15 @@
       }
 
       Type *src_child_type =
-          dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
+          dst_die.GetDWARF()->GetDIEToType().Lookup(src_die.GetDIE());
       if (src_child_type) {
         if (log)
           log->Printf(
               "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
               static_cast<void *>(src_child_type), src_child_type->GetID(),
               src_die.GetOffset(), dst_die.GetOffset());
-        dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
+        dst_die.GetDWARF()->GetDIEToType().Set(dst_die.GetDIE(),
+                                               src_child_type);
       } else {
         if (log)
           log->Printf("warning: tried to unique lldb_private::Type from "
@@ -4149,7 +4159,7 @@
 
         if (src_die && (src_die.Tag() == dst_die.Tag())) {
           clang::DeclContext *src_decl_ctx =
-              src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
+              src_dwarf_ast_parser->m_die_to_decl_ctx.Lookup(src_die.GetDIE());
           if (src_decl_ctx) {
             if (log)
               log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
@@ -4164,16 +4174,16 @@
           }
 
           Type *src_child_type =
-              dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
+              dst_die.GetDWARF()->GetDIEToType().Lookup(src_die.GetDIE());
           if (src_child_type) {
             if (log)
               log->Printf("uniquing type %p (uid=0x%" PRIx64
                           ") from 0x%8.8x for 0x%8.8x",
                           static_cast<void *>(src_child_type),
                           src_child_type->GetID(), src_die.GetOffset(),
                           dst_die.GetOffset());
-            dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] =
-                src_child_type;
+            dst_die.GetDWARF()->GetDIEToType().Set(dst_die.GetDIE(),
+                                                   src_child_type);
           } else {
             if (log)
               log->Printf("warning: tried to unique lldb_private::Type from "
@@ -4207,7 +4217,7 @@
       if (dst_die) {
         // Both classes have the artificial types, link them
         clang::DeclContext *src_decl_ctx =
-            src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
+            src_dwarf_ast_parser->m_die_to_decl_ctx.Lookup(src_die.GetDIE());
         if (src_decl_ctx) {
           if (log)
             log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
@@ -4222,14 +4232,15 @@
         }
 
         Type *src_child_type =
-            dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
+            dst_die.GetDWARF()->GetDIEToType().Lookup(src_die.GetDIE());
         if (src_child_type) {
           if (log)
             log->Printf(
                 "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
                 static_cast<void *>(src_child_type), src_child_type->GetID(),
                 src_die.GetOffset(), dst_die.GetOffset());
-          dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
+          dst_die.GetDWARF()->GetDIEToType().Set(dst_die.GetDIE(),
+                                                 src_child_type);
         } else {
           if (log)
             log->Printf("warning: tried to unique lldb_private::Type from "
Index: include/lldb/Core/ThreadSafeDenseMap.h
===================================================================
--- include/lldb/Core/ThreadSafeDenseMap.h
+++ include/lldb/Core/ThreadSafeDenseMap.h
@@ -36,6 +36,17 @@
     m_map.insert(std::make_pair(k, v));
   }
 
+  void Set(_KeyType k, _ValueType v) {
+    std::lock_guard<_MutexType> guard(m_mutex);
+    m_map[k] = v;
+  }
+
+  void ApplyToEntry(_KeyType k,
+                    llvm::function_ref<void(_ValueType &)> mutator) {
+    std::lock_guard<_MutexType> guard(m_mutex);
+    mutator(m_map[k]);
+  }
+
   void Erase(_KeyType k) {
     std::lock_guard<_MutexType> guard(m_mutex);
     m_map.erase(k);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to