Fix the cleanup process of exception information in JIT. Now JIT

deregisters registered by it FDE structures allowing consecutive
JIT runs to succeed.  Patch by Yuri.  Fixes PR8285.

llvm-svn: 117004
This commit is contained in:
Duncan Sands 2010-10-21 08:57:29 +00:00
parent 54bf3c3cfb
commit abc7901e4e
3 changed files with 36 additions and 9 deletions

View File

@ -126,10 +126,12 @@ protected:
/// pointer is invoked to create it. If this returns null, the JIT will abort.
void* (*LazyFunctionCreator)(const std::string &);
/// ExceptionTableRegister - If Exception Handling is set, the JIT will
/// register dwarf tables with this function
/// ExceptionTableRegister - If Exception Handling is set, the JIT will
/// register dwarf tables with this function.
typedef void (*EERegisterFn)(void*);
static EERegisterFn ExceptionTableRegister;
EERegisterFn ExceptionTableRegister;
EERegisterFn ExceptionTableDeregister;
std::vector<void*> AllExceptionTables;
public:
/// lock - This lock is protects the ExecutionEngine, JIT, JITResolver and
@ -373,17 +375,26 @@ public:
/// InstallExceptionTableRegister - The JIT will use the given function
/// to register the exception tables it generates.
static void InstallExceptionTableRegister(void (*F)(void*)) {
void InstallExceptionTableRegister(EERegisterFn F) {
ExceptionTableRegister = F;
}
void InstallExceptionTableDeregister(EERegisterFn F) {
ExceptionTableDeregister = F;
}
/// RegisterTable - Registers the given pointer as an exception table. It uses
/// the ExceptionTableRegister function.
static void RegisterTable(void* res) {
if (ExceptionTableRegister)
void RegisterTable(void* res) {
if (ExceptionTableRegister) {
ExceptionTableRegister(res);
AllExceptionTables.push_back(res);
}
}
/// DeregisterAllTables - Deregisters all previously registered pointers to an
/// exception tables. It uses the ExceptionTableoDeregister function.
void DeregisterAllTables();
protected:
explicit ExecutionEngine(Module *M);

View File

@ -47,12 +47,12 @@ ExecutionEngine *(*ExecutionEngine::JITCtor)(
const SmallVectorImpl<std::string>& MAttrs) = 0;
ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M,
std::string *ErrorStr) = 0;
ExecutionEngine::EERegisterFn ExecutionEngine::ExceptionTableRegister = 0;
ExecutionEngine::ExecutionEngine(Module *M)
: EEState(*this),
LazyFunctionCreator(0) {
LazyFunctionCreator(0),
ExceptionTableRegister(0),
ExceptionTableDeregister(0) {
CompilingLazily = false;
GVCompilationDisabled = false;
SymbolSearchingDisabled = false;
@ -66,6 +66,16 @@ ExecutionEngine::~ExecutionEngine() {
delete Modules[i];
}
void ExecutionEngine::DeregisterAllTables() {
if (ExceptionTableDeregister) {
std::vector<void*>::iterator it = AllExceptionTables.begin();
std::vector<void*>::iterator ite = AllExceptionTables.end();
for (; it != ite; ++it)
ExceptionTableDeregister(*it);
AllExceptionTables.clear();
}
}
namespace {
// This class automatically deletes the memory block when the GlobalVariable is
// destroyed.

View File

@ -87,6 +87,7 @@ extern "C" void LLVMLinkInJIT() {
// values of an opaque key, used by libgcc to find dwarf tables.
extern "C" void __register_frame(void*);
extern "C" void __deregister_frame(void*);
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1050
# define USE_KEYMGR 1
@ -318,8 +319,10 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
LOI = (LibgccObjectInfo*)calloc(sizeof(struct LibgccObjectInfo), 1);
_keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, LOI);
InstallExceptionTableRegister(DarwinRegisterFrame);
// Not sure about how to deregister on Darwin.
#else
InstallExceptionTableRegister(__register_frame);
InstallExceptionTableDeregister(__deregister_frame);
#endif // __APPLE__
#endif // __GNUC__
@ -328,6 +331,9 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
}
JIT::~JIT() {
// Unregister all exception tables registered by this JIT.
DeregisterAllTables();
// Cleanup.
AllJits->Remove(this);
delete jitstate;
delete JCE;