Support unregistering exception frames of functions when they are removed.

Patch by Johannes Schaub!

Fixes PR8548


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127047 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Christopher
2011-03-04 23:37:39 +00:00
parent b1939d5db6
commit 515c67ee77
3 changed files with 25 additions and 9 deletions

View File

@@ -21,6 +21,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ValueMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Target/TargetMachine.h"
@@ -161,7 +162,9 @@ protected:
typedef void (*EERegisterFn)(void*);
EERegisterFn ExceptionTableRegister;
EERegisterFn ExceptionTableDeregister;
std::vector<void*> AllExceptionTables;
/// This maps functions to their exception tables frames.
DenseMap<const Function*, void*> AllExceptionTables;
public:
/// lock - This lock protects the ExecutionEngine, JIT, JITResolver and
@@ -410,10 +413,21 @@ public:
/// RegisterTable - Registers the given pointer as an exception table. It
/// uses the ExceptionTableRegister function.
void RegisterTable(void* res) {
void RegisterTable(const Function *fn, void* res) {
if (ExceptionTableRegister) {
ExceptionTableRegister(res);
AllExceptionTables.push_back(res);
AllExceptionTables[fn] = res;
}
}
/// DeregisterTable - Deregisters the exception frame previously registered for the given function.
void DeregisterTable(const Function *Fn) {
if (ExceptionTableDeregister) {
DenseMap<const Function*, void*>::iterator frame = AllExceptionTables.find(Fn);
if(frame != AllExceptionTables.end()) {
ExceptionTableDeregister(frame->second);
AllExceptionTables.erase(frame);
}
}
}

View File

@@ -79,9 +79,10 @@ ExecutionEngine::~ExecutionEngine() {
void ExecutionEngine::DeregisterAllTables() {
if (ExceptionTableDeregister) {
for (std::vector<void*>::iterator it = AllExceptionTables.begin(),
ie = AllExceptionTables.end(); it != ie; ++it)
ExceptionTableDeregister(*it);
DenseMap<const Function*, void*>::iterator it = AllExceptionTables.begin();
DenseMap<const Function*, void*>::iterator ite = AllExceptionTables.end();
for (; it != ite; ++it)
ExceptionTableDeregister(it->second);
AllExceptionTables.clear();
}
}

View File

@@ -985,7 +985,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
CurBufferPtr = SavedCurBufferPtr;
if (JITExceptionHandling) {
TheJIT->RegisterTable(FrameRegister);
TheJIT->RegisterTable(F.getFunction(), FrameRegister);
}
if (JITEmitDebugInfo) {
@@ -1033,8 +1033,9 @@ void JITEmitter::deallocateMemForFunction(const Function *F) {
EmittedFunctions.erase(Emitted);
}
// TODO: Do we need to unregister exception handling information from libgcc
// here?
if(JITExceptionHandling) {
TheJIT->DeregisterTable(F);
}
if (JITEmitDebugInfo) {
DR->UnregisterFunction(F);