* array.c (rb_ary_modify): remember shared array owner if a shared

array owner is promoted and a shared array is not promoted.
  Now, shared array is WB-unprotected so that shared arrays are not
  promoted.  All objects referred from shared array should be marked
  correctly.
  [ruby-core:61919] [ruby-trunk - Bug #9718]
* test/ruby/test_array.rb: add a test for above.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45553 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2014-04-10 10:16:24 +00:00
Родитель be51200785
Коммит f19bf5ba5a
3 изменённых файлов: 42 добавлений и 1 удалений

Просмотреть файл

@ -1,3 +1,16 @@
Thu Apr 10 19:11:11 2014 Koichi Sasada <ko1@atdot.net>
* array.c (rb_ary_modify): remember shared array owner if a shared
array owner is promoted and a shared array is not promoted.
Now, shared array is WB-unprotected so that shared arrays are not
promoted. All objects referred from shared array should be marked
correctly.
[ruby-core:61919] [ruby-trunk - Bug #9718]
* test/ruby/test_array.rb: add a test for above.
Thu Apr 10 18:57:12 2014 Koichi Sasada <ko1@atdot.net>
* gc.c (gc_verify_internal_consistency): move lines and enable

Просмотреть файл

@ -343,6 +343,11 @@ rb_ary_modify(VALUE ary)
ARY_SET_CAPA(ary, len);
ARY_SET_PTR(ary, ptr);
}
/* TODO: age2 promotion, OBJ_PROMOTED() checks not infant. */
if (OBJ_PROMOTED(ary) && !OBJ_PROMOTED(shared)) {
rb_gc_writebarrier_remember_promoted(ary);
}
}
}

Просмотреть файл

@ -2389,7 +2389,7 @@ class TestArray < Test::Unit::TestCase
assert_equal([], a.rotate!(13))
assert_equal([], a.rotate!(-13))
a = [].freeze
assert_raise_with_message(RuntimeError, /can't modify frozen/) {a.rotate!}
assert_raise_with_message(RuntimeError, /can\'t modify frozen/) {a.rotate!}
a = [1,2,3]
assert_raise(ArgumentError) { a.rotate!(1, 1) }
end
@ -2428,4 +2428,27 @@ class TestArray < Test::Unit::TestCase
assert_include([4, 7], a.bsearch {|x| (2**100).coerce((1 - x / 4) * (2**100)).first })
end
def test_shared_marking
assert_normal_exit <<-EOS, '[Bug #9718]'
begin
require 'timeout'
timeout(5) do
queue = []
i = 0
srand(0)
loop do
if (i+=1) > rand(100_000)
GC.verify_internal_consistency
queue.shift.call
i = 0
end
queue << lambda{}
end
end
rescue TimeoutError
assert(true)
end
EOS
end
end