mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Make sure vm_call_cfunc uses inlined cc
which is checked by the first guard. When JIT-inlined cc and operand cd->cc are different, the JIT-ed code might wrongly dispatch cd->cc even while class check is done with another cc inlined by JIT. This fixes SEGV on railsbench.
This commit is contained in:
parent
4989987419
commit
7fa3c71bec
2 changed files with 18 additions and 2 deletions
|
@ -793,6 +793,22 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end;
|
end;
|
||||||
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
|
def test_inlined_exivar
|
||||||
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 3, recompile_count: 1, min_calls: 2)
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "aaa", success_count: 3, recompile_count: 1, min_calls: 2)
|
||||||
begin;
|
begin;
|
||||||
|
|
|
@ -75,8 +75,8 @@
|
||||||
|
|
||||||
if (vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_CFUNC) {
|
if (vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_CFUNC) {
|
||||||
% # TODO: optimize this more
|
% # TODO: optimize this more
|
||||||
fprintf(f, " CALL_DATA cd = (CALL_DATA)0x%"PRIxVALUE";\n", operands[0]);
|
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, cd);\n");
|
fprintf(f, " val = vm_call_cfunc_with_frame(ec, reg_cfp, &calling, &cc_cd);\n");
|
||||||
}
|
}
|
||||||
else { // VM_METHOD_TYPE_ISEQ
|
else { // VM_METHOD_TYPE_ISEQ
|
||||||
% # fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
|
% # fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
|
||||||
|
|
Loading…
Add table
Reference in a new issue