summaryrefslogtreecommitdiff
path: root/lib/ruby_vm
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-19 14:15:45 -0700
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-19 14:15:45 -0700
commit2f29044de48ed3f468c09ea3c5c214791370037f (patch)
tree097eef9f6974c9a384c8ee2ad8df606965505366 /lib/ruby_vm
parent83ad1cac811b144b0016fdbfc9d83c11fd190349 (diff)
RJIT: Optimize Kernel#block_given?
Diffstat (limited to 'lib/ruby_vm')
-rw-r--r--lib/ruby_vm/rjit/assembler.rb14
-rw-r--r--lib/ruby_vm/rjit/insn_compiler.rb25
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)