/// 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
/// 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);
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;
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.
// 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
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__
}
JIT::~JIT() {
+ // Unregister all exception tables registered by this JIT.
+ DeregisterAllTables();
+ // Cleanup.
AllJits->Remove(this);
delete jitstate;
delete JCE;