diff options
Diffstat (limited to 'lib/ruby_vm/rjit/insn_compiler.rb')
-rw-r--r-- | lib/ruby_vm/rjit/insn_compiler.rb | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb index c892ee8c5c..2c8086345d 100644 --- a/lib/ruby_vm/rjit/insn_compiler.rb +++ b/lib/ruby_vm/rjit/insn_compiler.rb @@ -2995,7 +2995,7 @@ module RubyVM::RJIT # Guard that the concat argument is a string asm.mov(:rax, ctx.stack_opnd(0)) - guard_object_is_string(asm, :rax, :rcx, side_exit) + guard_object_is_string(jit, ctx, asm, :rax, :rcx, StackOpnd[0]) # Guard buffers from GC since rb_str_buf_append may allocate. During the VM lock on GC, # other Ractors may trigger global invalidation, so we need ctx.clear_local_types. @@ -3499,7 +3499,20 @@ module RubyVM::RJIT end end - def guard_object_is_string(asm, object_reg, flags_reg, side_exit) + # @param jit [RubyVM::RJIT::JITState] + # @param ctx [RubyVM::RJIT::Context] + # @param asm [RubyVM::RJIT::Assembler] + def guard_object_is_string(jit, ctx, asm, object_reg, flags_reg, object_opnd, counter = nil) + object_type = ctx.get_opnd_type(object_opnd) + if object_type.string? + 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 string') # Pull out the type mask asm.mov(flags_reg, [object_reg, C.RBasic.offsetof(:flags)]) @@ -3508,6 +3521,10 @@ module RubyVM::RJIT # Compare the result with T_STRING asm.cmp(flags_reg, C::RUBY_T_STRING) asm.jne(side_exit) + + if object_type.diff(Type::TString) != TypeDiff::Incompatible + ctx.upgrade_opnd_type(object_opnd, Type::TString) + end end # clobbers object_reg |