diff options
author | Takashi Kokubun <[email protected]> | 2023-03-19 14:15:45 -0700 |
---|---|---|
committer | Takashi Kokubun <[email protected]> | 2023-03-19 14:15:45 -0700 |
commit | 2f29044de48ed3f468c09ea3c5c214791370037f (patch) | |
tree | 097eef9f6974c9a384c8ee2ad8df606965505366 /lib | |
parent | 83ad1cac811b144b0016fdbfc9d83c11fd190349 (diff) |
RJIT: Optimize Kernel#block_given?
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ruby_vm/rjit/assembler.rb | 14 | ||||
-rw-r--r-- | lib/ruby_vm/rjit/insn_compiler.rb | 25 |
2 files changed, 38 insertions, 1 deletions
diff --git a/lib/ruby_vm/rjit/assembler.rb b/lib/ruby_vm/rjit/assembler.rb index bd8f8ad1d6..35f01392c9 100644 --- a/lib/ruby_vm/rjit/assembler.rb +++ b/lib/ruby_vm/rjit/assembler.rb @@ -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) diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb index b05578b6c8..e65da9c36f 100644 --- a/lib/ruby_vm/rjit/insn_compiler.rb +++ b/lib/ruby_vm/rjit/insn_compiler.rb @@ -3036,6 +3036,29 @@ module RubyVM::RJIT # @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] def jit_thread_s_current(jit, ctx, asm, argc, _known_recv_class) return false if argc != 0 asm.comment('Thread.current') @@ -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) |