diff options
| author | Owen Anderson <resistor@mac.com> | 2009-08-19 00:37:02 +0000 | 
|---|---|---|
| committer | Owen Anderson <resistor@mac.com> | 2009-08-19 00:37:02 +0000 | 
| commit | 304253908957b2bd7b8ab716611d18b8c452576d (patch) | |
| tree | 6ed9a8f1000a744a20387ee9e8552128233f492d /llvm/lib/VMCore/LeakDetector.cpp | |
| parent | 0cf168635ed8bbfde74b85c1039ab62d4f334d7e (diff) | |
| download | bcm5719-llvm-304253908957b2bd7b8ab716611d18b8c452576d.tar.gz bcm5719-llvm-304253908957b2bd7b8ab716611d18b8c452576d.zip | |
Privatize part of the leak detector mechanism, which turned out to be heavily contended
when trying to run opt in parallel.  This lets parallel opt crunch 403.gcc in about a third
of the time.
llvm-svn: 79387
Diffstat (limited to 'llvm/lib/VMCore/LeakDetector.cpp')
| -rw-r--r-- | llvm/lib/VMCore/LeakDetector.cpp | 114 | 
1 files changed, 24 insertions, 90 deletions
| diff --git a/llvm/lib/VMCore/LeakDetector.cpp b/llvm/lib/VMCore/LeakDetector.cpp index a6be1afed49..31857421746 100644 --- a/llvm/lib/VMCore/LeakDetector.cpp +++ b/llvm/lib/VMCore/LeakDetector.cpp @@ -11,129 +11,63 @@  //  //===----------------------------------------------------------------------===// +#include "LLVMContextImpl.h"  #include "llvm/Support/LeakDetector.h"  #include "llvm/ADT/SmallPtrSet.h"  #include "llvm/Support/Compiler.h"  #include "llvm/Support/ManagedStatic.h"  #include "llvm/Support/Streams.h" -#include "llvm/System/RWMutex.h" +#include "llvm/System/Mutex.h"  #include "llvm/System/Threading.h"  #include "llvm/Value.h"  using namespace llvm; -namespace { -  template <class T> -  struct VISIBILITY_HIDDEN PrinterTrait { -    static void print(const T* P) { cerr << P; } -  }; +static ManagedStatic<sys::SmartMutex<true> > ObjectsLock; +static ManagedStatic<LeakDetectorImpl<void> > Objects; -  template<> -  struct VISIBILITY_HIDDEN PrinterTrait<Value> { -    static void print(const Value* P) { cerr << *P; } -  }; - -  ManagedStatic<sys::SmartRWMutex<true> > LeakDetectorLock; - -  template <typename T> -  struct VISIBILITY_HIDDEN LeakDetectorImpl { -    explicit LeakDetectorImpl(const char* const name = "") :  -      Cache(0), Name(name) { } - -    void clear() { -      Cache = 0; -      Ts.clear(); -    } -     -    void setName(const char* n) {  -      Name = n; -    } -     -    // Because the most common usage pattern, by far, is to add a -    // garbage object, then remove it immediately, we optimize this -    // case.  When an object is added, it is not added to the set -    // immediately, it is added to the CachedValue Value.  If it is -    // immediately removed, no set search need be performed. -    void addGarbage(const T* o) { -      sys::SmartScopedWriter<true> Writer(*LeakDetectorLock); -      if (Cache) { -        assert(Ts.count(Cache) == 0 && "Object already in set!"); -        Ts.insert(Cache); -      } -      Cache = o; -    } - -    void removeGarbage(const T* o) { -      sys::SmartScopedWriter<true> Writer(*LeakDetectorLock); -      if (o == Cache) -        Cache = 0; // Cache hit -      else -        Ts.erase(o); -    } - -    bool hasGarbage(const std::string& Message) { -      addGarbage(0); // Flush the Cache - -      sys::SmartScopedReader<true> Reader(*LeakDetectorLock); -      assert(Cache == 0 && "No value should be cached anymore!"); - -      if (!Ts.empty()) { -        cerr << "Leaked " << Name << " objects found: " << Message << ":\n"; -        for (typename SmallPtrSet<const T*, 8>::iterator I = Ts.begin(), -               E = Ts.end(); I != E; ++I) { -          cerr << "\t"; -          PrinterTrait<T>::print(*I); -          cerr << "\n"; -        } -        cerr << '\n'; - -        return true; -      } -       -      return false; -    } - -  private: -    SmallPtrSet<const T*, 8> Ts; -    const T* Cache; -    const char* Name; -  }; - -  static ManagedStatic<LeakDetectorImpl<void> > Objects; -  static ManagedStatic<LeakDetectorImpl<Value> > LLVMObjects; - -  static void clearGarbage() { -    Objects->clear(); -    LLVMObjects->clear(); -  } +static void clearGarbage(LLVMContext &Context) { +  Objects->clear(); +  Context.pImpl->LLVMObjects.clear();  }  void LeakDetector::addGarbageObjectImpl(void *Object) { +  sys::SmartScopedLock<true> Lock(*ObjectsLock);    Objects->addGarbage(Object);  }  void LeakDetector::addGarbageObjectImpl(const Value *Object) { -  LLVMObjects->addGarbage(Object); +  LLVMContextImpl *pImpl = Object->getContext().pImpl; +  sys::SmartScopedLock<true> Lock(pImpl->LLVMObjectsLock); +  pImpl->LLVMObjects.addGarbage(Object);  }  void LeakDetector::removeGarbageObjectImpl(void *Object) { +  sys::SmartScopedLock<true> Lock(*ObjectsLock);    Objects->removeGarbage(Object);  }  void LeakDetector::removeGarbageObjectImpl(const Value *Object) { -  LLVMObjects->removeGarbage(Object); +  LLVMContextImpl *pImpl = Object->getContext().pImpl; +  sys::SmartScopedLock<true> Lock(pImpl->LLVMObjectsLock); +  pImpl->LLVMObjects.removeGarbage(Object);  } -void LeakDetector::checkForGarbageImpl(const std::string &Message) { +void LeakDetector::checkForGarbageImpl(LLVMContext &Context,  +                                       const std::string &Message) { +  LLVMContextImpl *pImpl = Context.pImpl; +  sys::SmartScopedLock<true> Lock(*ObjectsLock); +  sys::SmartScopedLock<true> CLock(pImpl->LLVMObjectsLock); +      Objects->setName("GENERIC"); -  LLVMObjects->setName("LLVM"); +  pImpl->LLVMObjects.setName("LLVM");    // use non-short-circuit version so that both checks are performed    if (Objects->hasGarbage(Message) | -      LLVMObjects->hasGarbage(Message)) +      pImpl->LLVMObjects.hasGarbage(Message))      cerr << "\nThis is probably because you removed an object, but didn't "           << "delete it.  Please check your code for memory leaks.\n";    // Clear out results so we don't get duplicate warnings on    // next call... -  clearGarbage(); +  clearGarbage(Context);  } | 

