aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cont.c21
-rw-r--r--internal.h2
-rw-r--r--mjit.c3
-rw-r--r--test/ruby/test_jit.rb32
4 files changed, 50 insertions, 8 deletions
diff --git a/cont.c b/cont.c
index 793bce018b..a8321abcca 100644
--- a/cont.c
+++ b/cont.c
@@ -1097,6 +1097,15 @@ cont_save_thread(rb_context_t *cont, rb_thread_t *th)
}
static void
+cont_init_mjit_cont(rb_context_t *cont)
+{
+ VM_ASSERT(cont->mjit_cont == NULL);
+ if (mjit_enabled) {
+ cont->mjit_cont = mjit_cont_new(&(cont->saved_ec));
+ }
+}
+
+static void
cont_init(rb_context_t *cont, rb_thread_t *th)
{
/* save thread context */
@@ -1105,9 +1114,7 @@ cont_init(rb_context_t *cont, rb_thread_t *th)
cont->saved_ec.local_storage = NULL;
cont->saved_ec.local_storage_recursive_hash = Qnil;
cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil;
- if (mjit_enabled) {
- cont->mjit_cont = mjit_cont_new(&cont->saved_ec);
- }
+ cont_init_mjit_cont(cont);
}
static rb_context_t *
@@ -1124,6 +1131,14 @@ cont_new(VALUE klass)
return cont;
}
+void
+rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber)
+{
+ // Currently this function is meant for root_fiber. Others go through cont_new.
+ // XXX: Is this mjit_cont `mjit_cont_free`d?
+ cont_init_mjit_cont(&fiber->cont);
+}
+
#if 0
void
show_vm_stack(const rb_execution_context_t *ec)
diff --git a/internal.h b/internal.h
index f2e3862198..d5f1b93b39 100644
--- a/internal.h
+++ b/internal.h
@@ -1505,9 +1505,11 @@ VALUE rb_dbl_complex_new_polar_pi(double abs, double ang);
struct rb_thread_struct;
/* cont.c */
+struct rb_fiber_struct;
VALUE rb_obj_is_fiber(VALUE);
void rb_fiber_reset_root_local_storage(struct rb_thread_struct *);
void ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(VALUE), VALUE (*rollback_func)(VALUE));
+void rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber);
/* debug.c */
PRINTF_ARGS(void ruby_debug_printf(const char*, ...), 1, 2);
diff --git a/mjit.c b/mjit.c
index df0169e748..4dc6ad80b4 100644
--- a/mjit.c
+++ b/mjit.c
@@ -801,6 +801,9 @@ mjit_init(const struct mjit_options *opts)
rb_native_cond_initialize(&mjit_worker_wakeup);
rb_native_cond_initialize(&mjit_gc_wakeup);
+ // Make sure root_fiber's saved_ec is scanned by mark_ec_units
+ rb_fiber_init_mjit_cont(GET_EC()->fiber_ptr);
+
// Initialize class_serials cache for compilation
valid_class_serials = rb_hash_new();
rb_obj_hide(valid_class_serials);
diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb
index adb66036de..e3d8f9cee2 100644
--- a/test/ruby/test_jit.rb
+++ b/test/ruby/test_jit.rb
@@ -12,6 +12,10 @@ class TestJIT < Test::Unit::TestCase
/\AJIT inline: .+\n\z/,
/\ASuccessful MJIT finish\n\z/,
]
+ MAX_CACHE_PATTERNS = [
+ /\AJIT compaction \([^)]+\): .+\n\z/,
+ /\ANo units can be unloaded -- .+\n\z/,
+ ]
# trace_* insns are not compiled for now...
TEST_PENDING_INSNS = RubyVM::INSTRUCTION_NAMES.select { |n| n.start_with?('trace_') }.map(&:to_sym) + [
@@ -611,11 +615,7 @@ class TestJIT < Test::Unit::TestCase
end
def test_nothing_to_unload_with_jit_wait
- ignorable_patterns = [
- /\AJIT compaction \([^)]+\): .+\n\z/,
- /\ANo units can be unloaded -- .+\n\z/,
- ]
- assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 11, max_cache: 10, ignorable_patterns: ignorable_patterns)
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 11, max_cache: 10, ignorable_patterns: MAX_CACHE_PATTERNS)
begin;
def a1() a2() end
def a2() a3() end
@@ -632,6 +632,28 @@ class TestJIT < Test::Unit::TestCase
end;
end
+ def test_unload_units_on_fiber
+ assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: 'hello', success_count: 12, max_cache: 10, ignorable_patterns: MAX_CACHE_PATTERNS)
+ begin;
+ def a1() a2(false); a2(true) end
+ def a2(a) a3(a) end
+ def a3(a) a4(a) end
+ def a4(a) a5(a) end
+ def a5(a) a6(a) end
+ def a6(a) a7(a) end
+ def a7(a) a8(a) end
+ def a8(a) a9(a) end
+ def a9(a) a10(a) end
+ def a10(a)
+ if a
+ Fiber.new { a11 }.resume
+ end
+ end
+ def a11() print('hello') end
+ a1
+ end;
+ end
+
def test_unload_units_and_compaction
Dir.mktmpdir("jit_test_unload_units_") do |dir|
# MIN_CACHE_SIZE is 10