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
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] ... Jonas Devlieghere via Phabricator via lldb-commits

Reply via email to