diff options
Diffstat (limited to 'test/ruby/test_objectspace.rb')
| -rw-r--r-- | test/ruby/test_objectspace.rb | 111 |
1 files changed, 80 insertions, 31 deletions
diff --git a/test/ruby/test_objectspace.rb b/test/ruby/test_objectspace.rb index a7cfb064a8..a479547599 100644 --- a/test/ruby/test_objectspace.rb +++ b/test/ruby/test_objectspace.rb @@ -8,7 +8,7 @@ class TestObjectSpace < Test::Unit::TestCase line = $1.to_i code = <<"End" define_method("test_id2ref_#{line}") {\ - o = ObjectSpace._id2ref(obj.object_id);\ + o = EnvUtil.suppress_warning { ObjectSpace._id2ref(obj.object_id) } assert_same(obj, o, "didn't round trip: \#{obj.inspect}");\ } End @@ -57,17 +57,20 @@ End def test_id2ref_invalid_argument msg = /no implicit conversion/ - assert_raise_with_message(TypeError, msg) {ObjectSpace._id2ref(nil)} - assert_raise_with_message(TypeError, msg) {ObjectSpace._id2ref(false)} - assert_raise_with_message(TypeError, msg) {ObjectSpace._id2ref(true)} - assert_raise_with_message(TypeError, msg) {ObjectSpace._id2ref(:a)} - assert_raise_with_message(TypeError, msg) {ObjectSpace._id2ref("0")} - assert_raise_with_message(TypeError, msg) {ObjectSpace._id2ref(Object.new)} + assert_raise_with_message(TypeError, msg) { EnvUtil.suppress_warning { ObjectSpace._id2ref(nil) } } + assert_raise_with_message(TypeError, msg) { EnvUtil.suppress_warning { ObjectSpace._id2ref(false) } } + assert_raise_with_message(TypeError, msg) { EnvUtil.suppress_warning { ObjectSpace._id2ref(true) } } + assert_raise_with_message(TypeError, msg) { EnvUtil.suppress_warning { ObjectSpace._id2ref(:a) } } + assert_raise_with_message(TypeError, msg) { EnvUtil.suppress_warning { ObjectSpace._id2ref("0") } } + assert_raise_with_message(TypeError, msg) { EnvUtil.suppress_warning { ObjectSpace._id2ref(Object.new) } } end def test_id2ref_invalid_symbol_id - msg = /is not symbol id value/ - assert_raise_with_message(RangeError, msg) { ObjectSpace._id2ref(:a.object_id + GC::INTERNAL_CONSTANTS[:RVALUE_SIZE]) } + # RB_STATIC_SYM_P checks for static symbols by checking that the bottom + # 8 bits of the object is equal to RUBY_SYMBOL_FLAG, so we need to make + # sure that the bottom 8 bits remain unchanged. + msg = /is not a symbol id value/ + assert_raise_with_message(RangeError, msg) { EnvUtil.suppress_warning { ObjectSpace._id2ref(:a.object_id + 256) } } end def test_count_objects @@ -91,13 +94,27 @@ End end def test_finalizer - assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok :ok), []) + assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok), []) a = [] ObjectSpace.define_finalizer(a) { p :ok } b = a.dup ObjectSpace.define_finalizer(a) { p :ok } !b END + + assert_in_out_err(["-e", <<~RUBY], "", %w(:ok :ok), [], timeout: 60) + a = Object.new + ObjectSpace.define_finalizer(a) { p :ok } + + 1_000_000.times do + o = Object.new + ObjectSpace.define_finalizer(o) { } + end + + b = Object.new + ObjectSpace.define_finalizer(b) { p :ok } + RUBY + assert_raise(ArgumentError) { ObjectSpace.define_finalizer([], Object.new) } code = proc do |priv| @@ -120,6 +137,25 @@ End } end + def test_finalizer_copy + assert_in_out_err(["-e", <<~'RUBY'], "", %w(:ok), []) + def fin + ids = Set.new + ->(id) { puts "object_id (#{id}) reused" unless ids.add?(id) } + end + + OBJ = Object.new + ObjectSpace.define_finalizer(OBJ, fin) + OBJ.freeze + + 10.times do + OBJ.clone + end + + p :ok + RUBY + end + def test_finalizer_with_super assert_in_out_err(["-e", <<-END], "", %w(:ok), []) class A @@ -174,30 +210,28 @@ End end def test_finalizer_thread_raise - GC.disable - fzer = proc do |id| - sleep 0.2 - end - 2.times do - o = Object.new - ObjectSpace.define_finalizer(o, fzer) - end + EnvUtil.without_gc do + fzer = proc do |id| + sleep 0.2 + end + 2.times do + o = Object.new + ObjectSpace.define_finalizer(o, fzer) + end - my_error = Class.new(RuntimeError) - begin - main_th = Thread.current - Thread.new do - sleep 0.1 - main_th.raise(my_error) + my_error = Class.new(RuntimeError) + begin + main_th = Thread.current + Thread.new do + sleep 0.1 + main_th.raise(my_error) + end + GC.start + sleep(10) + assert(false) + rescue my_error end - GC.start - puts "After GC" - sleep(10) - assert(false) - rescue my_error end - ensure - GC.enable end def test_each_object @@ -250,6 +284,21 @@ End end; end + def test_id2ref_table_build + assert_separately([], <<-End) + 10.times do + Object.new.object_id + end + + GC.start(immediate_mark: false) + + obj = Object.new + EnvUtil.suppress_warning do + assert_equal obj, ObjectSpace._id2ref(obj.object_id) + end + End + end + def test_each_object_singleton_class assert_separately([], <<-End) class C |
