mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
Keep track of memory allocated by alloca so that it is freed appropriately
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1776 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ae50560920
commit
9bffa73530
@ -741,15 +741,16 @@ void Interpreter::executeAllocInst(AllocationInst *I, ExecutionContext &SF) {
|
||||
}
|
||||
|
||||
// Allocate enough memory to hold the type...
|
||||
GenericValue Result;
|
||||
// FIXME: Don't use CALLOC, use a tainted malloc.
|
||||
Result.PointerVal = (PointerTy)calloc(NumElements, TD.getTypeSize(Ty));
|
||||
void *Memory = calloc(NumElements, TD.getTypeSize(Ty));
|
||||
|
||||
GenericValue Result;
|
||||
Result.PointerVal = (PointerTy)Memory;
|
||||
assert(Result.PointerVal != 0 && "Null pointer returned by malloc!");
|
||||
SetValue(I, Result, SF);
|
||||
|
||||
if (I->getOpcode() == Instruction::Alloca) {
|
||||
// TODO: FIXME: alloca should keep track of memory to free it later...
|
||||
}
|
||||
if (I->getOpcode() == Instruction::Alloca)
|
||||
ECStack.back().Allocas.add(Memory);
|
||||
}
|
||||
|
||||
static void executeFreeInst(FreeInst *I, ExecutionContext &SF) {
|
||||
|
@ -42,6 +42,36 @@ union GenericValue {
|
||||
PointerTy PointerVal;
|
||||
};
|
||||
|
||||
// AllocaHolder - Object to track all of the blocks of memory allocated by
|
||||
// alloca. When the function returns, this object is poped off the execution
|
||||
// stack, which causes the dtor to be run, which frees all the alloca'd memory.
|
||||
//
|
||||
class AllocaHolder {
|
||||
friend class AllocaHolderHandle;
|
||||
std::vector<void*> Allocations;
|
||||
unsigned RefCnt;
|
||||
public:
|
||||
AllocaHolder() : RefCnt(0) {}
|
||||
void add(void *mem) { Allocations.push_back(mem); }
|
||||
~AllocaHolder() {
|
||||
for (unsigned i = 0; i < Allocations.size(); ++i)
|
||||
free(Allocations[i]);
|
||||
}
|
||||
};
|
||||
|
||||
// AllocaHolderHandle gives AllocaHolder value semantics so we can stick it into
|
||||
// a vector...
|
||||
//
|
||||
class AllocaHolderHandle {
|
||||
AllocaHolder *H;
|
||||
public:
|
||||
AllocaHolderHandle() : H(new AllocaHolder()) { H->RefCnt++; }
|
||||
AllocaHolderHandle(const AllocaHolderHandle &AH) : H(AH.H) { H->RefCnt++; }
|
||||
~AllocaHolderHandle() { if (--H->RefCnt == 0) delete H; }
|
||||
|
||||
void add(void *mem) { H->add(mem); }
|
||||
};
|
||||
|
||||
typedef std::vector<GenericValue> ValuePlaneTy;
|
||||
|
||||
// ExecutionContext struct - This struct represents one stack frame currently
|
||||
@ -57,6 +87,7 @@ struct ExecutionContext {
|
||||
BasicBlock *PrevBB; // The previous BB or null if in first BB
|
||||
CallInst *Caller; // Holds the call that called subframes.
|
||||
// NULL if main func or debugger invoked fn
|
||||
AllocaHolderHandle Allocas; // Track memory allocated by alloca
|
||||
};
|
||||
|
||||
// Interpreter - This class represents the entirety of the interpreter.
|
||||
|
Loading…
Reference in New Issue
Block a user