Fix compaction during ary_make_partial
The ary_make_shared call may allocate, which can trigger a GC compaction. This can cause the array to be embedded because it has a length of 0.
This commit is contained in:
parent
3af56e87ca
commit
150ed44d87
5
array.c
5
array.c
@ -1204,7 +1204,10 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len)
|
||||
else {
|
||||
VALUE shared = ary_make_shared(ary);
|
||||
|
||||
assert(!ARY_EMBED_P(result));
|
||||
/* The ary_make_shared call may allocate, which can trigger a GC
|
||||
* compaction. This can cause the array to be embedded because it has
|
||||
* a length of 0. */
|
||||
FL_UNSET_EMBED(result);
|
||||
|
||||
ARY_SET_PTR(result, RARRAY_CONST_PTR(ary));
|
||||
ARY_SET_LEN(result, RARRAY_LEN(ary));
|
||||
|
@ -1693,6 +1693,10 @@ class TestArray < Test::Unit::TestCase
|
||||
assert_equal([100], a.slice(-1, 1_000_000_000))
|
||||
end
|
||||
|
||||
def test_slice_gc_compact_stress
|
||||
EnvUtil.under_gc_compact_stress { assert_equal([1, 2, 3, 4, 5], (0..10).to_a[1, 5]) }
|
||||
end
|
||||
|
||||
def test_slice!
|
||||
a = @cls[1, 2, 3, 4, 5]
|
||||
assert_equal(3, a.slice!(2))
|
||||
|
@ -245,6 +245,15 @@ module EnvUtil
|
||||
end
|
||||
module_function :under_gc_stress
|
||||
|
||||
def under_gc_compact_stress(&block)
|
||||
auto_compact = GC.auto_compact
|
||||
GC.auto_compact = true
|
||||
under_gc_stress(&block)
|
||||
ensure
|
||||
GC.auto_compact = auto_compact
|
||||
end
|
||||
module_function :under_gc_compact_stress
|
||||
|
||||
def with_default_external(enc)
|
||||
suppress_warning { Encoding.default_external = enc }
|
||||
yield
|
||||
|
Loading…
x
Reference in New Issue
Block a user