diff options
author | Takashi Kokubun <[email protected]> | 2023-07-24 13:51:46 -0700 |
---|---|---|
committer | <[email protected]> | 2023-07-24 13:51:46 -0700 |
commit | cef60e93e6db859b47c818f745be809feb04ae48 () | |
tree | 60ac5fe6f0c41aa72b152656d6ce426b1c708d70 | |
parent | c4e893ceb5811f3436f1e16cab769a16469b56b0 (diff) |
YJIT: Fallback send instructions to vm_sendish (#8106)
Notes: Merged-By: k0kubun <[email protected]>
-rw-r--r-- | test/ruby/test_yjit.rb | 6 | ||||
-rw-r--r-- | vm_exec.h | 10 | ||||
-rw-r--r-- | vm_insnhelper.c | 36 | ||||
-rw-r--r-- | yjit.c | 14 | ||||
-rw-r--r-- | yjit/bindgen/src/main.rs | 2 | ||||
-rw-r--r-- | yjit/src/codegen.rs | 115 | ||||
-rw-r--r-- | yjit/src/cruby_bindings.inc.rs | 2 |
7 files changed, 178 insertions, 7 deletions
@@ -548,7 +548,7 @@ class TestYJIT < Test::Unit::TestCase def test_getblockparamproxy # Currently two side exits as OPTIMIZED_METHOD_TYPE_CALL is unimplemented - assert_compiles(<<~'RUBY', insns: [:getblockparamproxy], exits: { opt_send_without_block: 2 }) def foo &blk p blk.call p blk.call @@ -607,7 +607,7 @@ class TestYJIT < Test::Unit::TestCase def test_send_kwargs # For now, this side-exits when calls include keyword args - assert_compiles(<<~'RUBY', result: "2#a:1,b:2/A", exits: {opt_send_without_block: 1}) def internal_method(**kw) "#{kw.size}##{kw.keys.map { |k| "#{k}:#{kw[k]}" }.join(",")}" end @@ -647,7 +647,7 @@ class TestYJIT < Test::Unit::TestCase def test_send_kwargs_splat # For now, this side-exits when calling with a splat - assert_compiles(<<~'RUBY', result: "2#a:1,b:2/B", exits: {opt_send_without_block: 1}) def internal_method(**kw) "#{kw.size}##{kw.keys.map { |k| "#{k}:#{kw[k]}" }.join(",")}" end @@ -169,10 +169,20 @@ default: \ #define THROW_EXCEPTION(exc) return (VALUE)(exc) #endif #define JIT_EXEC(ec, val) do { \ rb_jit_func_t func; \ if (val == Qundef && (func = jit_compile(ec))) { \ val = func(ec, ec->cfp); \ if (ec->tag->state) THROW_EXCEPTION(val); \ } \ } while (0) @@ -5528,6 +5528,42 @@ vm_sendish( return val; } /* object.c */ VALUE rb_nil_to_s(VALUE); VALUE rb_true_to_s(VALUE); @@ -1122,6 +1122,20 @@ rb_yjit_assert_holding_vm_lock(void) ASSERT_vm_locking(); } // Primitives used by yjit.rb VALUE rb_yjit_stats_enabled_p(rb_execution_context_t *ec, VALUE self); VALUE rb_yjit_trace_exit_locations_enabled_p(rb_execution_context_t *ec, VALUE self); @@ -325,6 +325,8 @@ fn main() { .allowlist_function("rb_yjit_icache_invalidate") .allowlist_function("rb_optimized_call") .allowlist_function("rb_yjit_assert_holding_vm_lock") // from vm_sync.h .allowlist_function("rb_vm_barrier") @@ -6428,6 +6428,38 @@ fn gen_struct_aset( Some(EndBlock) } fn gen_send_general( jit: &mut JITState, asm: &mut Assembler, @@ -6909,9 +6941,22 @@ fn gen_opt_send_without_block( asm: &mut Assembler, ocb: &mut OutlinedCb, ) -> Option<CodegenStatus> { let cd = jit.get_arg(0).as_ptr(); - gen_send_general(jit, asm, ocb, cd, None) } fn gen_send( @@ -6919,9 +6964,24 @@ fn gen_send( asm: &mut Assembler, ocb: &mut OutlinedCb, ) -> Option<CodegenStatus> { let cd = jit.get_arg(0).as_ptr(); let block = jit.get_arg(1).as_optional_ptr(); - return gen_send_general(jit, asm, ocb, cd, block); } fn gen_invokeblock( @@ -6929,13 +6989,36 @@ fn gen_invokeblock( asm: &mut Assembler, ocb: &mut OutlinedCb, ) -> Option<CodegenStatus> { if !jit.at_current_insn() { defer_compilation(jit, asm, ocb); return Some(EndBlock); } // Get call info - let cd = jit.get_arg(0).as_ptr(); let ci = unsafe { get_call_data_ci(cd) }; let argc: i32 = unsafe { vm_ci_argc(ci) }.try_into().unwrap(); let flags = unsafe { vm_ci_flag(ci) }; @@ -7065,7 +7148,31 @@ fn gen_invokesuper( asm: &mut Assembler, ocb: &mut OutlinedCb, ) -> Option<CodegenStatus> { - let cd: *const rb_call_data = jit.get_arg(0).as_ptr(); let block: Option<IseqPtr> = jit.get_arg(1).as_optional_ptr(); // Defer compilation so we can specialize on class of receiver @@ -1336,4 +1336,6 @@ extern "C" { line: ::std::os::raw::c_int, ); pub fn rb_yjit_assert_holding_vm_lock(); } |