mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Revert incorrect string-guard optimisation. (#5969)
Also add jhawthorn's test to for this bug. Fix String#to_s invalidation test
This commit is contained in:
		
							parent
							
								
									1177665e62
								
							
						
					
					
						commit
						9d18661e1d
					
				
				
				Notes:
				
					git
				
				2022-06-01 23:22:37 +09:00 
				
			
			Merged-By: maximecb <maximecb@ruby-lang.org>
					 2 changed files with 31 additions and 27 deletions
				
			
		| 
						 | 
				
			
			@ -1339,12 +1339,42 @@ assert_equal 'foo123', %q{
 | 
			
		|||
 | 
			
		||||
# test that invalidation of String#to_s doesn't crash
 | 
			
		||||
assert_equal 'meh', %q{
 | 
			
		||||
  def inval_method
 | 
			
		||||
    "".to_s
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  inval_method
 | 
			
		||||
 | 
			
		||||
  class String
 | 
			
		||||
    def to_s
 | 
			
		||||
      "meh"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  "".to_s
 | 
			
		||||
 | 
			
		||||
  inval_method
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# test that overriding to_s on a String subclass isn't over-optimised
 | 
			
		||||
assert_equal 'meh', %q{
 | 
			
		||||
  class MyString < String
 | 
			
		||||
    def to_s
 | 
			
		||||
      "meh"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_to_s(obj)
 | 
			
		||||
    obj.to_s
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  OBJ = MyString.new
 | 
			
		||||
 | 
			
		||||
  # Should return 'meh' both times
 | 
			
		||||
  test_to_s("")
 | 
			
		||||
  test_to_s("")
 | 
			
		||||
 | 
			
		||||
  # Can return '' if YJIT optimises String#to_s too aggressively
 | 
			
		||||
  test_to_s(OBJ)
 | 
			
		||||
  test_to_s(OBJ)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# test string interpolation with overridden to_s
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3421,32 +3421,6 @@ fn jit_guard_known_klass(
 | 
			
		|||
            jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
 | 
			
		||||
            ctx.upgrade_opnd_type(insn_opnd, Type::Flonum);
 | 
			
		||||
        }
 | 
			
		||||
    } else if unsafe { known_klass == rb_cString } && sample_instance.string_p() {
 | 
			
		||||
        assert!(!val_type.is_imm());
 | 
			
		||||
        if val_type != Type::String {
 | 
			
		||||
            assert!(val_type.is_unknown());
 | 
			
		||||
 | 
			
		||||
            // Need the check for immediate, because trying to look up the klass field of an immediate will segfault
 | 
			
		||||
            if !val_type.is_heap() {
 | 
			
		||||
                add_comment(cb, "guard not immediate (for string)");
 | 
			
		||||
                assert!(Qfalse.as_i32() < Qnil.as_i32());
 | 
			
		||||
                test(cb, REG0, imm_opnd(RUBY_IMMEDIATE_MASK as i64));
 | 
			
		||||
                jit_chain_guard(JCC_JNZ, jit, ctx, cb, ocb, max_chain_depth, side_exit);
 | 
			
		||||
                cmp(cb, REG0, imm_opnd(Qnil.into()));
 | 
			
		||||
                jit_chain_guard(JCC_JBE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            add_comment(cb, "guard object is string");
 | 
			
		||||
            let klass_opnd = mem_opnd(64, REG0, RUBY_OFFSET_RBASIC_KLASS);
 | 
			
		||||
            mov(cb, REG1, uimm_opnd(unsafe { rb_cString }.into()));
 | 
			
		||||
            cmp(cb, klass_opnd, REG1);
 | 
			
		||||
            jit_chain_guard(JCC_JNE, jit, ctx, cb, ocb, max_chain_depth, side_exit);
 | 
			
		||||
 | 
			
		||||
            // Upgrading here causes an error with invalidation writing past end of block
 | 
			
		||||
            ctx.upgrade_opnd_type(insn_opnd, Type::String);
 | 
			
		||||
        } else {
 | 
			
		||||
            add_comment(cb, "skip guard - known to be a string");
 | 
			
		||||
        }
 | 
			
		||||
    } else if unsafe {
 | 
			
		||||
        FL_TEST(known_klass, VALUE(RUBY_FL_SINGLETON)) != VALUE(0)
 | 
			
		||||
            && sample_instance == rb_attr_get(known_klass, id__attached__ as ID)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue