Fix the cleanup process of exception information in JIT. Now JIT
authorDuncan Sands <baldrick@free.fr>
Thu, 21 Oct 2010 08:57:29 +0000 (08:57 +0000)
committerDuncan Sands <baldrick@free.fr>
Thu, 21 Oct 2010 08:57:29 +0000 (08:57 +0000)
deregisters registered by it FDE structures allowing consecutive
JIT runs to succeed.  Patch by Yuri.  Fixes PR8285.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117004 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ExecutionEngine/ExecutionEngine.h
lib/ExecutionEngine/ExecutionEngine.cpp
lib/ExecutionEngine/JIT/JIT.cpp

index 3287b39a3c9500c8d5d2e57e4df4d2be751d881c..752c92f47c7e1e8bbf33dc2cbd1c82e6ece552a6 100644 (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);
 
index be7f1f56a958c2c7a879b09cb2f9a114322060d5..77082c4d04190d92433360e186dea694386e9411 100644 (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.
index 63125b79c8e26c25a229949cdd0bda91833e7893..8104ab995a4a1a06dc7ca6e731137e3e4c9c7536 100644 (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;