changeset 15386:8ccb187b24e9

Erase partially created functions on JIT compilation failure (bug #37308) * pt-jit.cc (tree_jit::optimize): Verify module in debug mode. (jit_function_info::jit_function_info): Erase functions on failure.
author Max Brister <max@2bass.com>
date Fri, 14 Sep 2012 06:09:41 -0600
parents d8d7596fc68d
children 5546fe4dd77f
files libinterp/interp-core/jit-typeinfo.cc libinterp/interp-core/jit-typeinfo.h libinterp/interp-core/pt-jit.cc
diffstat 3 files changed, 28 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/interp-core/jit-typeinfo.cc
+++ b/libinterp/interp-core/jit-typeinfo.cc
@@ -586,6 +586,16 @@
     args (fn.args), call_conv (fn.call_conv), mcan_error (fn.mcan_error)
 {}
 
+void
+jit_function::erase (void)
+{
+  if (! llvm_function)
+    return;
+
+  llvm_function->eraseFromParent ();
+  llvm_function = 0;
+}
+
 std::string
 jit_function::name (void) const
 {
--- a/libinterp/interp-core/jit-typeinfo.h
+++ b/libinterp/interp-core/jit-typeinfo.h
@@ -236,6 +236,9 @@
 
   jit_function (const jit_function& fn);
 
+  // erase the interal LLVM function (if it exists). Will become invalid.
+  void erase (void);
+
   template <typename T>
   void add_mapping (llvm::ExecutionEngine *engine, T fn)
   {
--- a/libinterp/interp-core/pt-jit.cc
+++ b/libinterp/interp-core/pt-jit.cc
@@ -1865,6 +1865,9 @@
 void
 tree_jit::optimize (llvm::Function *fn)
 {
+  if (Venable_jit_debug)
+    llvm::verifyModule (*module);
+
   module_pass_manager->run (*module);
   pass_manager->run (*fn);
 
@@ -1887,6 +1890,9 @@
   for (size_t i = 0; i < nargs; ++i)
     argument_types[i] = jit_typeinfo::type_of (ov_args(i));
 
+  jit_function raw_fn;
+  jit_function wrapper;
+
   try
     {
       jit_convert conv (fcn, argument_types);
@@ -1912,10 +1918,9 @@
       jit_factory& factory = conv.get_factory ();
       llvm::Module *module = tjit.get_module ();
       jit_convert_llvm to_llvm;
-      jit_function raw_fn = to_llvm.convert_function (module,
-                                                      infer.get_blocks (),
-                                                      factory.constants (),
-                                                      fcn, argument_types);
+      raw_fn = to_llvm.convert_function (module, infer.get_blocks (),
+                                         factory.constants (), fcn,
+                                         argument_types);
 
       if (Venable_jit_debug)
         {
@@ -1928,8 +1933,9 @@
       std::string wrapper_name = fcn.name () + "_wrapper";
       jit_type *any_t = jit_typeinfo::get_any ();
       std::vector<jit_type *> wrapper_args (1, jit_typeinfo::get_any_ptr ());
-      jit_function wrapper (module, jit_convention::internal, wrapper_name,
-                            any_t, wrapper_args);
+      wrapper = jit_function (module, jit_convention::internal, wrapper_name,
+                              any_t, wrapper_args);
+
       llvm::BasicBlock *wrapper_body = wrapper.new_block ();
       builder.SetInsertPoint (wrapper_body);
 
@@ -1985,6 +1991,9 @@
           if (e.known ())
             std::cout << "jit fail: " << e.what () << std::endl;
         }
+
+      wrapper.erase ();
+      raw_fn.erase ();
     }
 }