diff --git a/.github/workflows/zjit-macos.yml b/.github/workflows/zjit-macos.yml index abce65dd2f..5511614718 100644 --- a/.github/workflows/zjit-macos.yml +++ b/.github/workflows/zjit-macos.yml @@ -30,7 +30,7 @@ jobs: configure: '--enable-zjit=dev' - test_task: 'btest' - zjit_opts: '--zjit' + zjit_opts: '--zjit-call-threshold=1' configure: '--enable-zjit=dev' btests: '../src/bootstraptest/test_zjit.rb' diff --git a/.github/workflows/zjit-ubuntu.yml b/.github/workflows/zjit-ubuntu.yml index 24f8ce4386..865cb3f1db 100644 --- a/.github/workflows/zjit-ubuntu.yml +++ b/.github/workflows/zjit-ubuntu.yml @@ -35,7 +35,7 @@ jobs: configure: '--enable-zjit=dev' - test_task: 'btest' - zjit_opts: '--zjit' + zjit_opts: '--zjit-call-threshold=1' configure: '--enable-zjit=dev' btests: '../src/bootstraptest/test_zjit.rb' diff --git a/vm.c b/vm.c index 735e40376a..98ec1dc45a 100644 --- a/vm.c +++ b/vm.c @@ -437,9 +437,10 @@ jit_compile(rb_execution_context_t *ec) // Increment the ISEQ's call counter and trigger JIT compilation if not compiled #if USE_ZJIT extern bool rb_zjit_enabled_p; + extern uint64_t rb_zjit_call_threshold; if (body->jit_entry == NULL && rb_zjit_enabled_p) { body->jit_entry_calls++; - if (body->jit_entry_calls == 1) { + if (body->jit_entry_calls == rb_zjit_call_threshold) { extern void rb_zjit_compile_iseq(const rb_iseq_t *iseq, rb_execution_context_t *ec, bool jit_exception); rb_zjit_compile_iseq(iseq, ec, false); } diff --git a/zjit/src/options.rs b/zjit/src/options.rs index a9c0679f03..981d2c3cc5 100644 --- a/zjit/src/options.rs +++ b/zjit/src/options.rs @@ -1,5 +1,12 @@ use std::{ffi::CStr, os::raw::c_char}; +// This option is exposed to the C side in a global variable for performance, see vm.c +// Number of method calls after which to start generating code +// Threshold==1 means compile on first execution +#[no_mangle] +#[allow(non_upper_case_globals)] +pub static mut rb_zjit_call_threshold: u64 = 1; + #[derive(Clone, Copy, Debug)] pub struct Options { /// Enable debug logging @@ -79,6 +86,11 @@ fn parse_option(options: &mut Options, str_ptr: *const std::os::raw::c_char) -> match (opt_name, opt_val) { ("", "") => {}, // Simply --zjit + ("call-threshold", _) => match opt_val.parse() { + Ok(n) => unsafe { rb_zjit_call_threshold = n }, + Err(_) => return None, + }, + ("debug", "") => options.debug = true, ("dump-ssa", "") => options.dump_ssa = Some(DumpSSA::WithoutSnapshot),