diff options
author | Aaron Patterson <tenderlove@ruby-lang.org> | 2019-11-06 15:12:28 -0800 |
---|---|---|
committer | Aaron Patterson <tenderlove@ruby-lang.org> | 2019-11-06 15:12:28 -0800 |
commit | e58814d150b0652f5e11958b36b85d977fdd0426 (patch) | |
tree | 1733515f939591caf954d8a80e3010cdd0981491 /test | |
parent | bd2b314a05ae9192b3143e1e678a37c370d8a9ce (diff) |
Revert "Use a monotonically increasing number for object_id"
This reverts commit bd2b314a05ae9192b3143e1e678a37c370d8a9ce.
Diffstat (limited to 'test')
-rw-r--r-- | test/ruby/test_gc.rb | 8 | ||||
-rw-r--r-- | test/ruby/test_gc_compact.rb | 90 |
2 files changed, 90 insertions, 8 deletions
diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index f42e098863..1511ea3011 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -461,12 +461,4 @@ class TestGc < Test::Unit::TestCase skip "finalizers did not get run" if @result.empty? assert_equal([:c1, :c2], @result) end - - def test_object_ids_never_repeat - GC.start - a = 1000.times.map { Object.new.object_id } - GC.start - b = 1000.times.map { Object.new.object_id } - assert_empty(a & b) - end end diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index bc26897386..eaffccda08 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -7,6 +7,13 @@ class TestGCCompact < Test::Unit::TestCase (Fiddle.dlwrap(obj) >> 1) end + def assert_object_ids(list) + same_count = list.find_all { |obj| + memory_location(obj) == obj.object_id + }.count + list.count - same_count + end + def big_list(level = 10) if level > 0 big_list(level - 1) @@ -34,6 +41,89 @@ class TestGCCompact < Test::Unit::TestCase new_object end + def try_to_move_objects + 10.times do + list_of_objects = big_list + + ids = list_of_objects.map(&:object_id) # store id in map + addresses = list_of_objects.map(&self.:memory_location) + + assert_equal ids, addresses + + # All object ids should be equal + assert_equal 0, assert_object_ids(list_of_objects) # should be 0 + + GC.verify_compaction_references(toward: :empty) + + # Some should have moved + id_count = assert_object_ids(list_of_objects) + skip "couldn't get objects to move" if id_count == 0 + assert_operator id_count, :>, 0 + + new_ids = list_of_objects.map(&:object_id) + + # Object ids should not change after compaction + assert_equal ids, new_ids + + new_tenant = find_object_in_recycled_slot(addresses) + return [list_of_objects, addresses, new_tenant] if new_tenant + end + + flunk "Couldn't get objects to move" + end + + def test_find_collided_object + skip "figure out how to guarantee move" + + list_of_objects, addresses, new_tenant = try_to_move_objects + + # This is the object that used to be in new_object's position + loc = memory_location(new_tenant) + assert loc, "should have a memory location" + + if (ENV['TRAVIS'] && RUBY_PLATFORM =~ /darwin/) + skip "tests are failing on Travis osx / Wercker from here" + end + + address_idx = addresses.index(loc) + assert address_idx, "should have an address index" + + previous_tenant = list_of_objects[address_idx] + assert previous_tenant, "should have a previous tenant" + + assert_not_equal previous_tenant.object_id, new_tenant.object_id + + # Should be able to look up object by object_id + assert_equal new_tenant, ObjectSpace._id2ref(new_tenant.object_id) + + # Should be able to look up object by object_id + assert_equal previous_tenant, ObjectSpace._id2ref(previous_tenant.object_id) + + int = (new_tenant.object_id >> 1) + # These two should be the same! but they are not :( + assert_equal int, ObjectSpace._id2ref(int.object_id) + end + + def test_many_collisions + list_of_objects = big_list + ids = list_of_objects.map(&:object_id) + addresses = list_of_objects.map(&self.:memory_location) + + GC.verify_compaction_references(toward: :empty) + + skip "time consuming" + + new_tenants = 10.times.map { + find_object_in_recycled_slot(addresses) + } + + collisions = GC.stat(:object_id_collisions) + skip "couldn't get objects to collide" if collisions == 0 + assert_operator collisions, :>, 0 + ids.clear + new_tenants.clear + end + def test_complex_hash_keys list_of_objects = big_list hash = list_of_objects.hash |