summaryrefslogtreecommitdiff
path: root/test/ruby/test_gc_compact.rb
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2019-11-06 15:12:28 -0800
committerAaron Patterson <tenderlove@ruby-lang.org>2019-11-06 15:12:28 -0800
commite58814d150b0652f5e11958b36b85d977fdd0426 (patch)
tree1733515f939591caf954d8a80e3010cdd0981491 /test/ruby/test_gc_compact.rb
parentbd2b314a05ae9192b3143e1e678a37c370d8a9ce (diff)
Revert "Use a monotonically increasing number for object_id"
This reverts commit bd2b314a05ae9192b3143e1e678a37c370d8a9ce.
Diffstat (limited to 'test/ruby/test_gc_compact.rb')
-rw-r--r--test/ruby/test_gc_compact.rb90
1 files changed, 90 insertions, 0 deletions
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