summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2011-08-13 01:04:44 +0000
committerNick Lewycky <nicholas@mxc.ca>2011-08-13 01:04:44 +0000
commit2be81acd775c0ac9d6bdc30cd2c96c8d71fb22da (patch)
tree9ac555059e40bf38f6d5aee44b9f3dcdc8658262
parent66243847a50f83a03554f43e8351094faf3de2be (diff)
downloadbcm5719-llvm-2be81acd775c0ac9d6bdc30cd2c96c8d71fb22da.tar.gz
bcm5719-llvm-2be81acd775c0ac9d6bdc30cd2c96c8d71fb22da.zip
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. llvm-svn: 137546
-rw-r--r--llvm/include/llvm/Module.h26
-rw-r--r--llvm/lib/VMCore/Module.cpp19
2 files changed, 23 insertions, 22 deletions
diff --git a/llvm/include/llvm/Module.h b/llvm/include/llvm/Module.h
index 7eb34b68961..8ce5ec4f1d1 100644
--- a/llvm/include/llvm/Module.h
+++ b/llvm/include/llvm/Module.h
@@ -50,17 +50,35 @@ template<> struct ilist_traits<Function>
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>
diff --git a/llvm/lib/VMCore/Module.cpp b/llvm/lib/VMCore/Module.cpp
index ee63d696d54..c29029bf6c0 100644
--- a/llvm/lib/VMCore/Module.cpp
+++ b/llvm/lib/VMCore/Module.cpp
@@ -32,25 +32,10 @@ using namespace llvm;
// 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 @@ namespace {
void Module::findUsedStructTypes(std::vector<StructType*> &StructTypes) const {
TypeFinder(StructTypes).run(*this);
}
-
-
OpenPOWER on IntegriCloud