ruby-changes:73236
From: Takashi <ko1@a...>
Date: Tue, 30 Aug 2022 01:03:28 +0900 (JST)
Subject: [ruby-changes:73236] 330c9e9850 (master): Port anytostring, intern, and toregexp (https://github.com/Shopify/ruby/pull/348)
https://git.ruby-lang.org/ruby.git/commit/?id=330c9e9850 From 330c9e98506d421778c8f2581a23ba44e4663e06 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun <takashikkbn@g...> Date: Mon, 1 Aug 2022 20:39:31 -0700 Subject: Port anytostring, intern, and toregexp (https://github.com/Shopify/ruby/pull/348) * Port anytostring, intern, and toregexp * Port getspecial to the new backend (#349) PR: https://github.com/Shopify/ruby/pull/349 --- bootstraptest/test_yjit.rb | 16 ++++++ yjit/src/codegen.rs | 122 ++++++++++++++++++++++----------------------- 2 files changed, 77 insertions(+), 61 deletions(-) diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 2f8c6a8f18..b8374746f7 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -3087,3 +3087,19 @@ assert_equal 'foo', %q{ https://github.com/ruby/ruby/blob/trunk/bootstraptest/test_yjit.rb#L3087 foo = Foo.new foo.foo } + +# anytostring, intern +assert_equal 'true', %q{ + def foo() + :"#{true}" + end + foo() +} + +# toregexp +assert_equal '/true/', %q{ + def foo() + /#{true}/ + end + foo().inspect +} diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index ee52800699..36cdd55573 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -5338,31 +5338,28 @@ fn gen_setglobal( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5338 KeepCompiling } -/* fn gen_anytostring( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { // Save the PC and SP since we might call #to_s - jit_prepare_routine_call(jit, ctx, cb, REG0); + jit_prepare_routine_call(jit, ctx, asm); let str = ctx.stack_pop(1); let val = ctx.stack_pop(1); - mov(cb, C_ARG_REGS[0], str); - mov(cb, C_ARG_REGS[1], val); - - call_ptr(cb, REG0, rb_obj_as_string_result as *const u8); + let val = asm.ccall(rb_obj_as_string_result as *const u8, vec![str, val]); // Push the return value let stack_ret = ctx.stack_push(Type::TString); - mov(cb, stack_ret, RAX); + asm.mov(stack_ret, val); KeepCompiling } +/* fn gen_objtostring( jit: &mut JITState, ctx: &mut Context, @@ -5399,25 +5396,23 @@ fn gen_objtostring( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5396 gen_send_general(jit, ctx, cb, ocb, cd, None) } } +*/ fn gen_intern( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { // Save the PC and SP because we might allocate - jit_prepare_routine_call(jit, ctx, cb, REG0); + jit_prepare_routine_call(jit, ctx, asm); let str = ctx.stack_pop(1); - - mov(cb, C_ARG_REGS[0], str); - - call_ptr(cb, REG0, rb_str_intern as *const u8); + let sym = asm.ccall(rb_str_intern as *const u8, vec![str]); // Push the return value let stack_ret = ctx.stack_push(Type::Unknown); - mov(cb, stack_ret, RAX); + asm.mov(stack_ret, sym); KeepCompiling } @@ -5425,7 +5420,7 @@ fn gen_intern( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5420 fn gen_toregexp( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { let opt = jit_get_arg(jit, 0).as_i64(); @@ -5433,34 +5428,43 @@ fn gen_toregexp( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5428 // Save the PC and SP because this allocates an object and could // raise an exception. - jit_prepare_routine_call(jit, ctx, cb, REG0); + jit_prepare_routine_call(jit, ctx, asm); let values_ptr = ctx.sp_opnd(-((SIZEOF_VALUE as isize) * (cnt as isize))); ctx.stack_pop(cnt); - mov(cb, C_ARG_REGS[0], imm_opnd(0)); - mov(cb, C_ARG_REGS[1], imm_opnd(cnt.try_into().unwrap())); - lea(cb, C_ARG_REGS[2], values_ptr); - call_ptr(cb, REG0, rb_ary_tmp_new_from_values as *const u8); + let ary = asm.ccall( + rb_ary_tmp_new_from_values as *const u8, + vec![ + Opnd::Imm(0), + Opnd::UImm(jit_get_arg(jit, 1).as_u64()), + values_ptr, + ] + ); // Save the array so we can clear it later - push(cb, RAX); - push(cb, RAX); // Alignment - mov(cb, C_ARG_REGS[0], RAX); - mov(cb, C_ARG_REGS[1], imm_opnd(opt)); - call_ptr(cb, REG0, rb_reg_new_ary as *const u8); + asm.cpush(ary); + asm.cpush(ary); // Alignment + + let val = asm.ccall( + rb_reg_new_ary as *const u8, + vec![ + ary, + Opnd::Imm(opt), + ] + ); // The actual regex is in RAX now. Pop the temp array from // rb_ary_tmp_new_from_values into C arg regs so we can clear it - pop(cb, REG1); // Alignment - pop(cb, C_ARG_REGS[0]); + let ary = asm.cpop(); // Alignment + asm.cpop_into(ary); // The value we want to push on the stack is in RAX right now let stack_ret = ctx.stack_push(Type::Unknown); - mov(cb, stack_ret, RAX); + asm.mov(stack_ret, val); // Clear the temp array. - call_ptr(cb, REG0, rb_ary_clear as *const u8); + asm.ccall(rb_ary_clear as *const u8, vec![ary]); KeepCompiling } @@ -5468,7 +5472,7 @@ fn gen_toregexp( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5472 fn gen_getspecial( jit: &mut JITState, ctx: &mut Context, - cb: &mut CodeBlock, + asm: &mut Assembler, _ocb: &mut OutlinedCb, ) -> CodegenStatus { // This takes two arguments, key and type @@ -5484,65 +5488,63 @@ fn gen_getspecial( https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L5488 // Fetch a "special" backref based on a char encoded by shifting by 1 // Can raise if matchdata uninitialized - jit_prepare_routine_call(jit, ctx, cb, REG0); + jit_prepare_routine_call(jit, ctx, asm); // call rb_backref_get() - add_comment(cb, "rb_backref_get"); - call_ptr(cb, REG0, rb_backref_get as *const u8); - mov(cb, C_ARG_REGS[0], RAX); + asm.comment("rb_backref_get"); + let backref = asm.ccall(rb_backref_get as *const u8, vec![]); let rt_u8: u8 = (rtype >> 1).try_into().unwrap(); - match rt_u8.into() { + let val = match rt_u8.into() { '&' => { - add_comment(cb, "rb_reg_last_match"); - call_ptr(cb, REG0, rb_reg_last_match as *const u8); + asm.comment("rb_reg_last_match"); + asm.ccall(rb_reg_last_match as *const u8, vec![backref]) } '`' => { - add_comment(cb, "rb_reg_match_pre"); - call_ptr(cb, REG0, rb_reg_match_pre as *const u8); + asm.comment("rb_reg_match_pre"); + asm.ccall(rb_reg_match_pre as *const u8, vec![backref]) } '\'' => { - add_comment(cb, "rb_reg_match_post"); - call_ptr(cb, REG0, rb_reg_match_post as *const u8); + asm.comment("rb_reg_match_post"); + asm.ccall(rb_reg_match_post as *const u8, vec![backref]) } '+' => { - add_comment(cb, "rb_reg_match_last"); - call_ptr(cb, REG0, rb_reg_match_last as *const u8); + asm.comment("rb_reg_match_last"); + asm.ccall(rb_reg_match_last as *const u8, vec![backref]) } _ => panic!("invalid back-ref"), - } + }; let stack_ret = ctx.stack_push(Type::Unknown); - mov(cb, stack_ret, RAX); + asm.mov(stack_ret, val); KeepCompiling } else { // Fetch the N-th match from the last backref based on type shifted by 1 // Can raise if matchdata uninitialized - jit_prepare_routine_call(jit, ctx, cb, REG0); + jit_prepare_routine_call(jit, ctx, asm); // call rb_backref_get() - add_comment(cb, "rb_backref_get"); - call_ptr(cb, REG0, rb_backref_get as *const u8); + asm.comment("rb_backref_get"); + let backref = asm.ccall(rb_backref_get as *const u8, vec![]); // rb_reg_nth_match((int)(type >> 1), backref); - add_comment(cb, "rb_reg_nth_match"); - mov( - cb, - C_ARG_REGS[0], - imm_opnd((rtype >> 1).try_into().unwrap()), + asm.comment("rb_reg_nth_match"); + let val = asm.ccall( + rb_reg_nth_match as *const u8, + vec![ + Opnd::Imm((rtype >> 1).try_into().unwrap()), + backref, + ] ); - mov(cb, C_ARG_REGS[1], RAX); - call_ptr(cb, REG0, rb_reg_nth_match as *const u8); let stack_ret = ctx.stack_push(Type::Unknown); - mov(cb, stack_ret, RAX); + asm.mov(stack_ret, val); KeepCompiling } } -*/ fn gen_getclassvariable( jit: &mut JITState, @@ -6052,13 +6054,11 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> { https://github.com/ruby/ruby/blob/trunk/yjit/src/codegen.rs#L6054 YARVINSN_getglobal => Some(gen_getglobal), YARVINSN_setglobal => Some(gen_setglobal), - /* YARVINSN_anytostring => Some(gen_anytostring), - YARVINSN_objtostring => Some(gen_objtostring), + //YARVINSN_objtostring => Some(gen_objtostring), YARVINSN_intern => Some(gen_intern), YARVINSN_toregexp => Some(gen_toregexp), YARVINSN_getspecial => Some(gen_getspecial), - */ YARVINSN_getclassvariable => Some(gen_getclassvariable), YARVINSN_setclassvariable => Some(gen_setclassvariable), -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/