mirror of
https://github.com/ruby/ruby.git
synced 2025-08-23 21:14:23 +02:00
Check ROBJECT_EMBED on guards-merged ivar access
Fix CI failure like
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/3043247
introduced by a69dd699ee
This commit is contained in:
parent
c146362555
commit
e4f7eee009
2 changed files with 37 additions and 18 deletions
|
@ -921,6 +921,34 @@ class TestJIT < Test::Unit::TestCase
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_heap_promotion_of_ivar_in_the_middle_of_jit
|
||||||
|
assert_eval_with_jit("#{<<~"begin;"}\n#{<<~"end;"}", stdout: "true\ntrue\n", success_count: 2, min_calls: 2)
|
||||||
|
begin;
|
||||||
|
class A
|
||||||
|
def initialize
|
||||||
|
@iv0 = nil
|
||||||
|
@iv1 = []
|
||||||
|
@iv2 = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def test(add)
|
||||||
|
@iv0.nil?
|
||||||
|
@iv2.nil?
|
||||||
|
add_ivar if add
|
||||||
|
@iv1.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_ivar
|
||||||
|
@iv3 = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
a = A.new
|
||||||
|
p a.test(false)
|
||||||
|
p a.test(true)
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
def test_jump_to_precompiled_branch
|
def test_jump_to_precompiled_branch
|
||||||
assert_eval_with_jit("#{<<~'begin;'}\n#{<<~'end;'}", stdout: ".0", success_count: 1, min_calls: 1)
|
assert_eval_with_jit("#{<<~'begin;'}\n#{<<~'end;'}", stdout: ".0", success_count: 1, min_calls: 1)
|
||||||
begin;
|
begin;
|
||||||
|
|
|
@ -24,30 +24,21 @@
|
||||||
fprintf(f, "{\n");
|
fprintf(f, "{\n");
|
||||||
fprintf(f, " VALUE obj = GET_SELF();\n");
|
fprintf(f, " VALUE obj = GET_SELF();\n");
|
||||||
fprintf(f, " const st_index_t index = %"PRIuSIZE";\n", ic_copy->index);
|
fprintf(f, " const st_index_t index = %"PRIuSIZE";\n", ic_copy->index);
|
||||||
fprintf(f, " VALUE val;\n");
|
|
||||||
if (status->merge_ivar_guards_p) {
|
if (status->merge_ivar_guards_p) {
|
||||||
% # JIT: Access ivar without checking these VM_ASSERTed prerequisites as we checked them in the beginning of `mjit_compile_body`
|
% # JIT: Access ivar without checking these VM_ASSERTed prerequisites as we checked them in the beginning of `mjit_compile_body`
|
||||||
fprintf(f, " VM_ASSERT(RB_TYPE_P(obj, T_OBJECT));\n");
|
fprintf(f, " VM_ASSERT(RB_TYPE_P(obj, T_OBJECT));\n");
|
||||||
fprintf(f, " VM_ASSERT((rb_serial_t)%"PRI_SERIALT_PREFIX"u == RCLASS_SERIAL(RBASIC(obj)->klass));\n", ic_copy->ic_serial);
|
fprintf(f, " VM_ASSERT((rb_serial_t)%"PRI_SERIALT_PREFIX"u == RCLASS_SERIAL(RBASIC(obj)->klass));\n", ic_copy->ic_serial);
|
||||||
fprintf(f, " VM_ASSERT(index < ROBJECT_NUMIV(obj));\n");
|
fprintf(f, " VM_ASSERT(index < ROBJECT_NUMIV(obj));\n");
|
||||||
% if insn.name == 'setinstancevariable'
|
% if insn.name == 'setinstancevariable'
|
||||||
fprintf(f, " if (LIKELY(!RB_OBJ_FROZEN(obj))) {\n");
|
fprintf(f, " if (LIKELY(!RB_OBJ_FROZEN(obj) && %sRB_FL_ANY_RAW(obj, ROBJECT_EMBED))) {\n", status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "!" : "");
|
||||||
fprintf(f, " val = stack[%d];\n", b->stack_size - 1);
|
fprintf(f, " RB_OBJ_WRITE(obj, &ROBJECT(obj)->as.%s, stack[%d]);\n",
|
||||||
if (status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX) {
|
status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "heap.ivptr[index]" : "ary[index]", b->stack_size - 1);
|
||||||
fprintf(f, " RB_OBJ_WRITE(obj, &ROBJECT(obj)->as.heap.ivptr[index], val);\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fprintf(f, " RB_OBJ_WRITE(obj, &ROBJECT(obj)->as.ary[index], val);\n");
|
|
||||||
}
|
|
||||||
fprintf(f, " }\n");
|
fprintf(f, " }\n");
|
||||||
% else
|
% else
|
||||||
if (status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX) {
|
fprintf(f, " VALUE val;\n");
|
||||||
fprintf(f, " val = ROBJECT(obj)->as.heap.ivptr[index];\n");
|
fprintf(f, " if (LIKELY(%sRB_FL_ANY_RAW(obj, ROBJECT_EMBED) && (val = ROBJECT(obj)->as.%s) != Qundef)) {\n",
|
||||||
}
|
status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "!" : "",
|
||||||
else {
|
status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "heap.ivptr[index]" : "ary[index]");
|
||||||
fprintf(f, " val = ROBJECT(obj)->as.ary[index];\n");
|
|
||||||
}
|
|
||||||
fprintf(f, " if (LIKELY(val != Qundef)) {\n");
|
|
||||||
fprintf(f, " stack[%d] = val;\n", b->stack_size);
|
fprintf(f, " stack[%d] = val;\n", b->stack_size);
|
||||||
fprintf(f, " }\n");
|
fprintf(f, " }\n");
|
||||||
%end
|
%end
|
||||||
|
@ -56,12 +47,12 @@
|
||||||
fprintf(f, " const rb_serial_t ic_serial = (rb_serial_t)%"PRI_SERIALT_PREFIX"u;\n", ic_copy->ic_serial);
|
fprintf(f, " const rb_serial_t ic_serial = (rb_serial_t)%"PRI_SERIALT_PREFIX"u;\n", ic_copy->ic_serial);
|
||||||
% # JIT: cache hit path of vm_getivar/vm_setivar, or cancel JIT (recompile it with exivar)
|
% # JIT: cache hit path of vm_getivar/vm_setivar, or cancel JIT (recompile it with exivar)
|
||||||
% if insn.name == 'setinstancevariable'
|
% if insn.name == 'setinstancevariable'
|
||||||
fprintf(f, " val = stack[%d];\n", b->stack_size - 1);
|
|
||||||
fprintf(f, " if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && !RB_OBJ_FROZEN(obj))) {\n");
|
fprintf(f, " if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && !RB_OBJ_FROZEN(obj))) {\n");
|
||||||
fprintf(f, " VALUE *ptr = ROBJECT_IVPTR(obj);\n");
|
fprintf(f, " VALUE *ptr = ROBJECT_IVPTR(obj);\n");
|
||||||
fprintf(f, " RB_OBJ_WRITE(obj, &ptr[index], val);\n");
|
fprintf(f, " RB_OBJ_WRITE(obj, &ptr[index], stack[%d]);\n", b->stack_size - 1);
|
||||||
fprintf(f, " }\n");
|
fprintf(f, " }\n");
|
||||||
% else
|
% else
|
||||||
|
fprintf(f, " VALUE val;\n");
|
||||||
fprintf(f, " if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && (val = ROBJECT_IVPTR(obj)[index]) != Qundef)) {\n");
|
fprintf(f, " if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && (val = ROBJECT_IVPTR(obj)[index]) != Qundef)) {\n");
|
||||||
fprintf(f, " stack[%d] = val;\n", b->stack_size);
|
fprintf(f, " stack[%d] = val;\n", b->stack_size);
|
||||||
fprintf(f, " }\n");
|
fprintf(f, " }\n");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue