From 2cd5155c0e8f2448dbdbc9c9cd468e589f9745e9 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Mon, 31 Aug 2009 16:14:59 +0000 Subject: [PATCH] Free the constants that have no uses in ~LLVMContext. This fixes leaks from LLVMContext in multithreaded apps. Since constants are only deleted if they have no uses, it is safe to not delete a Module on shutdown, as many single-threaded tools do. Multithreaded apps should however delete the Module before destroying the Context to ensure that there are no leaks (assuming they use a different context for each thread). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80590 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/VMCore/ConstantsContext.h | 8 ++++++++ lib/VMCore/LLVMContextImpl.h | 23 ++++++++++++++++++++++- lib/VMCore/Type.cpp | 2 +- lib/VMCore/TypesContext.h | 2 -- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h index 22aba7e1d35..f4a2cde5d0f 100644 --- a/lib/VMCore/ConstantsContext.h +++ b/lib/VMCore/ConstantsContext.h @@ -575,6 +575,14 @@ public: // to enforce proper synchronization. typename MapTy::iterator map_begin() { return Map.begin(); } typename MapTy::iterator map_end() { return Map.end(); } + + void freeConstants() { + for (typename MapTy::iterator I=Map.begin(), E=Map.end(); + I != E; ++I) { + if (I->second->use_empty()) + delete I->second; + } + } /// InsertOrGetItem - Return an iterator for the specified element. /// If the element exists in the map, the returned iterator points to the diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 4016c0aa05a..2faf6ac6e38 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -96,7 +96,6 @@ struct DenseMapAPFloatKeyInfo { class LLVMContextImpl { public: sys::SmartRWMutex ConstantsLock; - typedef DenseMap IntMapTy; IntMapTy IntConstants; @@ -196,6 +195,28 @@ public: Int16Ty(C, 16), Int32Ty(C, 32), Int64Ty(C, 64) { } + + ~LLVMContextImpl() + { + ExprConstants.freeConstants(); + ArrayConstants.freeConstants(); + StructConstants.freeConstants(); + VectorConstants.freeConstants(); + + AggZeroConstants.freeConstants(); + NullPtrConstants.freeConstants(); + UndefValueConstants.freeConstants(); + for (IntMapTy::iterator I=IntConstants.begin(), E=IntConstants.end(); + I != E; ++I) { + if (I->second->use_empty()) + delete I->second; + } + for (FPMapTy::iterator I=FPConstants.begin(), E=FPConstants.end(); + I != E; ++I) { + if (I->second->use_empty()) + delete I->second; + } + } }; } diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index 696ac96ae6a..ba190d92301 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -500,7 +500,7 @@ void DerivedType::dropAllTypeUses() { llvm_release_global_lock(); } - } else { + } else if (!AlwaysOpaqueTy) { AlwaysOpaqueTy = OpaqueType::get(getContext()); Holder = new PATypeHolder(AlwaysOpaqueTy); } diff --git a/lib/VMCore/TypesContext.h b/lib/VMCore/TypesContext.h index 2a287fe5df6..e7950bd211f 100644 --- a/lib/VMCore/TypesContext.h +++ b/lib/VMCore/TypesContext.h @@ -221,7 +221,6 @@ public: // PATypeHolder won't destroy non-abstract types. // We can't destroy them by simply iterating, because // they may contain references to each-other. -#if 0 for (std::multimap::iterator I = TypesByHash.begin(), E = TypesByHash.end(); I != E; ++I) { Type *Ty = const_cast(I->second.Ty); @@ -235,7 +234,6 @@ public: operator delete(Ty); } } -#endif } void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) { -- 2.34.1