JDevlieghere created this revision.
JDevlieghere added a reviewer: labath.
Herald added a subscriber: mgorny.
JDevlieghere edited the summary of this revision.
This is an attempt to realize Pavel's suggestion from
https://reviews.llvm.org/D48393
In https://reviews.llvm.org/D48393#1139327, @labath wrote:
> It's even more complicated than that, in case you really have reference
> cycles, you can have multiple threads starting parsing from different points
> in that cycle, and getting deadlocked waiting for the DIE_IS_BEING_PARSED
> results from each other.
>
> The only sane algorithm I can come up right now is to make the list of parsed
> dies local to each thread/parsing entity (e.g. via a "visited" list), and
> only update the global map once the parsing has completed (successfully or
> not). This can potentially duplicate some effort where one thread parses a
> type only to find out that it has already been parsed, but hopefully that is
> not going to be the common case. The alternative is some complicated resource
> cycle detection scheme.
Repository:
rLLDB LLDB
https://reviews.llvm.org/D52406
Files:
source/Plugins/SymbolFile/DWARF/CMakeLists.txt
source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
source/Plugins/SymbolFile/DWARF/ThreadSafeDIEMap.cpp
source/Plugins/SymbolFile/DWARF/ThreadSafeDIEMap.h
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<const DWARFDebugInfoEntry *,
+ lldb_private::Type *> {
+
+ typedef ThreadSafeDenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
+ 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<const DWARFDebugInfoEntry *> 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;
+}
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<const DWARFDebugInfoEntry *,
- lldb_private::Type *>
- DIEToTypePtr;
+ typedef lldb_private::ThreadSafeDIEMap DIEToTypePtr;
typedef lldb_private::ThreadSafeDenseMap<const DWARFDebugInfoEntry *,
lldb::VariableSP>
DIEToVariableSP;
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
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits