diff --git a/test/ruby/test_jit.rb b/test/ruby/test_jit.rb index 08093a5817..c1f2f7a6d5 100644 --- a/test/ruby/test_jit.rb +++ b/test/ruby/test_jit.rb @@ -793,6 +793,22 @@ class TestJIT < Test::Unit::TestCase end; end + def test_inlined_c_method + assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 2, recompile_count: 1, min_calls: 2) + begin; + def test(obj, recursive: nil) + if recursive + test(recursive) + end + obj.to_s + end + + print(test('a')) # set #to_s cc to String#to_s (expecting C method) + print(test('a')) # JIT with #to_s cc: String#to_s + print(test('a', recursive: :foo)) # update #to_s cd->cc to Symbol#to_s, then go through inlined #to_s cc with Symbol#to_s + end; + end + def test_inlined_exivar assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 3, recompile_count: 1, min_calls: 2) begin; diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb index 6b271d4d74..2dff0165bd 100644 --- a/tool/ruby_vm/views/_mjit_compile_send.erb +++ b/tool/ruby_vm/views/_mjit_compile_send.erb @@ -75,8 +75,8 @@ if (vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_CFUNC) { % # TODO: optimize this more - fprintf(f, " CALL_DATA cd = (CALL_DATA)0x%"PRIxVALUE";\n", operands[0]); - fprintf(f, " val = vm_call_cfunc_with_frame(ec, reg_cfp, &calling, cd);\n"); + fprintf(f, " struct rb_call_data cc_cd = { .ci = (CALL_INFO)0x%"PRIxVALUE", .cc = cc };\n", (VALUE)ci); // creating local cd here because operand's cd->cc may not be the same as inlined cc. + fprintf(f, " val = vm_call_cfunc_with_frame(ec, reg_cfp, &calling, &cc_cd);\n"); } else { // VM_METHOD_TYPE_ISEQ % # fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE