Rename --mjit-min-calls to --mjit-call-threshold (#6731)

for consistency with YJIT
This commit is contained in:
Takashi Kokubun 2022-11-14 23:38:52 -08:00 коммит произвёл GitHub
Родитель c75de1e330
Коммит d15d1c01c2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 56 добавлений и 55 удалений

Просмотреть файл

@ -356,6 +356,7 @@ The following deprecated APIs are removed.
doing it in a native thread called MJIT worker. [[Feature #18968]]
* As a result, Microsoft Visual Studio (MSWIN) is no longer supported.
* MinGW is no longer supported. [[Feature #18824]]
* Rename `--mjit-min-calls` to `--mjit-call-threshold`.
## Static analysis

Просмотреть файл

@ -16,7 +16,7 @@ class BenchmarkDriver::Runner::Mjit < BenchmarkDriver::Runner::Ips
job.prelude = "#{job.prelude}\n#{<<~EOS}"
if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled?
__bmdv_ruby_i = 0
while __bmdv_ruby_i < 10000 # jit_min_calls
while __bmdv_ruby_i < 10000 # MJIT call threshold
#{job.script}
__bmdv_ruby_i += 1
end

Просмотреть файл

@ -283,7 +283,7 @@ assert_equal 30.times.map { 'ok' }.to_s, %q{
30.times.map{|i|
test i
}
} unless ENV['RUN_OPTS'] =~ /--jit-min-calls=5/ || # This always fails with --jit-wait --jit-min-calls=5
} unless ENV['RUN_OPTS'] =~ /--mjit-call-threshold=5/ || # This always fails with --mjit-wait --mjit-call-threshold=5
(ENV.key?('TRAVIS') && ENV['TRAVIS_CPU_ARCH'] == 'arm64') # https://bugs.ruby-lang.org/issues/17878
# Exception for empty select

26
mjit.c
Просмотреть файл

@ -1628,7 +1628,7 @@ system_tmpdir(void)
// Default permitted number of units with a JIT code kept in memory.
#define DEFAULT_MAX_CACHE_SIZE 10000
// A default threshold used to add iseq to JIT.
#define DEFAULT_MIN_CALLS_TO_ADD 10000
#define DEFAULT_CALL_THRESHOLD 10000
// Start MJIT worker. Return TRUE if worker is successfully started.
static bool
@ -1709,8 +1709,8 @@ mjit_setup_options(const char *s, struct mjit_options *mjit_opt)
else if (opt_match_arg(s, l, "max-cache")) {
mjit_opt->max_cache_size = atoi(s + 1);
}
else if (opt_match_arg(s, l, "min-calls")) {
mjit_opt->min_calls = atoi(s + 1);
else if (opt_match_arg(s, l, "call-threshold")) {
mjit_opt->call_threshold = atoi(s + 1);
}
// --mjit=pause is an undocumented feature for experiments
else if (opt_match_noarg(s, l, "pause")) {
@ -1724,15 +1724,15 @@ mjit_setup_options(const char *s, struct mjit_options *mjit_opt)
#define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc)
const struct ruby_opt_message mjit_option_messages[] = {
M("--mjit-warnings", "", "Enable printing JIT warnings"),
M("--mjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
M("--mjit-wait", "", "Wait until JIT compilation finishes every time (for testing)"),
M("--mjit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
M("--mjit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"),
M("--mjit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: "
M("--mjit-warnings", "", "Enable printing JIT warnings"),
M("--mjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
M("--mjit-wait", "", "Wait until JIT compilation finishes every time (for testing)"),
M("--mjit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
M("--mjit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"),
M("--mjit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: "
STRINGIZE(DEFAULT_MAX_CACHE_SIZE) ")"),
M("--mjit-min-calls=num", "", "Number of calls to trigger JIT (for testing, default: "
STRINGIZE(DEFAULT_MIN_CALLS_TO_ADD) ")"),
M("--mjit-call-threshold=num", "", "Number of calls to trigger JIT (for testing, default: "
STRINGIZE(DEFAULT_CALL_THRESHOLD) ")"),
{0}
};
#undef M
@ -1760,8 +1760,8 @@ mjit_init(const struct mjit_options *opts)
mjit_pid = getpid();
// Normalize options
if (mjit_opts.min_calls == 0)
mjit_opts.min_calls = DEFAULT_MIN_CALLS_TO_ADD;
if (mjit_opts.call_threshold == 0)
mjit_opts.call_threshold = DEFAULT_CALL_THRESHOLD;
if (mjit_opts.max_cache_size <= 0)
mjit_opts.max_cache_size = DEFAULT_MAX_CACHE_SIZE;
if (mjit_opts.max_cache_size < MIN_CACHE_SIZE)

2
mjit.h
Просмотреть файл

@ -52,7 +52,7 @@ struct mjit_options {
// If true, all ISeqs are synchronously compiled. For testing.
bool wait;
// Number of calls to trigger JIT compilation. For testing.
unsigned int min_calls;
unsigned int call_threshold;
// Force printing info about MJIT work of level VERBOSE or
// less. 0=silence, 1=medium, 2=verbose.
int verbose;

Просмотреть файл

@ -330,7 +330,7 @@ module RubyVM::MJIT
debug: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), debug)")],
debug_flags: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), debug_flags)")],
wait: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), wait)")],
min_calls: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), min_calls)")],
call_threshold: [CType::Immediate.parse("unsigned int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), call_threshold)")],
verbose: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), verbose)")],
max_cache_size: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), max_cache_size)")],
pause: [self._Bool, Primitive.cexpr!("OFFSETOF((*((struct mjit_options *)NULL)), pause)")],

Просмотреть файл

@ -38,10 +38,10 @@ module JITSupport
[stdout, stderr]
end
def eval_with_jit_without_retry(env = nil, script, verbose: 0, min_calls: 5, save_temps: false, max_cache: 1000, wait: true, timeout: JIT_TIMEOUT)
def eval_with_jit_without_retry(env = nil, script, verbose: 0, call_threshold: 5, save_temps: false, max_cache: 1000, wait: true, timeout: JIT_TIMEOUT)
args = [
'--disable-gems', "--mjit-verbose=#{verbose}",
"--mjit-min-calls=#{min_calls}", "--mjit-max-cache=#{max_cache}",
"--mjit-call-threshold=#{call_threshold}", "--mjit-max-cache=#{max_cache}",
]
args << '--disable-yjit'
args << '--mjit-wait' if wait

Просмотреть файл

@ -142,7 +142,7 @@ class TestMJIT < Test::Unit::TestCase
end;
# optimized getinstancevariable call
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '33', success_count: 1, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '33', success_count: 1, call_threshold: 2)
begin;
class A
def initialize
@ -533,7 +533,7 @@ class TestMJIT < Test::Unit::TestCase
def test_compile_insn_opt_aref
# optimized call (optimized JIT) -> send call
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '21', success_count: 2, min_calls: 1, insns: %i[opt_aref])
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '21', success_count: 2, call_threshold: 1, insns: %i[opt_aref])
begin;
obj = Object.new
def obj.[](h)
@ -546,7 +546,7 @@ class TestMJIT < Test::Unit::TestCase
end;
# send call -> optimized call (send JIT) -> optimized call
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '122', success_count: 2, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '122', success_count: 2, call_threshold: 2)
begin;
obj = Object.new
def obj.[](h)
@ -637,7 +637,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_mjit_output
out, err = eval_with_jit('5.times { puts "MJIT" }', verbose: 1, min_calls: 5)
out, err = eval_with_jit('5.times { puts "MJIT" }', verbose: 1, call_threshold: 5)
assert_equal("MJIT\n" * 5, out)
assert_match(/^#{JIT_SUCCESS_PREFIX}: block in <main>@-e:1 -> .+_ruby_mjit_p\d+u\d+\.c$/, err)
assert_match(/^Successful MJIT finish$/, err)
@ -686,7 +686,7 @@ class TestMJIT < Test::Unit::TestCase
def test_unload_units_and_compaction
Dir.mktmpdir("jit_test_unload_units_") do |dir|
# MIN_CACHE_SIZE is 10
out, err = eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~'end;'}", verbose: 1, min_calls: 1, max_cache: 10)
out, err = eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~'end;'}", verbose: 1, call_threshold: 1, max_cache: 10)
begin;
i = 0
while i < 11
@ -805,7 +805,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_inlined_builtin_methods
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '', success_count: 1, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '', success_count: 1, call_threshold: 2)
begin;
def test
float = 0.0
@ -819,7 +819,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_inlined_c_method
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 2, recompile_count: 1, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 2, recompile_count: 1, call_threshold: 2)
begin;
def test(obj, recursive: nil)
if recursive
@ -837,7 +837,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_inlined_exivar
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 4, recompile_count: 2, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 4, recompile_count: 2, call_threshold: 2)
begin;
class Foo < Hash
def initialize
@ -856,7 +856,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_inlined_undefined_ivar
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "bbb", success_count: 2, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "bbb", success_count: 2, call_threshold: 2)
begin;
class Foo
def initialize
@ -877,7 +877,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_inlined_setivar_frozen
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "FrozenError\n", success_count: 2, min_calls: 3)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "FrozenError\n", success_count: 2, call_threshold: 3)
begin;
class A
def a
@ -899,7 +899,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_inlined_getconstant
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '11', success_count: 1, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '11', success_count: 1, call_threshold: 2)
begin;
FOO = 1
def const
@ -911,7 +911,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_attr_reader
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "4nil\nnil\n6", success_count: 2, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "4nil\nnil\n6", success_count: 2, call_threshold: 2)
begin;
class A
attr_reader :a, :b
@ -942,7 +942,7 @@ class TestMJIT < Test::Unit::TestCase
print(2 * a.test)
end;
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true", success_count: 1, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true", success_count: 1, call_threshold: 2)
begin;
class Hoge
attr_reader :foo
@ -977,7 +977,7 @@ class TestMJIT < Test::Unit::TestCase
def test_heap_promotion_of_ivar_in_the_middle_of_jit
omit if GC.using_rvargc?
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\n", success_count: 2, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\n", success_count: 2, call_threshold: 2)
begin;
class A
def initialize
@ -1004,7 +1004,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_jump_to_precompiled_branch
assert_eval_with_jit("#{<<~'begin;'}\n#{<<~'end;'}", stdout: ".0", success_count: 1, min_calls: 1)
assert_eval_with_jit("#{<<~'begin;'}\n#{<<~'end;'}", stdout: ".0", success_count: 1, call_threshold: 1)
begin;
def test(foo)
".#{foo unless foo == 1}" if true
@ -1038,7 +1038,7 @@ class TestMJIT < Test::Unit::TestCase
omit '.bundle.dSYM directory is left but removing it is not supported for now'
end
Dir.mktmpdir("jit_test_clean_objects_on_exec_") do |dir|
eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1)
eval_with_jit({"TMPDIR"=>dir}, "#{<<~"begin;"}\n#{<<~"end;"}", call_threshold: 1)
begin;
def a; end; a
exec "true"
@ -1070,7 +1070,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_frame_omitted_inlining
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\ntrue\n", success_count: 1, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\ntrue\n", success_count: 1, call_threshold: 2)
begin;
class Integer
remove_method :zero?
@ -1086,7 +1086,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_block_handler_with_possible_frame_omitted_inlining
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "70.0\n70.0\n70.0\n", success_count: 2, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "70.0\n70.0\n70.0\n", success_count: 2, call_threshold: 2)
begin;
def multiply(a, b)
a *= b
@ -1099,7 +1099,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_builtin_frame_omitted_inlining
assert_eval_with_jit('0.zero?; 0.zero?; 3.times { p 0.zero? }', stdout: "true\ntrue\ntrue\n", success_count: 1, min_calls: 2)
assert_eval_with_jit('0.zero?; 0.zero?; 3.times { p 0.zero? }', stdout: "true\ntrue\ntrue\n", success_count: 1, call_threshold: 2)
end
def test_program_counter_with_regexpmatch
@ -1131,7 +1131,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_mjit_pause_wait
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '', success_count: 0, min_calls: 1)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: '', success_count: 0, call_threshold: 1)
begin;
RubyVM::MJIT.pause
proc {}.call
@ -1139,7 +1139,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_not_cancel_by_tracepoint_class
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 1, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 1, call_threshold: 2)
begin;
TracePoint.new(:class) {}.enable
2.times {}
@ -1147,7 +1147,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_cancel_by_tracepoint
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 0, min_calls: 2)
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", success_count: 0, call_threshold: 2)
begin;
TracePoint.new(:line) {}.enable
2.times {}
@ -1155,7 +1155,7 @@ class TestMJIT < Test::Unit::TestCase
end
def test_caller_locations_without_catch_table
out, _ = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1)
out, _ = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", call_threshold: 1)
begin;
def b # 2
caller_locations.first # 3
@ -1175,8 +1175,8 @@ class TestMJIT < Test::Unit::TestCase
def test_fork_with_mjit_worker_thread
Dir.mktmpdir("jit_test_fork_with_mjit_worker_thread_") do |dir|
# min_calls: 2 to skip fork block
out, err = eval_with_jit({ "TMPDIR" => dir }, "#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 2, verbose: 1)
# call_threshold: 2 to skip fork block
out, err = eval_with_jit({ "TMPDIR" => dir }, "#{<<~"begin;"}\n#{<<~"end;"}", call_threshold: 2, verbose: 1)
begin;
def before_fork; end
def after_fork; end
@ -1206,7 +1206,7 @@ class TestMJIT < Test::Unit::TestCase
end if defined?(fork)
def test_jit_failure
_, err = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", min_calls: 1, verbose: 1)
_, err = eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", call_threshold: 1, verbose: 1)
begin;
1.times do
class A
@ -1230,14 +1230,14 @@ class TestMJIT < Test::Unit::TestCase
end
# Shorthand for normal test cases
def assert_eval_with_jit(script, stdout: nil, success_count:, recompile_count: nil, min_calls: 1, max_cache: 1000, insns: [], uplevel: 1, ignorable_patterns: [])
out, err = eval_with_jit(script, verbose: 1, min_calls: min_calls, max_cache: max_cache)
def assert_eval_with_jit(script, stdout: nil, success_count:, recompile_count: nil, call_threshold: 1, max_cache: 1000, insns: [], uplevel: 1, ignorable_patterns: [])
out, err = eval_with_jit(script, verbose: 1, call_threshold: call_threshold, max_cache: max_cache)
success_actual = err.scan(/^#{JIT_SUCCESS_PREFIX}:/).size
recompile_actual = err.scan(/^#{JIT_RECOMPILE_PREFIX}:/).size
# Add --mjit-verbose=2 logs for cl.exe because compiler's error message is suppressed
# for cl.exe with --mjit-verbose=1. See `start_process` in mjit.c.
if RUBY_PLATFORM.match?(/mswin/) && success_count != success_actual
out2, err2 = eval_with_jit(script, verbose: 2, min_calls: min_calls, max_cache: max_cache)
out2, err2 = eval_with_jit(script, verbose: 2, call_threshold: call_threshold, max_cache: max_cache)
end
# Make sure that the script has insns expected to be tested

Просмотреть файл

@ -14,7 +14,7 @@ class TestRubyVMMJIT < Test::Unit::TestCase
end
def test_pause
out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
out, err = eval_with_jit(<<~'EOS', verbose: 1, call_threshold: 1, wait: false)
i = 0
while i < 5
eval("def mjit#{i}; end; mjit#{i}")
@ -36,7 +36,7 @@ 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)
out, err = eval_with_jit(<<~'EOS', verbose: 1, call_threshold: 1, wait: false)
def a() end; a
def b() end; b
RubyVM::MJIT.pause
@ -52,7 +52,7 @@ class TestRubyVMMJIT < Test::Unit::TestCase
end
def test_pause_after_waitall
out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
out, err = eval_with_jit(<<~'EOS', verbose: 1, call_threshold: 1, wait: false)
def test() = nil
test
Process.waitall
@ -65,7 +65,7 @@ class TestRubyVMMJIT < Test::Unit::TestCase
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)
out, _ = eval_with_jit(<<~'EOS', verbose: 1, call_threshold: 1, max_cache: 10, wait: false)
i = 0
while i < 11
eval("def mjit#{i}; end; mjit#{i}")
@ -77,7 +77,7 @@ class TestRubyVMMJIT < Test::Unit::TestCase
end
def test_pause_wait_false
out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
out, err = eval_with_jit(<<~'EOS', verbose: 1, call_threshold: 1, wait: false)
i = 0
while i < 10
eval("def mjit#{i}; end; mjit#{i}")
@ -95,7 +95,7 @@ class TestRubyVMMJIT < Test::Unit::TestCase
end
def test_resume
out, err = eval_with_jit(<<~'EOS', verbose: 1, min_calls: 1, wait: false)
out, err = eval_with_jit(<<~'EOS', verbose: 1, call_threshold: 1, wait: false)
print RubyVM::MJIT.resume
print RubyVM::MJIT.pause
print RubyVM::MJIT.resume

2
vm.c
Просмотреть файл

@ -391,7 +391,7 @@ mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_ise
ASSUME(func_i <= LAST_JIT_ISEQ_FUNC);
switch ((enum rb_mjit_iseq_func)func_i) {
case NOT_ADDED_JIT_ISEQ_FUNC:
if (body->total_calls == mjit_opts.min_calls) {
if (body->total_calls == mjit_opts.call_threshold) {
rb_mjit_add_iseq_to_process(iseq);
if (UNLIKELY(mjit_opts.wait && (uintptr_t)body->jit_func > LAST_JIT_ISEQ_FUNC)) {
return body->jit_func(ec, ec->cfp);