Another attempt at fixing PR2975.

Types can have references to eachother, so we can't just call destroy on them.

llvm-svn: 68523
This commit is contained in:
Torok Edwin 2009-04-07 17:23:02 +00:00
parent ce9fec457b
commit f57704fbed
3 changed files with 32 additions and 1 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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<unsigned, PATypeHolder> 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<unsigned, PATypeHolder>::iterator I
= TypesByHash.begin(), E = TypesByHash.end(); I != E; ++I) {
Type *Ty = const_cast<Type*>(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<const Type*>(Ty)->Type::~Type();
operator delete(Ty);
}
}
}
void RemoveFromTypesByHash(unsigned Hash, const Type *Ty) {
std::multimap<unsigned, PATypeHolder>::iterator I =
TypesByHash.lower_bound(Hash);