RJIT: Upgrade type to Array after guard
This commit is contained in:
parent
d876c008ec
commit
f0b69eb14f
@ -994,8 +994,7 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
# Move the array from the stack and check that it's an array.
|
# Move the array from the stack and check that it's an array.
|
||||||
asm.mov(:rax, array_opnd)
|
asm.mov(:rax, array_opnd)
|
||||||
guard_object_is_heap(jit, ctx, asm, :rax, array_stack_opnd, :expandarray_not_array)
|
guard_object_is_array(jit, ctx, asm, :rax, :rcx, array_stack_opnd, :expandarray_not_array)
|
||||||
guard_object_is_array(asm, :rax, :rcx, counted_exit(side_exit, :expandarray_not_array))
|
|
||||||
ctx.stack_pop(1) # pop after using the type info
|
ctx.stack_pop(1) # pop after using the type info
|
||||||
|
|
||||||
# If we don't actually want any values, then just return.
|
# If we don't actually want any values, then just return.
|
||||||
@ -3472,8 +3471,20 @@ module RubyVM::RJIT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @param jit [RubyVM::RJIT::JITState]
|
||||||
|
# @param ctx [RubyVM::RJIT::Context]
|
||||||
# @param asm [RubyVM::RJIT::Assembler]
|
# @param asm [RubyVM::RJIT::Assembler]
|
||||||
def guard_object_is_array(asm, object_reg, flags_reg, side_exit)
|
def guard_object_is_array(jit, ctx, asm, object_reg, flags_reg, object_opnd, counter = nil)
|
||||||
|
object_type = ctx.get_opnd_type(object_opnd)
|
||||||
|
if object_type.array?
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
guard_object_is_heap(jit, ctx, asm, object_reg, object_opnd, counter)
|
||||||
|
|
||||||
|
side_exit = side_exit(jit, ctx)
|
||||||
|
side_exit = counted_exit(side_exit, counter) if counter
|
||||||
|
|
||||||
asm.comment('guard object is array')
|
asm.comment('guard object is array')
|
||||||
# Pull out the type mask
|
# Pull out the type mask
|
||||||
asm.mov(flags_reg, [object_reg, C.RBasic.offsetof(:flags)])
|
asm.mov(flags_reg, [object_reg, C.RBasic.offsetof(:flags)])
|
||||||
@ -3482,6 +3493,10 @@ module RubyVM::RJIT
|
|||||||
# Compare the result with T_ARRAY
|
# Compare the result with T_ARRAY
|
||||||
asm.cmp(flags_reg, C::RUBY_T_ARRAY)
|
asm.cmp(flags_reg, C::RUBY_T_ARRAY)
|
||||||
asm.jne(side_exit)
|
asm.jne(side_exit)
|
||||||
|
|
||||||
|
if object_type.diff(Type::TArray) != TypeDiff::Incompatible
|
||||||
|
ctx.upgrade_opnd_type(object_opnd, Type::TArray)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def guard_object_is_string(asm, object_reg, flags_reg, side_exit)
|
def guard_object_is_string(asm, object_reg, flags_reg, side_exit)
|
||||||
@ -5527,8 +5542,7 @@ module RubyVM::RJIT
|
|||||||
array_reg = :rax
|
array_reg = :rax
|
||||||
asm.mov(array_reg, array_opnd)
|
asm.mov(array_reg, array_opnd)
|
||||||
|
|
||||||
guard_object_is_heap(jit, ctx, asm, array_reg, array_stack_opnd, :send_args_splat_not_array)
|
guard_object_is_array(jit, ctx, asm, array_reg, :rcx, array_stack_opnd, :send_args_splat_not_array)
|
||||||
guard_object_is_array(asm, array_reg, :rcx, counted_exit(side_exit, :send_args_splat_not_array))
|
|
||||||
|
|
||||||
array_len_opnd = :rcx
|
array_len_opnd = :rcx
|
||||||
jit_array_len(asm, array_reg, array_len_opnd)
|
jit_array_len(asm, array_reg, array_len_opnd)
|
||||||
|
@ -30,6 +30,15 @@ module RubyVM::RJIT
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Check if it's a T_ARRAY object (both TArray and CArray are T_ARRAY)
|
||||||
|
def array?
|
||||||
|
case self
|
||||||
|
in Type::TArray then true
|
||||||
|
in Type::CArray then true
|
||||||
|
else false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Returns a boolean representing whether the value is truthy if known, otherwise nil
|
# Returns a boolean representing whether the value is truthy if known, otherwise nil
|
||||||
def known_truthy
|
def known_truthy
|
||||||
case self
|
case self
|
||||||
|
Loading…
x
Reference in New Issue
Block a user