diff options
| author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2023-07-17 10:41:18 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-17 10:41:18 -0400 |
| commit | d70484f0eb176a7ef7274972ff92b88905ea0edc (patch) | |
| tree | f255d7024f61ed86e0dd4e2f848c39a8e2dfce97 | |
| parent | 1c4a523006e4a0994db4f166bd410fe1d35e8611 (diff) | |
YJIT: refactoring to allow for fancier call threshold logic (#8078)
* YJIT: refactoring to allow for fancier call threshold logic
* Avoid potentially compiling functions multiple times.
* Update vm.c
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
---------
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Notes
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
| -rw-r--r-- | vm.c | 7 | ||||
| -rw-r--r-- | yjit.c | 6 | ||||
| -rw-r--r-- | yjit.h | 4 | ||||
| -rw-r--r-- | yjit/bindgen/src/main.rs | 1 | ||||
| -rw-r--r-- | yjit/src/cruby_bindings.inc.rs | 1 | ||||
| -rw-r--r-- | yjit/src/yjit.rs | 10 |
6 files changed, 23 insertions, 6 deletions
@@ -385,9 +385,14 @@ jit_compile(rb_execution_context_t *ec) return 0; } + // Don't try to compile the function if it's already compiled + if (body->jit_func) { + return body->jit_func; + } + // Trigger JIT compilation as needed if (yjit_enabled) { - if (body->total_calls == rb_yjit_call_threshold()) { + if (rb_yjit_threshold_hit(iseq)) { rb_yjit_compile_iseq(iseq, ec); } } @@ -590,6 +590,12 @@ rb_get_def_bmethod_proc(rb_method_definition_t *def) return def->body.bmethod.proc; } +unsigned long +rb_get_iseq_body_total_calls(const rb_iseq_t *iseq) +{ + return iseq->body->total_calls; +} + const rb_iseq_t * rb_get_iseq_body_local_iseq(const rb_iseq_t *iseq) { @@ -27,7 +27,7 @@ // Expose these as declarations since we are building YJIT. bool rb_yjit_enabled_p(void); bool rb_yjit_compile_new_iseqs(void); -unsigned rb_yjit_call_threshold(void); +bool rb_yjit_threshold_hit(const rb_iseq_t *const iseq); void rb_yjit_invalidate_all_method_lookup_assumptions(void); void rb_yjit_cme_invalidate(rb_callable_method_entry_t *cme); void rb_yjit_collect_binding_alloc(void); @@ -49,7 +49,7 @@ void rb_yjit_tracing_invalidate_all(void); static inline bool rb_yjit_enabled_p(void) { return false; } static inline bool rb_yjit_compile_new_iseqs(void) { return false; } -static inline unsigned rb_yjit_call_threshold(void) { return UINT_MAX; } +static inline bool rb_yjit_threshold_hit(const rb_iseq_t *const iseq) { return false; } static inline void rb_yjit_invalidate_all_method_lookup_assumptions(void) {} static inline void rb_yjit_cme_invalidate(rb_callable_method_entry_t *cme) {} static inline void rb_yjit_collect_binding_alloc(void) {} diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index 30b4c8b5d7..d00816b3d5 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -394,6 +394,7 @@ fn main() { .allowlist_function("rb_get_def_iseq_ptr") .allowlist_function("rb_get_def_bmethod_proc") .allowlist_function("rb_iseq_encoded_size") + .allowlist_function("rb_get_iseq_body_total_calls") .allowlist_function("rb_get_iseq_body_local_iseq") .allowlist_function("rb_get_iseq_body_parent_iseq") .allowlist_function("rb_get_iseq_body_iseq_encoded") diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index c27fa1f29d..ed1384571f 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1251,6 +1251,7 @@ extern "C" { pub fn rb_get_mct_func(mct: *const rb_method_cfunc_t) -> *mut ::std::os::raw::c_void; pub fn rb_get_def_iseq_ptr(def: *mut rb_method_definition_t) -> *const rb_iseq_t; pub fn rb_get_def_bmethod_proc(def: *mut rb_method_definition_t) -> VALUE; + pub fn rb_get_iseq_body_total_calls(iseq: *const rb_iseq_t) -> ::std::os::raw::c_ulong; pub fn rb_get_iseq_body_local_iseq(iseq: *const rb_iseq_t) -> *const rb_iseq_t; pub fn rb_get_iseq_body_parent_iseq(iseq: *const rb_iseq_t) -> *const rb_iseq_t; pub fn rb_get_iseq_body_local_table_size(iseq: *const rb_iseq_t) -> ::std::os::raw::c_uint; diff --git a/yjit/src/yjit.rs b/yjit/src/yjit.rs index 08440d7076..a453728702 100644 --- a/yjit/src/yjit.rs +++ b/yjit/src/yjit.rs @@ -45,10 +45,14 @@ pub fn yjit_enabled_p() -> bool { YJIT_ENABLED.load(Ordering::Acquire) } -/// After how many calls YJIT starts compiling a method +/// Test whether we are ready to compile an ISEQ or not #[no_mangle] -pub extern "C" fn rb_yjit_call_threshold() -> raw::c_uint { - get_option!(call_threshold) as raw::c_uint +pub extern "C" fn rb_yjit_threshold_hit(iseq: IseqPtr) -> bool { + + let call_threshold = get_option!(call_threshold) as u64; + let total_calls = unsafe { rb_get_iseq_body_total_calls(iseq) } as u64; + + return total_calls == call_threshold; } /// This function is called from C code |
