diff options
author | Jeffrey Yasskin <jyasskin@google.com> | 2010-03-27 04:53:56 +0000 |
---|---|---|
committer | Jeffrey Yasskin <jyasskin@google.com> | 2010-03-27 04:53:56 +0000 |
commit | 47b7112418a8c6ca23039ad5239cbc16091911a0 (patch) | |
tree | 4184663c182b3ba4c91c314175a417f8466af115 /lib/ExecutionEngine | |
parent | 2cd1a12fe07be753e331a12389aa1ceb49de836b (diff) | |
download | llvm-47b7112418a8c6ca23039ad5239cbc16091911a0.tar.gz llvm-47b7112418a8c6ca23039ad5239cbc16091911a0.tar.bz2 llvm-47b7112418a8c6ca23039ad5239cbc16091911a0.tar.xz |
Avoid leaking the memory allocated for GlobalVariables in the interpreter, by
freeing that memory when the GV is destroyed.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99706 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r-- | lib/ExecutionEngine/ExecutionEngine.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index d3d19df286..da21c2de9a 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -66,10 +66,39 @@ ExecutionEngine::~ExecutionEngine() { delete Modules[i]; } +namespace { +// This class automatically deletes the memory block when the GlobalVariable is +// destroyed. +class GVMemoryBlock : public CallbackVH { + GVMemoryBlock(const GlobalVariable *GV) + : CallbackVH(const_cast<GlobalVariable*>(GV)) {} + +public: + // Returns the address the GlobalVariable should be written into. The + // GVMemoryBlock object prefixes that. + static char *Create(const GlobalVariable *GV, const TargetData& TD) { + const Type *ElTy = GV->getType()->getElementType(); + size_t GVSize = (size_t)TD.getTypeAllocSize(ElTy); + void *RawMemory = ::operator new( + TargetData::RoundUpAlignment(sizeof(GVMemoryBlock), + TD.getPreferredAlignment(GV)) + + GVSize); + new(RawMemory) GVMemoryBlock(GV); + return static_cast<char*>(RawMemory) + sizeof(GVMemoryBlock); + } + + virtual void deleted() { + // We allocated with operator new and with some extra memory hanging off the + // end, so don't just delete this. I'm not sure if this is actually + // required. + this->~GVMemoryBlock(); + ::operator delete(this); + } +}; +} // anonymous namespace + char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) { - const Type *ElTy = GV->getType()->getElementType(); - size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy); - return new char[GVSize]; + return GVMemoryBlock::Create(GV, *getTargetData()); } /// removeModule - Remove a Module from the list of modules. |