diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 46ee7a64860..c78faa600f7 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -16,7 +16,6 @@ #define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H #include "llvm-c/ExecutionEngine.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ValueMap.h" @@ -153,15 +152,6 @@ protected: /// abort. void *(*LazyFunctionCreator)(const std::string &); - /// ExceptionTableRegister - If Exception Handling is set, the JIT will - /// register dwarf tables with this function. - typedef void (*EERegisterFn)(void*); - EERegisterFn ExceptionTableRegister; - EERegisterFn ExceptionTableDeregister; - /// This maps functions to their exception tables frames. - DenseMap AllExceptionTables; - - public: /// lock - This lock protects the ExecutionEngine, JIT, JITResolver and /// JITEmitter classes. It must be held while changing the internal state of @@ -489,41 +479,6 @@ public: LazyFunctionCreator = P; } - /// InstallExceptionTableRegister - The JIT will use the given function - /// to register the exception tables it generates. - 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. - void RegisterTable(const Function *fn, void* res) { - if (ExceptionTableRegister) { - ExceptionTableRegister(res); - AllExceptionTables[fn] = res; - } - } - - /// DeregisterTable - Deregisters the exception frame previously registered - /// for the given function. - void DeregisterTable(const Function *Fn) { - if (ExceptionTableDeregister) { - DenseMap::iterator frame = - AllExceptionTables.find(Fn); - if(frame != AllExceptionTables.end()) { - ExceptionTableDeregister(frame->second); - AllExceptionTables.erase(frame); - } - } - } - - /// DeregisterAllTables - Deregisters all previously registered pointers to an - /// exception tables. It uses the ExceptionTableoDeregister function. - void DeregisterAllTables(); - protected: explicit ExecutionEngine(Module *M); diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 95d5fcb18f2..a8de4205dad 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -56,9 +56,7 @@ ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M, ExecutionEngine::ExecutionEngine(Module *M) : EEState(*this), - LazyFunctionCreator(0), - ExceptionTableRegister(0), - ExceptionTableDeregister(0) { + LazyFunctionCreator(0) { CompilingLazily = false; GVCompilationDisabled = false; SymbolSearchingDisabled = false; @@ -72,16 +70,6 @@ ExecutionEngine::~ExecutionEngine() { delete Modules[i]; } -void ExecutionEngine::DeregisterAllTables() { - if (ExceptionTableDeregister) { - DenseMap::iterator it = AllExceptionTables.begin(); - DenseMap::iterator ite = AllExceptionTables.end(); - for (; it != ite; ++it) - ExceptionTableDeregister(it->second); - AllExceptionTables.clear(); - } -} - namespace { /// \brief Helper class which uses a value handler to automatically deletes the /// memory block when the GlobalVariable is destroyed. diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index e0504d1c84e..246a675b091 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -67,140 +67,6 @@ static struct RegisterJIT { extern "C" void LLVMLinkInJIT() { } -// Determine whether we can register EH tables. -#if (defined(__GNUC__) && !defined(__ARM_EABI__) && !defined(__ia64__) && \ - !defined(__USING_SJLJ_EXCEPTIONS__)) -#define HAVE_EHTABLE_SUPPORT 1 -#else -#define HAVE_EHTABLE_SUPPORT 0 -#endif - -#if HAVE_EHTABLE_SUPPORT - -// libgcc defines the __register_frame function to dynamically register new -// dwarf frames for exception handling. This functionality is not portable -// across compilers and is only provided by GCC. We use the __register_frame -// function here so that code generated by the JIT cooperates with the unwinding -// runtime of libgcc. When JITting with exception handling enable, LLVM -// generates dwarf frames and registers it to libgcc with __register_frame. -// -// The __register_frame function works with Linux. -// -// Unfortunately, this functionality seems to be in libgcc after the unwinding -// library of libgcc for darwin was written. The code for darwin overwrites the -// value updated by __register_frame with a value fetched with "keymgr". -// "keymgr" is an obsolete functionality, which should be rewritten some day. -// In the meantime, since "keymgr" is on all libgccs shipped with apple-gcc, we -// need a workaround in LLVM which uses the "keymgr" to dynamically modify the -// 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 -#else -# define USE_KEYMGR 0 -#endif - -#if USE_KEYMGR - -namespace { - -// LibgccObject - This is the structure defined in libgcc. There is no #include -// provided for this structure, so we also define it here. libgcc calls it -// "struct object". The structure is undocumented in libgcc. -struct LibgccObject { - void *unused1; - void *unused2; - void *unused3; - - /// frame - Pointer to the exception table. - void *frame; - - /// encoding - The encoding of the object? - union { - struct { - unsigned long sorted : 1; - unsigned long from_array : 1; - unsigned long mixed_encoding : 1; - unsigned long encoding : 8; - unsigned long count : 21; - } b; - size_t i; - } encoding; - - /// fde_end - libgcc defines this field only if some macro is defined. We - /// include this field even if it may not there, to make libgcc happy. - char *fde_end; - - /// next - At least we know it's a chained list! - struct LibgccObject *next; -}; - -// "kemgr" stuff. Apparently, all frame tables are stored there. -extern "C" void _keymgr_set_and_unlock_processwide_ptr(int, void *); -extern "C" void *_keymgr_get_and_lock_processwide_ptr(int); -#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */ - -/// LibgccObjectInfo - libgcc defines this struct as km_object_info. It -/// probably contains all dwarf tables that are loaded. -struct LibgccObjectInfo { - - /// seenObjects - LibgccObjects already parsed by the unwinding runtime. - /// - struct LibgccObject* seenObjects; - - /// unseenObjects - LibgccObjects not parsed yet by the unwinding runtime. - /// - struct LibgccObject* unseenObjects; - - unsigned unused[2]; -}; - -/// darwin_register_frame - Since __register_frame does not work with darwin's -/// libgcc,we provide our own function, which "tricks" libgcc by modifying the -/// "Dwarf2 object list" key. -void DarwinRegisterFrame(void* FrameBegin) { - // Get the key. - LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) - _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); - assert(LOI && "This should be preallocated by the runtime"); - - // Allocate a new LibgccObject to represent this frame. Deallocation of this - // object may be impossible: since darwin code in libgcc was written after - // the ability to dynamically register frames, things may crash if we - // deallocate it. - struct LibgccObject* ob = (struct LibgccObject*) - malloc(sizeof(struct LibgccObject)); - - // Do like libgcc for the values of the field. - ob->unused1 = (void *)-1; - ob->unused2 = 0; - ob->unused3 = 0; - ob->frame = FrameBegin; - ob->encoding.i = 0; - ob->encoding.b.encoding = llvm::dwarf::DW_EH_PE_omit; - - // Put the info on both places, as libgcc uses the first or the second - // field. Note that we rely on having two pointers here. If fde_end was a - // char, things would get complicated. - ob->fde_end = (char*)LOI->unseenObjects; - ob->next = LOI->unseenObjects; - - // Update the key's unseenObjects list. - LOI->unseenObjects = ob; - - // Finally update the "key". Apparently, libgcc requires it. - _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, - LOI); - -} - -} -#endif // __APPLE__ -#endif // HAVE_EHTABLE_SUPPORT - /// createJIT - This is the factory method for creating a JIT for the current /// machine, it does not fall back to the interpreter. This takes ownership /// of the module. @@ -293,33 +159,11 @@ JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji, report_fatal_error("Target does not support machine code emission!"); } - // Register routine for informing unwinding runtime about new EH frames -#if HAVE_EHTABLE_SUPPORT -#if USE_KEYMGR - struct LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) - _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); - - // The key is created on demand, and libgcc creates it the first time an - // exception occurs. Since we need the key to register frames, we create - // it now. - if (!LOI) - 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 // HAVE_EHTABLE_SUPPORT - // Initialize passes. PM.doInitialization(); } JIT::~JIT() { - // Unregister all exception tables registered by this JIT. - DeregisterAllTables(); // Cleanup. AllJits->Remove(this); delete jitstate;