RJIT: Upgrade type to Fixnum after guard

This commit is contained in:
Takashi Kokubun 2023-04-03 00:02:45 -07:00
Родитель 0abe9d8b32
Коммит 1d452c2cf8
2 изменённых файлов: 60 добавлений и 8 удалений

Просмотреть файл

@ -3667,15 +3667,48 @@ module RubyVM::RJIT
arg1 = ctx.stack_opnd(0)
arg0 = ctx.stack_opnd(1)
asm.comment('guard arg0 fixnum')
asm.test(arg0, C::RUBY_FIXNUM_FLAG)
jit_chain_guard(:jz, jit, ctx, asm, side_exit)
# TODO: upgrade type, and skip the check when possible
# Get the stack operand types
arg1_type = ctx.get_opnd_type(StackOpnd[0])
arg0_type = ctx.get_opnd_type(StackOpnd[1])
asm.comment('guard arg1 fixnum')
asm.test(arg1, C::RUBY_FIXNUM_FLAG)
jit_chain_guard(:jz, jit, ctx, asm, side_exit)
# TODO: upgrade type, and skip the check when possible
if arg0_type.heap? || arg1_type.heap?
asm.comment('arg is heap object')
asm.jmp(side_exit)
return
end
if arg0_type != Type::Fixnum && arg0_type.specific?
asm.comment('arg0 not fixnum')
asm.jmp(side_exit)
return
end
if arg1_type != Type::Fixnum && arg1_type.specific?
asm.comment('arg1 not fixnum')
asm.jmp(side_exit)
return
end
assert(!arg0_type.heap?)
assert(!arg1_type.heap?)
assert(arg0_type == Type::Fixnum || arg0_type.unknown?)
assert(arg1_type == Type::Fixnum || arg1_type.unknown?)
# If not fixnums at run-time, fall back
if arg0_type != Type::Fixnum
asm.comment('guard arg0 fixnum')
asm.test(arg0, C::RUBY_FIXNUM_FLAG)
jit_chain_guard(:jz, jit, ctx, asm, side_exit)
end
if arg1_type != Type::Fixnum
asm.comment('guard arg1 fixnum')
asm.test(arg1, C::RUBY_FIXNUM_FLAG)
jit_chain_guard(:jz, jit, ctx, asm, side_exit)
end
# Set stack types in context
ctx.upgrade_opnd_type(StackOpnd[0], Type::Fixnum)
ctx.upgrade_opnd_type(StackOpnd[1], Type::Fixnum)
end
# @param jit [RubyVM::RJIT::JITState]
@ -5642,6 +5675,10 @@ module RubyVM::RJIT
asm.cmovnz(ary_opnd, array_reg)
end
def assert(cond)
assert_equal(cond, true)
end
def assert_equal(left, right)
if left != right
raise "'#{left.inspect}' was not '#{right.inspect}'"

Просмотреть файл

@ -15,6 +15,21 @@ module RubyVM::RJIT
end
end
# Returns true when the type is not specific.
def unknown?
case self
in Type::Unknown | Type::UnknownImm | Type::UnknownHeap then true
else false
end
end
# Returns true when we know the VALUE is a specific handle type,
# such as a static symbol ([Type::ImmSymbol], i.e. true from RB_STATIC_SYM_P()).
# Opposite of [Self::is_unknown].
def specific?
!self.unknown?
end
# Check if the type is a heap object
def heap?
case self