aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c2
-rw-r--r--internal.h4
-rw-r--r--mjit.c16
-rw-r--r--process.c2
4 files changed, 14 insertions, 10 deletions
diff --git a/eval.c b/eval.c
index f3a30dd159..ecb79ccdcb 100644
--- a/eval.c
+++ b/eval.c
@@ -233,7 +233,7 @@ ruby_cleanup(volatile int ex)
}
}
- mjit_finish(); /* We still need ISeqs here. */
+ mjit_finish(TRUE); /* We still need ISeqs here. */
ruby_finalize_1();
diff --git a/internal.h b/internal.h
index b505a47ace..b49939c61f 100644
--- a/internal.h
+++ b/internal.h
@@ -1634,12 +1634,12 @@ VALUE rb_math_sqrt(VALUE);
extern int mjit_enabled;
VALUE mjit_pause(int wait_p);
VALUE mjit_resume(void);
-void mjit_finish(void);
+void mjit_finish(int close_handle_p);
#else
#define mjit_enabled 0
static inline VALUE mjit_pause(int wait_p){ return Qnil; } /* unreachable */
static inline VALUE mjit_resume(void){ return Qnil; } /* unreachable */
-static inline void mjit_finish(void){}
+static inline void mjit_finish(int close_handle_p){}
#endif
/* newline.c */
diff --git a/mjit.c b/mjit.c
index 5fa93a3cfa..7c8eb28481 100644
--- a/mjit.c
+++ b/mjit.c
@@ -134,12 +134,13 @@ init_list(struct rb_mjit_unit_list *list)
because node of unit_queue and one of active_units may have the same unit
during proceeding unit. */
static void
-free_list(struct rb_mjit_unit_list *list)
+free_list(struct rb_mjit_unit_list *list, int close_handle_p)
{
struct rb_mjit_unit *unit = 0, *next;
list_for_each_safe(&list->head, unit, next, unode) {
list_del(&unit->unode);
+ if (!close_handle_p) unit->handle = NULL; /* Skip dlclose in free_unit() */
free_unit(unit);
}
list->length = 0;
@@ -787,9 +788,12 @@ mjit_child_after_fork(void)
/* Finish the threads processing units and creating PCH, finalize
and free MJIT data. It should be called last during MJIT
- life. */
+ life.
+
+ If close_handle_p is TRUE, it calls dlclose() for JIT-ed code. So it should be FALSE
+ if the code can still be on stack. ...But it means to leak JIT-ed handle forever (FIXME). */
void
-mjit_finish(void)
+mjit_finish(int close_handle_p)
{
if (!mjit_enabled)
return;
@@ -827,9 +831,9 @@ mjit_finish(void)
xfree(pch_file); pch_file = NULL;
mjit_call_p = FALSE;
- free_list(&unit_queue);
- free_list(&active_units);
- free_list(&compact_units);
+ free_list(&unit_queue, close_handle_p);
+ free_list(&active_units, close_handle_p);
+ free_list(&compact_units, close_handle_p);
finish_conts();
mjit_enabled = FALSE;
diff --git a/process.c b/process.c
index 29d8ae6fa4..56a90e770b 100644
--- a/process.c
+++ b/process.c
@@ -2944,7 +2944,7 @@ rb_f_exec(int argc, const VALUE *argv)
execarg_obj = rb_execarg_new(argc, argv, TRUE, FALSE);
eargp = rb_execarg_get(execarg_obj);
- if (mjit_enabled) mjit_finish(); /* do not leave files or leak children */
+ if (mjit_enabled) mjit_finish(FALSE); /* avoid leaking resources, and do not leave files. XXX: JIT-ed handle can leak after exec error is rescued. */
before_exec(); /* stop timer thread before redirects */
rb_execarg_parent_start(execarg_obj);
fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;