summaryrefslogtreecommitdiff
path: root/yjit
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-04-05 13:19:31 -0700
committerGitHub <noreply@github.com>2023-04-05 13:19:31 -0700
commit1587494b0b5f64a9976dcf0bd94dfe98123c2c27 (patch)
treecde249ed1d85312a98de6b7e26bb80bdce2e44f8 /yjit
parent52e571fa72debcd764765775bd1b76ee87e36d2d (diff)
downloadruby-1587494b0b5f64a9976dcf0bd94dfe98123c2c27.tar.gz
YJIT: Add codegen for Integer methods (#7665)
* YJIT: Add codegen for Integer methods * YJIT: Update dependencies * YJIT: Fix Integer#[] for argc=2
Diffstat (limited to 'yjit')
-rw-r--r--yjit/bindgen/src/main.rs7
-rw-r--r--yjit/src/codegen.rs96
-rw-r--r--yjit/src/cruby.rs4
-rw-r--r--yjit/src/cruby_bindings.inc.rs5
4 files changed, 109 insertions, 3 deletions
diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs
index 6d915ec411..4fb02cfdf0 100644
--- a/yjit/bindgen/src/main.rs
+++ b/yjit/bindgen/src/main.rs
@@ -213,6 +213,9 @@ fn main() {
.allowlist_function("rb_sym2id")
.allowlist_function("rb_str_intern")
+ // From internal/numeric.h
+ .allowlist_function("rb_fix_aref")
+
// From internal/string.h
.allowlist_function("rb_ec_str_resurrect")
.allowlist_function("rb_str_concat_literals")
@@ -413,7 +416,9 @@ fn main() {
.allowlist_function("rb_yarv_str_eql_internal")
.allowlist_function("rb_str_neq_internal")
.allowlist_function("rb_yarv_ary_entry_internal")
- .allowlist_function("rb_yarv_fix_mod_fix")
+ .allowlist_function("rb_yjit_fix_div_fix")
+ .allowlist_function("rb_yjit_fix_mod_fix")
+ .allowlist_function("rb_yjit_fix_mul_fix")
.allowlist_function("rb_FL_TEST")
.allowlist_function("rb_FL_TEST_RAW")
.allowlist_function("rb_RB_TYPE_P")
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index 94de95906a..fdee17c166 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -4354,6 +4354,98 @@ fn jit_rb_int_equal(
true
}
+fn jit_rb_int_mul(
+ jit: &mut JITState,
+ ctx: &mut Context,
+ asm: &mut Assembler,
+ ocb: &mut OutlinedCb,
+ _ci: *const rb_callinfo,
+ _cme: *const rb_callable_method_entry_t,
+ _block: Option<IseqPtr>,
+ _argc: i32,
+ _known_recv_class: *const VALUE,
+) -> bool {
+ if ctx.two_fixnums_on_stack(jit) != Some(true) {
+ return false;
+ }
+ guard_two_fixnums(jit, ctx, asm, ocb);
+
+ // rb_fix_mul_fix may allocate memory for Bignum
+ jit_prepare_routine_call(jit, ctx, asm);
+
+ asm.comment("Integer#*");
+ let obj = ctx.stack_pop(1);
+ let recv = ctx.stack_pop(1);
+ let ret = asm.ccall(rb_fix_mul_fix as *const u8, vec![recv, obj]);
+
+ let ret_opnd = ctx.stack_push(asm, Type::Unknown);
+ asm.mov(ret_opnd, ret);
+ true
+}
+
+fn jit_rb_int_div(
+ jit: &mut JITState,
+ ctx: &mut Context,
+ asm: &mut Assembler,
+ ocb: &mut OutlinedCb,
+ _ci: *const rb_callinfo,
+ _cme: *const rb_callable_method_entry_t,
+ _block: Option<IseqPtr>,
+ _argc: i32,
+ _known_recv_class: *const VALUE,
+) -> bool {
+ if ctx.two_fixnums_on_stack(jit) != Some(true) {
+ return false;
+ }
+ guard_two_fixnums(jit, ctx, asm, ocb);
+
+ asm.comment("Integer#/");
+ asm.spill_temps(ctx); // for ccall (must be done before stack_pop)
+ let obj = ctx.stack_pop(1);
+ let recv = ctx.stack_pop(1);
+
+ // Check for arg0 % 0
+ asm.cmp(obj, VALUE::fixnum_from_usize(0).as_i64().into());
+ asm.je(side_exit(jit, ctx, ocb));
+
+ let ret = asm.ccall(rb_fix_div_fix as *const u8, vec![recv, obj]);
+
+ let ret_opnd = ctx.stack_push(asm, Type::Fixnum);
+ asm.mov(ret_opnd, ret);
+ true
+}
+
+fn jit_rb_int_aref(
+ jit: &mut JITState,
+ ctx: &mut Context,
+ asm: &mut Assembler,
+ ocb: &mut OutlinedCb,
+ _ci: *const rb_callinfo,
+ _cme: *const rb_callable_method_entry_t,
+ _block: Option<IseqPtr>,
+ argc: i32,
+ _known_recv_class: *const VALUE,
+) -> bool {
+ if argc != 1 {
+ return false;
+ }
+ if ctx.two_fixnums_on_stack(jit) != Some(true) {
+ return false;
+ }
+ guard_two_fixnums(jit, ctx, asm, ocb);
+
+ asm.comment("Integer#[]");
+ asm.spill_temps(ctx); // for ccall (must be done before stack_pop)
+ let obj = ctx.stack_pop(1);
+ let recv = ctx.stack_pop(1);
+
+ let ret = asm.ccall(rb_fix_aref as *const u8, vec![recv, obj]);
+
+ let ret_opnd = ctx.stack_push(asm, Type::Fixnum);
+ asm.mov(ret_opnd, ret);
+ true
+}
+
/// If string is frozen, duplicate it to get a non-frozen string. Otherwise, return it.
fn jit_rb_str_uplus(
jit: &mut JITState,
@@ -8136,6 +8228,10 @@ impl CodegenGlobals {
self.yjit_reg_method(rb_cInteger, "==", jit_rb_int_equal);
self.yjit_reg_method(rb_cInteger, "===", jit_rb_int_equal);
+ self.yjit_reg_method(rb_cInteger, "*", jit_rb_int_mul);
+ self.yjit_reg_method(rb_cInteger, "/", jit_rb_int_div);
+ self.yjit_reg_method(rb_cInteger, "[]", jit_rb_int_aref);
+
// rb_str_to_s() methods in string.c
self.yjit_reg_method(rb_cString, "empty?", jit_rb_str_empty_p);
self.yjit_reg_method(rb_cString, "to_s", jit_rb_str_to_s);
diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs
index 5dd6cf5d69..49afbae4c8 100644
--- a/yjit/src/cruby.rs
+++ b/yjit/src/cruby.rs
@@ -184,7 +184,9 @@ pub use rb_get_cikw_keywords_idx as get_cikw_keywords_idx;
pub use rb_get_call_data_ci as get_call_data_ci;
pub use rb_yarv_str_eql_internal as rb_str_eql_internal;
pub use rb_yarv_ary_entry_internal as rb_ary_entry_internal;
-pub use rb_yarv_fix_mod_fix as rb_fix_mod_fix;
+pub use rb_yjit_fix_div_fix as rb_fix_div_fix;
+pub use rb_yjit_fix_mod_fix as rb_fix_mod_fix;
+pub use rb_yjit_fix_mul_fix as rb_fix_mul_fix;
pub use rb_FL_TEST as FL_TEST;
pub use rb_FL_TEST_RAW as FL_TEST_RAW;
pub use rb_RB_TYPE_P as RB_TYPE_P;
diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs
index 34f0f73e07..af3fdbccc3 100644
--- a/yjit/src/cruby_bindings.inc.rs
+++ b/yjit/src/cruby_bindings.inc.rs
@@ -1183,6 +1183,7 @@ extern "C" {
) -> ::std::os::raw::c_int;
pub fn rb_insn_len(insn: VALUE) -> ::std::os::raw::c_int;
pub fn rb_vm_insn_decode(encoded: VALUE) -> ::std::os::raw::c_int;
+ pub fn rb_fix_aref(fix: VALUE, idx: VALUE) -> VALUE;
pub fn rb_vm_insn_addr2opcode(addr: *const ::std::os::raw::c_void) -> ::std::os::raw::c_int;
pub fn rb_iseq_line_no(iseq: *const rb_iseq_t, pos: usize) -> ::std::os::raw::c_uint;
pub fn rb_iseqw_to_iseq(iseqw: VALUE) -> *const rb_iseq_t;
@@ -1299,7 +1300,9 @@ extern "C" {
pub fn rb_yarv_ary_entry_internal(ary: VALUE, offset: ::std::os::raw::c_long) -> VALUE;
pub fn rb_ary_unshift_m(argc: ::std::os::raw::c_int, argv: *mut VALUE, ary: VALUE) -> VALUE;
pub fn rb_yjit_rb_ary_subseq_length(ary: VALUE, beg: ::std::os::raw::c_long) -> VALUE;
- pub fn rb_yarv_fix_mod_fix(recv: VALUE, obj: VALUE) -> VALUE;
+ pub fn rb_yjit_fix_div_fix(recv: VALUE, obj: VALUE) -> VALUE;
+ pub fn rb_yjit_fix_mod_fix(recv: VALUE, obj: VALUE) -> VALUE;
+ pub fn rb_yjit_fix_mul_fix(recv: VALUE, obj: VALUE) -> VALUE;
pub fn rb_yjit_dump_iseq_loc(iseq: *const rb_iseq_t, insn_idx: u32);
pub fn rb_FL_TEST(obj: VALUE, flags: VALUE) -> VALUE;
pub fn rb_FL_TEST_RAW(obj: VALUE, flags: VALUE) -> VALUE;