Skip to content

Commit f1acf47

Browse files
authored
YJIT: Call YJIT hooks before enabling YJIT (ruby#14032)
1 parent a0d0b84 commit f1acf47

File tree

8 files changed

+22
-14
lines changed

8 files changed

+22
-14
lines changed

inits.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ rb_call_builtin_inits(void)
9090
#define BUILTIN(n) CALL(builtin_##n)
9191
BUILTIN(kernel);
9292
BUILTIN(yjit);
93-
// BUILTIN(yjit_hook) is called after rb_yjit_init()
9493
BUILTIN(gc);
9594
BUILTIN(ractor);
9695
BUILTIN(numeric);
@@ -109,6 +108,7 @@ rb_call_builtin_inits(void)
109108
BUILTIN(nilclass);
110109
BUILTIN(marshal);
111110
BUILTIN(zjit);
111+
BUILTIN(yjit_hook);
112112
Init_builtin_prelude();
113113
}
114114
#undef CALL

ruby.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,12 +1833,6 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
18331833
}
18341834
#endif
18351835

1836-
#if USE_YJIT
1837-
// Call yjit_hook.rb after rb_yjit_init() to use `RubyVM::YJIT.enabled?`
1838-
void Init_builtin_yjit_hook();
1839-
Init_builtin_yjit_hook();
1840-
#endif
1841-
18421836
rb_namespace_init_done();
18431837
ruby_init_prelude();
18441838
ruby_set_script_name(opt->script_name);

yjit.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ def self.enable(stats: false, log: false, mem_size: nil, call_threshold: nil)
6464
end
6565

6666
at_exit { print_and_dump_stats } if stats
67-
call_yjit_hooks
6867
Primitive.rb_yjit_enable(stats, stats != :quiet, log, log != :quiet, mem_size, call_threshold)
6968
end
7069

yjit/bindgen/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ fn main() {
105105
.allowlist_var("SHAPE_ID_NUM_BITS")
106106
.allowlist_var("SHAPE_ID_HAS_IVAR_MASK")
107107

108+
// From ruby/internal/eval.h
109+
.allowlist_function("rb_funcall")
110+
108111
// From ruby/internal/intern/object.h
109112
.allowlist_function("rb_obj_is_kind_of")
110113
.allowlist_function("rb_obj_frozen_p")
@@ -269,6 +272,7 @@ fn main() {
269272
.allowlist_function("rb_float_new")
270273

271274
// From vm_core.h
275+
.allowlist_var("rb_cRubyVM")
272276
.allowlist_var("rb_mRubyVMFrozenCore")
273277
.allowlist_var("VM_BLOCK_HANDLER_NONE")
274278
.allowlist_type("vm_frame_env_flags")
@@ -383,6 +387,7 @@ fn main() {
383387
.allowlist_function("rb_ivar_defined")
384388
.allowlist_function("rb_ivar_get")
385389
.allowlist_function("rb_mod_name")
390+
.allowlist_function("rb_const_get")
386391

387392
// From internal/vm.h
388393
.allowlist_var("rb_vm_insns_count")

yjit/src/cruby.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,15 @@ pub fn rust_str_to_ruby(str: &str) -> VALUE {
601601

602602
/// Produce a Ruby symbol from a Rust string slice
603603
pub fn rust_str_to_sym(str: &str) -> VALUE {
604+
let id = rust_str_to_id(str);
605+
unsafe { rb_id2sym(id) }
606+
}
607+
608+
/// Produce an ID from a Rust string slice
609+
pub fn rust_str_to_id(str: &str) -> ID {
604610
let c_str = CString::new(str).unwrap();
605611
let c_ptr: *const c_char = c_str.as_ptr();
606-
unsafe { rb_id2sym(rb_intern(c_ptr)) }
612+
unsafe { rb_intern(c_ptr) }
607613
}
608614

609615
/// Produce an owned Rust String from a C char pointer

yjit/src/cruby_bindings.inc.rs

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

yjit/src/yjit.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ fn yjit_init() {
5454
// TODO: need to make sure that command-line options have been
5555
// initialized by CRuby
5656

57+
// Call YJIT hooks before enabling YJIT to avoid compiling the hooks themselves
58+
unsafe {
59+
let yjit = rb_const_get(rb_cRubyVM, rust_str_to_id("YJIT"));
60+
rb_funcall(yjit, rust_str_to_id("call_yjit_hooks"), 0);
61+
}
62+
5763
// Catch panics to avoid UB for unwinding into C frames.
5864
// See https://doc.rust-lang.org/nomicon/exception-safety.html
5965
let result = std::panic::catch_unwind(|| {

yjit_hook.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
# If YJIT is enabled, load the YJIT-only version of builtin methods
2-
if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
3-
RubyVM::YJIT.send(:call_yjit_hooks)
4-
end
5-
61
# Remove the helper defined in kernel.rb
72
class Module
83
undef :with_yjit

0 commit comments

Comments
 (0)