Implement `opt_aref_with` instruction (#8118)

Implement gen_opt_aref_with

Vm opt_aref_with is available

Test opt_aref_with

Stats for opt_aref_with

Co-authored-by: jhawthorn <jhawthorn@github.com>
This commit is contained in:
ywenc 2023-07-26 10:38:59 -04:00 коммит произвёл GitHub
Родитель 786a864900
Коммит 8ca399d640
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 61 добавлений и 0 удалений

Просмотреть файл

@ -1100,6 +1100,18 @@ assert_equal '[42, :default]', %q{
]
}
# Test default value block for Hash with opt_aref_with
assert_equal "false", %q{
def index_with_string(h)
h["foo"]
end
h = Hash.new { |h, k| k.frozen? }
index_with_string(h)
index_with_string(h)
}
# A regression test for making sure cfp->sp is proper when
# hitting stubs. See :stub-sp-flush:
assert_equal 'ok', %q{

Просмотреть файл

@ -1289,6 +1289,14 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
def test_opt_aref_with
assert_compiles(<<~RUBY, insns: %i[opt_aref_with], result: "bar")
h = {"foo" => "bar"}
h["foo"]
RUBY
end
private
def code_gc_helpers

Просмотреть файл

@ -6259,6 +6259,12 @@ vm_opt_aref_with(VALUE recv, VALUE key)
}
}
VALUE
rb_vm_opt_aref_with(VALUE recv, VALUE key)
{
return vm_opt_aref_with(recv, key);
}
static VALUE
vm_opt_aset_with(VALUE recv, VALUE key, VALUE val)
{

Просмотреть файл

@ -259,6 +259,7 @@ module RubyVM::YJIT
print_counters(stats, out: out, prefix: 'setivar_', prompt: 'setinstancevariable exit reasons:')
print_counters(stats, out: out, prefix: 'definedivar_', prompt: 'definedivar exit reasons:')
print_counters(stats, out: out, prefix: 'opt_aref_', prompt: 'opt_aref exit reasons: ')
print_counters(stats, out: out, prefix: 'opt_aref_with_', prompt: 'opt_aref_with exit reasons: ')
print_counters(stats, out: out, prefix: 'expandarray_', prompt: 'expandarray exit reasons: ')
print_counters(stats, out: out, prefix: 'opt_getinlinecache_', prompt: 'opt_getinlinecache exit reasons: ')
print_counters(stats, out: out, prefix: 'invalidate_', prompt: 'invalidation reasons: ')

Просмотреть файл

@ -3064,6 +3064,37 @@ fn gen_opt_aset(
}
}
fn gen_opt_aref_with(
jit: &mut JITState,
asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> Option<CodegenStatus>{
jit_prepare_routine_call(jit, asm);
let key_opnd = Opnd::Value(jit.get_arg(0));
let recv_opnd = asm.stack_pop(1);
extern "C" {
fn rb_vm_opt_aref_with(recv: VALUE, key: VALUE) -> VALUE;
}
let val_opnd = asm.ccall(
rb_vm_opt_aref_with as *const u8,
vec![
recv_opnd,
key_opnd
],
);
asm.cmp(val_opnd, Qundef.into());
asm.je(Target::side_exit(Counter::opt_aref_with_qundef));
let top = asm.stack_push(Type::Unknown);
asm.mov(top, val_opnd);
return Some(KeepCompiling);
}
fn gen_opt_and(
jit: &mut JITState,
asm: &mut Assembler,
@ -8040,6 +8071,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_opt_neq => Some(gen_opt_neq),
YARVINSN_opt_aref => Some(gen_opt_aref),
YARVINSN_opt_aset => Some(gen_opt_aset),
YARVINSN_opt_aref_with => Some(gen_opt_aref_with),
YARVINSN_opt_mult => Some(gen_opt_mult),
YARVINSN_opt_div => Some(gen_opt_div),
YARVINSN_opt_ltlt => Some(gen_opt_ltlt),

Просмотреть файл

@ -344,6 +344,8 @@ make_counters! {
opt_aset_not_fixnum,
opt_aset_not_hash,
opt_aref_with_qundef,
opt_case_dispatch_megamorphic,
opt_getinlinecache_miss,