RJIT: Optimize Kernel#block_given?

This commit is contained in:
Takashi Kokubun 2023-03-19 14:15:45 -07:00
parent 83ad1cac81
commit 2f29044de4
3 changed files with 46 additions and 1 deletions

View File

@ -243,6 +243,20 @@ module RubyVM::RJIT
end
end
def cmovne(dst, src)
case [dst, src]
# CMOVNE r64, r/m64 (Mod 11: reg)
in [R64 => dst_reg, R64 => src_reg]
# REX.W + 0F 45 /r
# RM: Operand 1: ModRM:reg (r, w), Operand 2: ModRM:r/m (r)
insn(
prefix: REX_W,
opcode: [0x0f, 0x45],
mod_rm: ModRM[mod: Mod11, reg: dst_reg, rm: src_reg],
)
end
end
def cmovnz(dst, src)
case [dst, src]
# CMOVNZ r64, r/m64 (Mod 11: reg)

View File

@ -3033,6 +3033,29 @@ module RubyVM::RJIT
true
end
# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
def jit_rb_f_block_given_p(jit, ctx, asm, argc, _known_recv_class)
asm.comment('block_given?')
# Same as rb_vm_frame_block_handler
jit_get_lep(jit, asm, reg: :rax)
asm.mov(:rax, [:rax, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]) # block_handler
ctx.stack_pop(1)
out_opnd = ctx.stack_push
# Return `block_handler != VM_BLOCK_HANDLER_NONE`
asm.cmp(:rax, C::VM_BLOCK_HANDLER_NONE)
asm.mov(:rax, Qfalse)
asm.mov(:rcx, Qtrue)
asm.cmovne(:rax, :rcx) # block_given
asm.mov(out_opnd, :rax)
true
end
# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
@ -3089,7 +3112,7 @@ module RubyVM::RJIT
register_cfunc_method(Array, :empty?, :jit_rb_ary_empty_p)
register_cfunc_method(Kernel, :respond_to?, :jit_obj_respond_to)
#register_cfunc_method(Kernel, :block_given?, :jit_rb_f_block_given_p)
register_cfunc_method(Kernel, :block_given?, :jit_rb_f_block_given_p)
# Thread.current
register_cfunc_method(C.rb_singleton_class(Thread), :current, :jit_thread_s_current)

View File

@ -93,6 +93,14 @@ module RubyVM::RJIT
EOS
end
def test_cmovne
asm = Assembler.new
asm.cmovne(:rax, :rbx) # CMOVNE r64, r/m64 (Mod 11: reg)
assert_compile(asm, <<~EOS) # cmovne == cmovnz
0x0: cmovne rax, rbx
EOS
end
def test_cmovnz
asm = Assembler.new
asm.cmovnz(:rax, :rbx) # CMOVNZ r64, r/m64 (Mod 11: reg)