Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt =================================================================== --- source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -37,6 +37,7 @@ SymbolFileDWARFDwoDwp.cpp SymbolFileDWARFDwp.cpp SymbolFileDWARFDebugMap.cpp + ThreadSafeDIEMap.cpp UniqueDWARFASTType.cpp LINK_LIBS Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -39,6 +39,7 @@ #include "DWARFDataExtractor.h" #include "DWARFDefines.h" #include "DWARFIndex.h" +#include "ThreadSafeDIEMap.h" #include "UniqueDWARFASTType.h" //---------------------------------------------------------------------- @@ -61,8 +62,6 @@ class SymbolFileDWARFDwo; class SymbolFileDWARFDwp; -#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) - class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::UserID { public: @@ -320,9 +319,7 @@ void Dump(lldb_private::Stream &s) override; protected: - typedef lldb_private::ThreadSafeDenseMap - DIEToTypePtr; + typedef lldb_private::ThreadSafeDIEMap DIEToTypePtr; typedef lldb_private::ThreadSafeDenseMap DIEToVariableSP; Index: source/Plugins/SymbolFile/DWARF/ThreadSafeDIEMap.h =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/ThreadSafeDIEMap.h @@ -0,0 +1,39 @@ +//===-- ThreadSafeDIEMap.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef SymbolFileDWARF_ThreadSafeDIEMap_h_ +#define SymbolFileDWARF_ThreadSafeDIEMap_h_ + +#include "lldb/Core/ThreadSafeDenseMap.h" +#include "lldb/Symbol/Type.h" + +class DWARFDebugInfoEntry; + +#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) + +namespace lldb_private { + +/// Special kind of ThreadSafeMap for mapping DWARF DIEs to types. What makes +/// this class special is that the value DIE_IS_BEING_PARSED is not stored in +/// the global map, but in thread local storage. The map is only updated when +/// parsing is complete. +class ThreadSafeDIEMap : public ThreadSafeDenseMap { + + typedef ThreadSafeDenseMap + Parent; + +public: + void Set(const DWARFDebugInfoEntry *die, lldb_private::Type *type); + lldb_private::Type *Lookup(const DWARFDebugInfoEntry *die); +}; + +} // namespace lldb_private + +#endif // SymbolFileDWARF_ThreadSafeDIEMap_h_ Index: source/Plugins/SymbolFile/DWARF/ThreadSafeDIEMap.cpp =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/ThreadSafeDIEMap.cpp @@ -0,0 +1,37 @@ +//===-- ThreadSafeDIEMap.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ThreadSafeDIEMap.h" +#include "DWARFDebugInfo.h" + +using namespace lldb; +using namespace lldb_private; + +thread_local llvm::DenseSet g_dies_being_parsed; + +void ThreadSafeDIEMap::Set(const DWARFDebugInfoEntry *die, + lldb_private::Type *type) { + if (type == DIE_IS_BEING_PARSED) { + g_dies_being_parsed.insert(die); + } else { + Parent::Set(die, type); + g_dies_being_parsed.erase(die); + } +} + +lldb_private::Type *ThreadSafeDIEMap::Lookup(const DWARFDebugInfoEntry *die) { + // Check the map in case the value was updated from another thread. + auto *t = Parent::Lookup(die); + if (g_dies_being_parsed.count(die)) { + if (t == nullptr) + return DIE_IS_BEING_PARSED; + g_dies_being_parsed.erase(die); + } + return t; +}