From eb55f3ea3c6a12e5d098f72f3f9a16d4b7e77645 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Tue, 7 Apr 2009 17:23:02 +0000 Subject: [PATCH] Another attempt at fixing PR2975. Types can have references to eachother, so we can't just call destroy on them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68523 91177308-0d34-0410-b5e6-96231b3b80d8 --- examples/HowToUseJIT/HowToUseJIT.cpp | 4 ++++ include/llvm/AbstractTypeUser.h | 4 +++- lib/VMCore/Type.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/examples/HowToUseJIT/HowToUseJIT.cpp b/examples/HowToUseJIT/HowToUseJIT.cpp index 0482df6248f..b5c6d111914 100644 --- a/examples/HowToUseJIT/HowToUseJIT.cpp +++ b/examples/HowToUseJIT/HowToUseJIT.cpp @@ -42,6 +42,7 @@ #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/Interpreter.h" #include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -109,5 +110,8 @@ int main() { // Import result of execution: outs() << "Result: " << gv.IntVal << "\n"; + EE->freeMachineCodeForFunction(FooF); + delete EE; + llvm_shutdown(); return 0; } diff --git a/include/llvm/AbstractTypeUser.h b/include/llvm/AbstractTypeUser.h index 80656d89b72..c1216baabf8 100644 --- a/include/llvm/AbstractTypeUser.h +++ b/include/llvm/AbstractTypeUser.h @@ -137,6 +137,7 @@ public: /// class PATypeHolder { mutable const Type *Ty; + void destroy(); public: PATypeHolder(const Type *ty) : Ty(ty) { addRef(); @@ -145,7 +146,7 @@ public: addRef(); } - ~PATypeHolder() { dropRef(); } + ~PATypeHolder() { if (Ty) dropRef(); } operator Type *() const { return get(); } Type *get() const; @@ -173,6 +174,7 @@ public: private: void addRef(); void dropRef(); + friend class TypeMapBase; }; // simplify_type - Allow clients to treat uses just like values when using diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index c14d5119e5d..9f93d17d9f3 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -388,6 +388,10 @@ OpaqueType::OpaqueType() : DerivedType(OpaqueTyID) { #endif } +void PATypeHolder::destroy() { + Ty = 0; +} + // dropAllTypeUses - When this (abstract) type is resolved to be equal to // another (more concrete) type, we must eliminate all references to other // types, to avoid some circular reference problems. @@ -666,6 +670,27 @@ protected: std::multimap TypesByHash; public: + ~TypeMapBase() + { + //PATypeHolder won't destroy non-abstract types. + //We can't destroy them by simply iterating, because + //they may contain references to each-other + + for (std::multimap::iterator I + = TypesByHash.begin(), E = TypesByHash.end(); I != E; ++I) { + Type *Ty = const_cast(I->second.Ty); + I->second.destroy(); + // We can't invoke destroy or delete, because the type may + // contain references to already freed types. + // So we have to destruct the object the ugly way. + if (Ty) { + Ty->AbstractTypeUsers.clear(); + static_cast(Ty)->Type::~Type(); + operator delete(Ty); + } + } + } + void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) { std::multimap::iterator I = TypesByHash.lower_bound(Hash);