mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-26 09:18:56 +00:00
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
This commit is contained in:
@@ -66,10 +66,39 @@ ExecutionEngine::~ExecutionEngine() {
|
|||||||
delete Modules[i];
|
delete Modules[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) {
|
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();
|
const Type *ElTy = GV->getType()->getElementType();
|
||||||
size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy);
|
size_t GVSize = (size_t)TD.getTypeAllocSize(ElTy);
|
||||||
return new char[GVSize];
|
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) {
|
||||||
|
return GVMemoryBlock::Create(GV, *getTargetData());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// removeModule - Remove a Module from the list of modules.
|
/// removeModule - Remove a Module from the list of modules.
|
||||||
|
Reference in New Issue
Block a user