diff --git a/include/llvm/System/RWMutex.h b/include/llvm/System/RWMutex.h index 8967e9ee6ca..0a3932e6560 100644 --- a/include/llvm/System/RWMutex.h +++ b/include/llvm/System/RWMutex.h @@ -79,7 +79,7 @@ namespace llvm /// @} }; - /// ScopedReader - RAII acquisition of a writer lock + /// ScopedReader - RAII acquisition of a reader lock struct ScopedReader { RWMutex* mutex; diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 96c67924051..00f9fa30067 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/LeakDetector.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/StringPool.h" +#include "llvm/Support/Threading.h" #include "llvm/System/RWMutex.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" @@ -230,21 +231,20 @@ void Function::removeAttribute(unsigned i, Attributes attr) { // allocating an additional word in Function for programs which do not use GC // (i.e., most programs) at the cost of increased overhead for clients which do // use GC. -static ManagedStatic > GCNames; -static ManagedStatic GCNamePool; +static DenseMap *GCNames; +static StringPool *GCNamePool; static ManagedStatic GCLock; bool Function::hasGC() const { if (llvm_is_multithreaded()) { sys::ScopedReader Reader(&*GCLock); - return GCNames->count(this); - } else - return GCNames->count(this); + return GCNames && GCNames->count(this); + } else + return GCNames && GCNames->count(this); } const char *Function::getGC() const { assert(hasGC() && "Function has no collector"); - if (llvm_is_multithreaded()) { sys::ScopedReader Reader(&*GCLock); return *(*GCNames)[this]; @@ -253,19 +253,29 @@ const char *Function::getGC() const { } void Function::setGC(const char *Str) { - if (llvm_is_multithreaded()) { - sys::ScopedWriter Writer(&*GCLock); - (*GCNames)[this] = GCNamePool->intern(Str); - } else - (*GCNames)[this] = GCNamePool->intern(Str); + if (llvm_is_multithreaded()) GCLock->writer_acquire(); + if (!GCNamePool) + GCNamePool = new StringPool(); + if (!GCNames) + GCNames = new DenseMap(); + (*GCNames)[this] = GCNamePool->intern(Str); + if (llvm_is_multithreaded()) GCLock->writer_release(); } void Function::clearGC() { - if (llvm_is_multithreaded()) { - sys::ScopedWriter Writer(&*GCLock); - GCNames->erase(this); - } else + if (llvm_is_multithreaded()) GCLock->writer_acquire(); + if (GCNames) { GCNames->erase(this); + if (GCNames->empty()) { + delete GCNames; + GCNames = 0; + if (GCNamePool->empty()) { + delete GCNamePool; + GCNamePool = 0; + } + } + } + if (llvm_is_multithreaded()) GCLock->writer_release(); } /// copyAttributesFrom - copy all additional attributes (those not needed to