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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits