mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Add missing write barriers to Array#replace
Previously it made object references without using write barriers, creating GC inconsistencies. See: http://ci.rvm.jp/results/trunk-gc-asserts@phosphorus-docker/3925529
This commit is contained in:
		
							parent
							
								
									0626e6f959
								
							
						
					
					
						commit
						c416dbb3c7
					
				
				
				Notes:
				
					git
				
				2022-04-29 00:31:52 +09:00 
				
			
			
			
		
		
					 2 changed files with 12 additions and 2 deletions
				
			
		
							
								
								
									
										6
									
								
								array.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								array.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -4680,14 +4680,16 @@ rb_ary_replace(VALUE copy, VALUE orig)
 | 
			
		|||
     * contents of orig. */
 | 
			
		||||
    else if (ARY_EMBED_P(orig)) {
 | 
			
		||||
        long len = ARY_EMBED_LEN(orig);
 | 
			
		||||
 | 
			
		||||
        VALUE *ptr = ary_heap_alloc(copy, len);
 | 
			
		||||
        MEMCPY(ptr, ARY_EMBED_PTR(orig), VALUE, len);
 | 
			
		||||
 | 
			
		||||
        FL_UNSET_EMBED(copy);
 | 
			
		||||
        ARY_SET_PTR(copy, ptr);
 | 
			
		||||
        ARY_SET_LEN(copy, len);
 | 
			
		||||
        ARY_SET_CAPA(copy, len);
 | 
			
		||||
 | 
			
		||||
        // No allocation and exception expected that could leave `copy` in a
 | 
			
		||||
        // bad state from the edits above.
 | 
			
		||||
        ary_memcpy(copy, 0, len, RARRAY_CONST_PTR_TRANSIENT(orig));
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    /* Otherwise, orig is on heap and copy does not have enough space to embed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1439,6 +1439,14 @@ class TestArray < Test::Unit::TestCase
 | 
			
		|||
    assert_raise(FrozenError) { fa.replace(42) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_replace_wb_variable_width_alloc
 | 
			
		||||
    small_embed = []
 | 
			
		||||
    4.times { GC.start } # age small_embed
 | 
			
		||||
    large_embed = [1, 2, 3, 4, 5, Array.new] # new young object
 | 
			
		||||
    small_embed.replace(large_embed) # adds old to young reference
 | 
			
		||||
    GC.verify_internal_consistency
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_reverse
 | 
			
		||||
    a = @cls[*%w( dog cat bee ant )]
 | 
			
		||||
    assert_equal(@cls[*%w(ant bee cat dog)], a.reverse)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue