summaryrefslogtreecommitdiff
path: root/lib/ruby_vm
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-02 22:43:55 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-05 23:28:59 -0800
commit92efd0569a1da349f8bc7f8214e3a780fd0c575a (patch)
tree5d67d9efec01e58b091e3686079c182c76863659 /lib/ruby_vm
parentdb4a8afa5e55591aa1e167ffde5924fc8f1f4807 (diff)
Optimize Integer#*
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7448
Diffstat (limited to 'lib/ruby_vm')
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb39
1 files changed, 34 insertions, 5 deletions
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index 6d241b7553..42f95cee1e 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -1684,7 +1684,10 @@ module RubyVM::MJIT
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
- def jit_rb_obj_not(jit, ctx, asm)
+ def jit_rb_obj_not(jit, ctx, asm, argc)
+ return false if argc != 0
+ asm.comment('jit_rb_obj_not')
+
recv = ctx.stack_pop
# This `test` sets ZF only for Qnil and Qfalse, which let cmovz set.
asm.test(recv, ~Qnil)
@@ -1696,16 +1699,42 @@ module RubyVM::MJIT
true
end
+ # @param jit [RubyVM::MJIT::JITState]
+ # @param ctx [RubyVM::MJIT::Context]
+ # @param asm [RubyVM::MJIT::Assembler]
+ def jit_rb_int_mul(jit, ctx, asm, argc)
+ return false if argc != 1
+ return false unless two_fixnums_on_stack?(jit)
+ asm.comment('jit_rb_int_mul')
+
+ side_exit = side_exit(jit, ctx)
+ guard_two_fixnums(jit, ctx, asm, side_exit)
+
+ jit_prepare_routine_call(jit, ctx, asm)
+
+ y_opnd = ctx.stack_pop
+ x_opnd = ctx.stack_pop
+ asm.mov(C_ARGS[0], x_opnd)
+ asm.mov(C_ARGS[1], y_opnd)
+ asm.call(C.rb_fix_mul_fix)
+
+ ret_opnd = ctx.stack_push
+ asm.mov(ret_opnd, C_RET)
+
+ true
+ end
+
#
# Helpers
#
def register_cfunc_codegen_funcs
- register_cfunc_method(BasicObject, '!', :jit_rb_obj_not)
+ register_cfunc_method(BasicObject, :!, :jit_rb_obj_not)
+ register_cfunc_method(Integer, :*, :jit_rb_int_mul)
end
- def register_cfunc_method(klass, mid_str, func)
- mid = C.rb_intern(mid_str)
+ def register_cfunc_method(klass, mid_sym, func)
+ mid = C.rb_intern(mid_sym.to_s)
me = C.rb_method_entry_at(klass, mid)
assert_equal(false, me.nil?)
@@ -2589,7 +2618,7 @@ module RubyVM::MJIT
# Delegate to codegen for C methods if we have it.
if flags & C.VM_CALL_KWARG == 0 && flags & C.VM_CALL_OPT_SEND == 0
known_cfunc_codegen = lookup_cfunc_codegen(cme.def)
- if known_cfunc_codegen&.call(jit, ctx, asm)
+ if known_cfunc_codegen&.call(jit, ctx, asm, argc)
# cfunc codegen generated code. Terminate the block so
# there isn't multiple calls in the same block.
jump_to_next_insn(jit, ctx, asm)