зеркало из https://github.com/github/ruby.git
Optimize Integer#*
This commit is contained in:
Родитель
db4a8afa5e
Коммит
92efd0569a
|
@ -1684,7 +1684,10 @@ module RubyVM::MJIT
|
||||||
# @param jit [RubyVM::MJIT::JITState]
|
# @param jit [RubyVM::MJIT::JITState]
|
||||||
# @param ctx [RubyVM::MJIT::Context]
|
# @param ctx [RubyVM::MJIT::Context]
|
||||||
# @param asm [RubyVM::MJIT::Assembler]
|
# @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
|
recv = ctx.stack_pop
|
||||||
# This `test` sets ZF only for Qnil and Qfalse, which let cmovz set.
|
# This `test` sets ZF only for Qnil and Qfalse, which let cmovz set.
|
||||||
asm.test(recv, ~Qnil)
|
asm.test(recv, ~Qnil)
|
||||||
|
@ -1696,16 +1699,42 @@ module RubyVM::MJIT
|
||||||
true
|
true
|
||||||
end
|
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
|
# Helpers
|
||||||
#
|
#
|
||||||
|
|
||||||
def register_cfunc_codegen_funcs
|
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
|
end
|
||||||
|
|
||||||
def register_cfunc_method(klass, mid_str, func)
|
def register_cfunc_method(klass, mid_sym, func)
|
||||||
mid = C.rb_intern(mid_str)
|
mid = C.rb_intern(mid_sym.to_s)
|
||||||
me = C.rb_method_entry_at(klass, mid)
|
me = C.rb_method_entry_at(klass, mid)
|
||||||
|
|
||||||
assert_equal(false, me.nil?)
|
assert_equal(false, me.nil?)
|
||||||
|
@ -2589,7 +2618,7 @@ module RubyVM::MJIT
|
||||||
# Delegate to codegen for C methods if we have it.
|
# Delegate to codegen for C methods if we have it.
|
||||||
if flags & C.VM_CALL_KWARG == 0 && flags & C.VM_CALL_OPT_SEND == 0
|
if flags & C.VM_CALL_KWARG == 0 && flags & C.VM_CALL_OPT_SEND == 0
|
||||||
known_cfunc_codegen = lookup_cfunc_codegen(cme.def)
|
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
|
# cfunc codegen generated code. Terminate the block so
|
||||||
# there isn't multiple calls in the same block.
|
# there isn't multiple calls in the same block.
|
||||||
jump_to_next_insn(jit, ctx, asm)
|
jump_to_next_insn(jit, ctx, asm)
|
||||||
|
|
|
@ -278,6 +278,10 @@ module RubyVM::MJIT # :nodoc: all
|
||||||
me_addr == 0 ? nil : rb_method_entry_t.new(me_addr)
|
me_addr == 0 ? nil : rb_method_entry_t.new(me_addr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def rb_fix_mul_fix
|
||||||
|
Primitive.cexpr! 'SIZET2NUM((size_t)rb_fix_mul_fix)'
|
||||||
|
end
|
||||||
|
|
||||||
#========================================================================================
|
#========================================================================================
|
||||||
#
|
#
|
||||||
# Old stuff
|
# Old stuff
|
||||||
|
|
Загрузка…
Ссылка в новой задаче