RJIT: Upgrade type to Fixnum after guard
This commit is contained in:
parent
0abe9d8b32
commit
1d452c2cf8
@ -3667,15 +3667,48 @@ module RubyVM::RJIT
|
|||||||
arg1 = ctx.stack_opnd(0)
|
arg1 = ctx.stack_opnd(0)
|
||||||
arg0 = ctx.stack_opnd(1)
|
arg0 = ctx.stack_opnd(1)
|
||||||
|
|
||||||
asm.comment('guard arg0 fixnum')
|
# Get the stack operand types
|
||||||
asm.test(arg0, C::RUBY_FIXNUM_FLAG)
|
arg1_type = ctx.get_opnd_type(StackOpnd[0])
|
||||||
jit_chain_guard(:jz, jit, ctx, asm, side_exit)
|
arg0_type = ctx.get_opnd_type(StackOpnd[1])
|
||||||
# TODO: upgrade type, and skip the check when possible
|
|
||||||
|
|
||||||
asm.comment('guard arg1 fixnum')
|
if arg0_type.heap? || arg1_type.heap?
|
||||||
asm.test(arg1, C::RUBY_FIXNUM_FLAG)
|
asm.comment('arg is heap object')
|
||||||
jit_chain_guard(:jz, jit, ctx, asm, side_exit)
|
asm.jmp(side_exit)
|
||||||
# TODO: upgrade type, and skip the check when possible
|
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
|
end
|
||||||
|
|
||||||
# @param jit [RubyVM::RJIT::JITState]
|
# @param jit [RubyVM::RJIT::JITState]
|
||||||
@ -5642,6 +5675,10 @@ module RubyVM::RJIT
|
|||||||
asm.cmovnz(ary_opnd, array_reg)
|
asm.cmovnz(ary_opnd, array_reg)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assert(cond)
|
||||||
|
assert_equal(cond, true)
|
||||||
|
end
|
||||||
|
|
||||||
def assert_equal(left, right)
|
def assert_equal(left, right)
|
||||||
if left != right
|
if left != right
|
||||||
raise "'#{left.inspect}' was not '#{right.inspect}'"
|
raise "'#{left.inspect}' was not '#{right.inspect}'"
|
||||||
|
@ -15,6 +15,21 @@ module RubyVM::RJIT
|
|||||||
end
|
end
|
||||||
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
|
# Check if the type is a heap object
|
||||||
def heap?
|
def heap?
|
||||||
case self
|
case self
|
||||||
|
Loading…
x
Reference in New Issue
Block a user