mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
RubyVM::MJIT.pause(wait: true) should wait
for all compilations and compaction. Prior to this commit, the last-compiled code has not been used because MJIT worker is stopped before setting the code, and compaction has also been skipped. But it was not intentional and `wait: true` pause should wait until those two things by its feature.
This commit is contained in:
parent
47a234954a
commit
5d8f112505
4 changed files with 25 additions and 3 deletions
2
mjit.c
2
mjit.c
|
@ -802,7 +802,9 @@ mjit_pause(bool wait_p)
|
|||
}
|
||||
}
|
||||
|
||||
mjit_pause_wait_p = wait_p; // Avoid cancelling the last compilation after the unit fetch if wait_p.
|
||||
stop_worker();
|
||||
mjit_pause_wait_p = false;
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
|
|
|
@ -210,6 +210,8 @@ static bool in_jit;
|
|||
static bool stop_worker_p;
|
||||
// Set to true if worker is stopped.
|
||||
static bool worker_stopped;
|
||||
// Set to true only when worker is being stopped for `RubyVM::MJIT.pause(wait: true)`.
|
||||
static bool mjit_pause_wait_p;
|
||||
|
||||
// Path of "/tmp", which can be changed to $TMP in MinGW.
|
||||
static char *tmp_dir;
|
||||
|
@ -1225,9 +1227,10 @@ mjit_worker(void)
|
|||
mjit_func_t func = convert_unit_to_func(unit);
|
||||
(void)RB_DEBUG_COUNTER_INC_IF(mjit_compile_failures, func == (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC);
|
||||
|
||||
// `mjit_copy_cache_from_main_thread` in `mjit_compile` may wait for a long time
|
||||
// and worker may be stopped during the compilation.
|
||||
if (stop_worker_p)
|
||||
// Checking `stop_worker_p` here because `mjit_copy_cache_from_main_thread` in `mjit_compile` may wait
|
||||
// for a long time and worker may be stopped during the compilation.
|
||||
// However, we do not want to stop here when the `stop_worker()` is from `MJIT.pause(wait: true)`.
|
||||
if (stop_worker_p && !mjit_pause_wait_p)
|
||||
break;
|
||||
|
||||
CRITICAL_SECTION_START(3, "in jit func replace");
|
||||
|
|
|
@ -3,6 +3,7 @@ require 'rbconfig'
|
|||
module JITSupport
|
||||
JIT_TIMEOUT = 600 # 10min for each...
|
||||
JIT_SUCCESS_PREFIX = 'JIT success \(\d+\.\dms\)'
|
||||
JIT_COMPACTION_PREFIX = 'JIT compaction \(\d+\.\dms\)'
|
||||
UNSUPPORTED_COMPILERS = [
|
||||
%r[\Aicc\b],
|
||||
%r[\A/opt/developerstudio\d+\.\d+/bin/cc\z],
|
||||
|
|
|
@ -35,6 +35,22 @@ class TestRubyVMMJIT < Test::Unit::TestCase
|
|||
)
|
||||
end
|
||||
|
||||
def test_pause_waits_until_compaction
|
||||
out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
|
||||
def a() end; a
|
||||
def b() end; b
|
||||
RubyVM::MJIT.pause
|
||||
EOS
|
||||
assert_equal(
|
||||
2, err.scan(/#{JITSupport::JIT_SUCCESS_PREFIX}/).size,
|
||||
"unexpected stdout:\n```\n#{out}```\n\nstderr:\n```\n#{err}```",
|
||||
)
|
||||
assert_equal(
|
||||
1, err.scan(/#{JITSupport::JIT_COMPACTION_PREFIX}/).size,
|
||||
"unexpected stdout:\n```\n#{out}```\n\nstderr:\n```\n#{err}```",
|
||||
) unless RUBY_PLATFORM.match?(/mswin|mingw/) # compaction is not supported on Windows yet
|
||||
end
|
||||
|
||||
def test_pause_does_not_hang_on_full_units
|
||||
out, _ = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, max_cache: 10, wait: false)
|
||||
i = 0
|
||||
|
|
Loading…
Reference in a new issue