[llvm-commits] [llvm] r137546 - in /llvm/trunk: include/llvm/Module.h lib/VMCore/Module.cpp

Nick Lewycky nicholas at mxc.ca
Fri Aug 12 18:04:44 PDT 2011


Author: nicholas
Date: Fri Aug 12 20:04:44 2011
New Revision: 137546

URL: http://llvm.org/viewvc/llvm-project?rev=137546&view=rev
Log:
Remove the last improper use of getGlobalContext() from LLVM.

This caused a race condition where a thread calls ~LLVMContextImpl which calls
Module::dropAllReferences which calls begin() on an empty ilist that would
create the sentinel, which racily accesses the global context.

This can not be fixed by locking inside createSentinel because the lock would
need to be shared with all users of the global context, including those that
reside outside LLVM's own code.

Modified:
    llvm/trunk/include/llvm/Module.h
    llvm/trunk/lib/VMCore/Module.cpp

Modified: llvm/trunk/include/llvm/Module.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Module.h?rev=137546&r1=137545&r2=137546&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Module.h (original)
+++ llvm/trunk/include/llvm/Module.h Fri Aug 12 20:04:44 2011
@@ -50,17 +50,35 @@
 private:
   mutable ilist_node<Function> Sentinel;
 };
+
 template<> struct ilist_traits<GlobalVariable>
   : public SymbolTableListTraits<GlobalVariable, Module> {
   // createSentinel is used to create a node that marks the end of the list.
-  static GlobalVariable *createSentinel();
-  static void destroySentinel(GlobalVariable *GV) { delete GV; }
+  GlobalVariable *createSentinel() const {
+    return static_cast<GlobalVariable*>(&Sentinel);
+  }
+  static void destroySentinel(GlobalVariable*) {}
+
+  GlobalVariable *provideInitialHead() const { return createSentinel(); }
+  GlobalVariable *ensureHead(GlobalVariable*) const { return createSentinel(); }
+  static void noteHead(GlobalVariable*, GlobalVariable*) {}
+private:
+  mutable ilist_node<GlobalVariable> Sentinel;
 };
+
 template<> struct ilist_traits<GlobalAlias>
   : public SymbolTableListTraits<GlobalAlias, Module> {
   // createSentinel is used to create a node that marks the end of the list.
-  static GlobalAlias *createSentinel();
-  static void destroySentinel(GlobalAlias *GA) { delete GA; }
+  GlobalAlias *createSentinel() const {
+    return static_cast<GlobalAlias*>(&Sentinel);
+  }
+  static void destroySentinel(GlobalAlias*) {}
+
+  GlobalAlias *provideInitialHead() const { return createSentinel(); }
+  GlobalAlias *ensureHead(GlobalAlias*) const { return createSentinel(); }
+  static void noteHead(GlobalAlias*, GlobalAlias*) {}
+private:
+  mutable ilist_node<GlobalAlias> Sentinel;
 };
 
 template<> struct ilist_traits<NamedMDNode>

Modified: llvm/trunk/lib/VMCore/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Module.cpp?rev=137546&r1=137545&r2=137546&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/Module.cpp (original)
+++ llvm/trunk/lib/VMCore/Module.cpp Fri Aug 12 20:04:44 2011
@@ -32,25 +32,10 @@
 // Methods to implement the globals and functions lists.
 //
 
-GlobalVariable *ilist_traits<GlobalVariable>::createSentinel() {
-  GlobalVariable *Ret = new GlobalVariable(Type::getInt32Ty(getGlobalContext()),
-                                           false, GlobalValue::ExternalLinkage);
-  // This should not be garbage monitored.
-  LeakDetector::removeGarbageObject(Ret);
-  return Ret;
-}
-GlobalAlias *ilist_traits<GlobalAlias>::createSentinel() {
-  GlobalAlias *Ret = new GlobalAlias(Type::getInt32Ty(getGlobalContext()),
-                                     GlobalValue::ExternalLinkage);
-  // This should not be garbage monitored.
-  LeakDetector::removeGarbageObject(Ret);
-  return Ret;
-}
-
 // Explicit instantiations of SymbolTableListTraits since some of the methods
 // are not in the public header file.
-template class llvm::SymbolTableListTraits<GlobalVariable, Module>;
 template class llvm::SymbolTableListTraits<Function, Module>;
+template class llvm::SymbolTableListTraits<GlobalVariable, Module>;
 template class llvm::SymbolTableListTraits<GlobalAlias, Module>;
 
 //===----------------------------------------------------------------------===//
@@ -552,5 +537,3 @@
 void Module::findUsedStructTypes(std::vector<StructType*> &StructTypes) const {
   TypeFinder(StructTypes).run(*this);
 }
-
-





More information about the llvm-commits mailing list