diff options
author | Takashi Kokubun <[email protected]> | 2023-03-19 21:49:51 -0700 |
---|---|---|
committer | Takashi Kokubun <[email protected]> | 2023-03-19 21:52:25 -0700 |
commit | e3dc25acae03f052e6e8a56868481b9fc2f733ea (patch) | |
tree | 0f4c83e2ebf5e946548653d9d3362af459d9398b | |
parent | 7aeb9e20b90bf16d25fcc76c619bf971f4c47ec5 (diff) |
RJIT: Fix ISeq invokeblock
-rw-r--r-- | lib/ruby_vm/rjit/insn_compiler.rb | 61 | ||||
-rw-r--r-- | rjit_c.h | 2 | ||||
-rw-r--r-- | rjit_c.rb | 2 |
3 files changed, 41 insertions, 24 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb index 6c05b9b844..b02a177c36 100644 --- a/lib/ruby_vm/rjit/insn_compiler.rb +++ b/lib/ruby_vm/rjit/insn_compiler.rb @@ -1497,12 +1497,6 @@ module RubyVM::RJIT asm.incr_counter(:invokeblock_none) CantCompile elsif comptime_handler & 0x3 == 0x1 # VM_BH_ISEQ_BLOCK_P - # Disabled until basictest is fixed - disabled = true - if disabled - return CantCompile - end - asm.comment('get local EP') ep_reg = :rax jit_get_lep(jit, asm, reg: ep_reg) @@ -1527,25 +1521,15 @@ module RubyVM::RJIT block_changed_exit = counted_exit(side_exit, :invokeblock_iseq_block_changed) jit_chain_guard(:jne, jit, ctx, asm, block_changed_exit) - jit_call_iseq_setup( - jit, ctx, asm, nil, flags, argc, comptime_iseq, :captured, + opt_pc = jit_callee_setup_block_arg(jit, ctx, asm, flags, argc, comptime_iseq, arg_setup_type: :arg_setup_block) + if opt_pc == CantCompile + return CantCompile + end + + jit_call_iseq_setup_normal( + jit, ctx, asm, nil, flags, argc, comptime_iseq, :captured, opt_pc, send_shift: 0, frame_type: C::VM_FRAME_MAGIC_BLOCK, ) - #gen_send_iseq( - # jit, - # ctx, - # asm, - # ocb, - # comptime_iseq, - # ci, - # VM_FRAME_MAGIC_BLOCK, - # None, - # 0, - # None, - # flags, - # argc, - # Some(captured_opnd), - #) elsif comptime_handler & 0x3 == 0x3 # VM_BH_IFUNC_P asm.incr_counter(:invokeblock_ifunc) CantCompile @@ -4028,7 +4012,7 @@ module RubyVM::RJIT # @param jit [RubyVM::RJIT::JITState] # @param ctx [RubyVM::RJIT::Context] # @param asm [RubyVM::RJIT::Assembler] - def jit_call_iseq_setup_normal(jit, ctx, asm, cme, flags, argc, iseq, block_handler, opt_pc, send_shift:, frame_type:, prev_ep:) + def jit_call_iseq_setup_normal(jit, ctx, asm, cme, flags, argc, iseq, block_handler, opt_pc, send_shift:, frame_type:, prev_ep: nil) # We will not have side exits from here. Adjust the stack. if flags & C::VM_CALL_OPT_SEND != 0 jit_call_opt_send_shift_stack(ctx, asm, argc, send_shift:) @@ -4640,6 +4624,35 @@ module RubyVM::RJIT return jit_setup_parameters_complex(jit, ctx, asm, flags, argc, iseq) end + # vm_callee_setup_block_arg: Set up args and return opt_pc (or CantCompile) + # @param jit [RubyVM::RJIT::JITState] + # @param ctx [RubyVM::RJIT::Context] + # @param asm [RubyVM::RJIT::Assembler] + def jit_callee_setup_block_arg(jit, ctx, asm, flags, argc, iseq, arg_setup_type:) + if C.rb_simple_iseq_p(iseq) + if jit_caller_setup_arg(jit, ctx, asm, flags) == CantCompile + return CantCompile + end + + if arg_setup_type == :arg_setup_block && + argc == 1 && + iseq.body.param.flags.has_lead && + !iseq.body.param.flags.ambiguous_param0 + asm.incr_counter(:invokeblock_iseq_arg0_splat) + return CantCompile + end + + if argc != iseq.body.param.lead_num + asm.incr_counter(:invokeblock_iseq_arity) + return CantCompile + end + + return 0 + else + return jit_setup_parameters_complex(jit, ctx, asm, flags, argc, iseq) + end + end + # setup_parameters_complex # @param jit [RubyVM::RJIT::JITState] # @param ctx [RubyVM::RJIT::Context] @@ -89,6 +89,8 @@ RJIT_RUNTIME_COUNTERS( invokeblock_proc, invokeblock_tag_changed, invokeblock_iseq_block_changed, + invokeblock_iseq_arity, + invokeblock_iseq_arg0_splat, getivar_megamorphic, getivar_not_heap, @@ -1321,6 +1321,8 @@ module RubyVM::RJIT # :nodoc: all invokeblock_proc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_proc)")], invokeblock_tag_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_tag_changed)")], invokeblock_iseq_block_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_block_changed)")], + invokeblock_iseq_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arity)")], + invokeblock_iseq_arg0_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arg0_splat)")], getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_megamorphic)")], getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_not_heap)")], getivar_special_const: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_special_const)")], |