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/SmallVector.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ValueMap.h" #include "llvm/ADT/ValueMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ValueHandle.h" #include "llvm/Support/ValueHandle.h"
#include "llvm/Support/Mutex.h" #include "llvm/Support/Mutex.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
@@ -161,7 +162,9 @@ protected:
typedef void (*EERegisterFn)(void*); typedef void (*EERegisterFn)(void*);
EERegisterFn ExceptionTableRegister; EERegisterFn ExceptionTableRegister;
EERegisterFn ExceptionTableDeregister; EERegisterFn ExceptionTableDeregister;
std::vector<void*> AllExceptionTables; /// This maps functions to their exception tables frames.
DenseMap<const Function*, void*> AllExceptionTables;
public: public:
/// lock - This lock protects the ExecutionEngine, JIT, JITResolver and /// lock - This lock protects the ExecutionEngine, JIT, JITResolver and
@@ -410,10 +413,21 @@ public:
/// RegisterTable - Registers the given pointer as an exception table. It /// RegisterTable - Registers the given pointer as an exception table. It
/// uses the ExceptionTableRegister function. /// uses the ExceptionTableRegister function.
void RegisterTable(void* res) { void RegisterTable(const Function *fn, void* res) {
if (ExceptionTableRegister) { if (ExceptionTableRegister) {
ExceptionTableRegister(res); 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() { void ExecutionEngine::DeregisterAllTables() {
if (ExceptionTableDeregister) { if (ExceptionTableDeregister) {
for (std::vector<void*>::iterator it = AllExceptionTables.begin(), DenseMap<const Function*, void*>::iterator it = AllExceptionTables.begin();
ie = AllExceptionTables.end(); it != ie; ++it) DenseMap<const Function*, void*>::iterator ite = AllExceptionTables.end();
ExceptionTableDeregister(*it); for (; it != ite; ++it)
ExceptionTableDeregister(it->second);
AllExceptionTables.clear(); AllExceptionTables.clear();
} }
} }

View File

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