ruby-changes:73274
From: Takashi <ko1@a...>
Date: Tue, 30 Aug 2022 01:07:30 +0900 (JST)
Subject: [ruby-changes:73274] 668b99b43b (master): Port gen_send_iseq to the new backend IR (https://github.com/Shopify/ruby/pull/381)
https://git.ruby-lang.org/ruby.git/commit/?id=668b99b43b From 668b99b43b26868e3cddc41de2025841522acc3b Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Tue, 9 Aug 2022 09:16:27 -0700 Subject: Port gen_send_iseq to the new backend IR (https://github.com/Shopify/ruby/pull/381) * Port gen_send_iseq to the new backend IR * Replace occurrences of 8 by SIZEOF_VALUE Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@g...> Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> --- .cirrus.yml | 10 +--- bootstraptest/test_yjit.rb | 33 +++++++++++ yjit/src/codegen.rs | 145 +++++++++++++++++++-------------------------- 3 files changed, 98 insertions(+), 90 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 1d7056c1d2..f743252655 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -157,16 +157,12 @@ yjit_task: https://github.com/ruby/ruby/blob/trunk/.cirrus.yml#L157 bootstraptest/test_struct.rb \ bootstraptest/test_syntax.rb \ bootstraptest/test_thread.rb \ + bootstraptest/test_yjit_30k_ifelse.rb \ + bootstraptest/test_yjit_30k_methods.rb \ bootstraptest/test_yjit_new_backend.rb \ bootstraptest/test_yjit_rust_port.rb # These are the btests we can't run yet on arm: - #bootstraptest/test_block.rb (missing opt_send) - #bootstraptest/test_insns.rb (missing opt_send) - #bootstraptest/test_ractor.rb ? (untested) - #bootstraptest/test_literal.rb (displacement bug) - #bootstraptest/test_yjit.rb (multiple bugs) - #bootstraptest/test_yjit_30k_ifelse.rb (missing opt_send) - #bootstraptest/test_yjit_30k_methods.rb (missing opt_send) + #bootstraptest/test_yjit.rb (out of executable memory not handled) # full_build_script: make -j diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 0f9150e388..833d1393f0 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -3165,3 +3165,36 @@ assert_equal '.', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L3165 # opt_invokebuiltin_delegate_leave assert_equal '[0]', %q{"\x00".unpack("c")} + +# opt_send_without_block (VM_METHOD_TYPE_ISEQ) +assert_equal '1', %q{ + def foo = 1 + def bar = foo + bar +} +assert_equal '[1, 2, 3]', %q{ + def foo(a, b) = [1, a, b] + def bar = foo(2, 3) + bar +} +assert_equal '[1, 2, 3, 4, 5, 6]', %q{ + def foo(a, b, c:, d:, e: 0, f: 6) = [a, b, c, d, e, f] + def bar = foo(1, 2, c: 3, d: 4, e: 5) + bar +} +assert_equal '[1, 2, 3, 4]', %q{ + def foo(a, b = 2) = [a, b] + def bar = foo(1) + foo(3, 4) + bar +} + +assert_equal '1', %q{ + def foo(a) = a + def bar = foo(1) { 2 } + bar +} +assert_equal '[1, 2]', %q{ + def foo(a, &block) = [a, block.call] + def bar = foo(1) { 2 } + bar +} diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 7f95512445..b8f4b84285 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -3981,7 +3981,7 @@ fn gen_send_cfunc( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3981 // sp[-3] = me; // Put compile time cme into REG1. It's assumed to be valid because we are notified when // any cme we depend on become outdated. See yjit_method_lookup_change(). - asm.mov(Opnd::mem(64, sp, 8 * -3), Opnd::UImm(cme as u64)); + asm.mov(Opnd::mem(64, sp, SIZEOF_VALUE_I32 * -3), Opnd::UImm(cme as u64)); // Write block handler at sp[-2] // sp[-2] = block_handler; @@ -3989,9 +3989,9 @@ fn gen_send_cfunc( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L3989 // reg1 = VM_BH_FROM_ISEQ_BLOCK(VM_CFP_TO_CAPTURED_BLOCK(reg_cfp)); let cfp_self = asm.lea(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SELF)); let block_handler = asm.or(cfp_self, Opnd::Imm(1)); - asm.mov(Opnd::mem(64, sp, 8 * -2), block_handler); + asm.mov(Opnd::mem(64, sp, SIZEOF_VALUE_I32 * -2), block_handler); } else { - let dst_opnd = Opnd::mem(64, sp, 8 * -2); + let dst_opnd = Opnd::mem(64, sp, SIZEOF_VALUE_I32 * -2); asm.mov(dst_opnd, Opnd::UImm(VM_BLOCK_HANDLER_NONE.into())); } @@ -4001,7 +4001,7 @@ fn gen_send_cfunc( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4001 if !kw_arg.is_null() { frame_type |= VM_FRAME_FLAG_CFRAME_KW } - asm.mov(Opnd::mem(64, sp, 8 * -1), Opnd::UImm(frame_type.into())); + asm.mov(Opnd::mem(64, sp, SIZEOF_VALUE_I32 * -1), Opnd::UImm(frame_type.into())); // Allocate a new CFP (ec->cfp--) let ec_cfp_opnd = Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP); @@ -4117,9 +4117,8 @@ fn gen_send_cfunc( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4117 EndBlock } -/* fn gen_return_branch( - cb: &mut CodeBlock, + asm: &mut Assembler, target0: CodePtr, _target1: Option<CodePtr>, shape: BranchShape, @@ -4127,8 +4126,7 @@ fn gen_return_branch( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4126 match shape { BranchShape::Next0 | BranchShape::Next1 => unreachable!(), BranchShape::Default => { - mov(cb, REG0, code_ptr_opnd(target0)); - mov(cb, mem_opnd(64, REG_CFP, RUBY_OFFSET_CFP_JIT_RETURN), REG0); + asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), Opnd::const_ptr(target0.raw_ptr())); } } } @@ -4136,7 +4134,7 @@ fn gen_return_branch( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4134 fn gen_send_iseq( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, ocb: &mut OutlinedCb, ci: *const rb_callinfo, cme: *const rb_callable_method_entry_t, @@ -4156,7 +4154,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4154 if unsafe { vm_ci_flag(ci) } & VM_CALL_TAILCALL != 0 { // We can't handle tailcalls - gen_counter_incr!(cb, send_iseq_tailcall); + gen_counter_incr!(asm, send_iseq_tailcall); return CantCompile; } @@ -4167,7 +4165,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4165 || get_iseq_flags_has_post(iseq) || get_iseq_flags_has_kwrest(iseq) } { - gen_counter_incr!(cb, send_iseq_complex_callee); + gen_counter_incr!(asm, send_iseq_complex_callee); return CantCompile; } @@ -4175,14 +4173,14 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4173 // positionals, then we need to allocate a hash. For now we're going to // call that too complex and bail. if supplying_kws && !unsafe { get_iseq_flags_has_kw(iseq) } { - gen_counter_incr!(cb, send_iseq_complex_callee); + gen_counter_incr!(asm, send_iseq_complex_callee); return CantCompile; } // If we have a method accepting no kwargs (**nil), exit if we have passed // it any kwargs. if supplying_kws && unsafe { get_iseq_flags_has_accepts_no_kwarg(iseq) } { - gen_counter_incr!(cb, send_iseq_complex_callee); + gen_counter_incr!(asm, send_iseq_complex_callee); return CantCompile; } @@ -4197,7 +4195,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4195 // In this case (param.flags.has_block && local_iseq != iseq), // the block argument is setup as a local variable and requires // materialization (allocation). Bail. - gen_counter_incr!(cb, send_iseq_complex_callee); + gen_counter_incr!(asm, send_iseq_complex_callee); return CantCompile; } } @@ -4220,7 +4218,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4218 let opts_missing: i32 = opt_num - opts_filled; if opts_filled < 0 || opts_filled > opt_num { - gen_counter_incr!(cb, send_iseq_arity_error); + gen_counter_incr!(asm, send_iseq_arity_error); return CantCompile; } @@ -4228,7 +4226,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4226 // would need to move adjust the arguments location to account for that. // For now we aren't handling this case. if doing_kw_call && opts_missing > 0 { - gen_counter_incr!(cb, send_iseq_complex_callee); + gen_counter_incr!(asm, send_iseq_complex_callee); return CantCompile; } @@ -4256,7 +4254,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4254 // We have so many keywords that (1 << num) encoded as a FIXNUM // (which shifts it left one more) no longer fits inside a 32-bit // immediate. - gen_counter_incr!(cb, send_iseq_complex_callee); + gen_counter_incr!(asm, send_iseq_complex_callee); return CantCompile; } @@ -4294,7 +4292,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4292 // If the keyword was never found, then we know we have a // mismatch in the names of the keyword arguments, so we need to // bail. - gen_counter_incr!(cb, send_iseq_kwargs_mismatch); + gen_counter_incr!(asm, send_iseq_kwargs_mismatch); return CantCompile; } Some((callee_idx, _)) if callee_idx < keyword_required_num => { @@ -4307,7 +4305,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L4305 } assert!(required_kwargs_filled <= keyword_required_num); if required_kwargs_filled != keyword_required_num { - gen_counter_incr!(cb, send_iseq_kwargs_mismatch); + gen_counter_incr!(asm, send_iseq_kwargs_mismatch); return CantCompile; } } @@ -4319,7 +4317,7 @@ fn gen_send_iseq( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/