[pypy-commit] pypy gc-incminimark-pinning: additional tests: old obj points to old obj pointing to pinned one.
groggi
noreply at buildbot.pypy.org
Sun Jul 27 11:40:26 CEST 2014
Author: Gregor Wegberg <code at gregorwegberg.com>
Branch: gc-incminimark-pinning
Changeset: r72552:203c544e7906
Date: 2014-07-27 11:38 +0200
http://bitbucket.org/pypy/pypy/changeset/203c544e7906/
Log: additional tests: old obj points to old obj pointing to pinned one.
In addition added some 'assert False' to be sure exceptions are
thrown.
diff --git a/rpython/memory/gc/test/test_object_pinning.py b/rpython/memory/gc/test/test_object_pinning.py
--- a/rpython/memory/gc/test/test_object_pinning.py
+++ b/rpython/memory/gc/test/test_object_pinning.py
@@ -83,7 +83,11 @@
# unpin and check if object is gone from nursery
self.gc.unpin(adr)
collect_func()
- py.test.raises(RuntimeError, 'ptr.someInt')
+ try:
+ assert ptr.someInt == 100
+ assert False
+ except RuntimeError as ex:
+ assert "freed" in str(ex)
# check if we object is still accessible
ptr_old = self.stackroots[0]
@@ -116,6 +120,7 @@
# be gone
try:
next_ptr.someInt = 101
+ assert False
except RuntimeError as ex:
assert "freed" in str(ex)
@@ -157,6 +162,7 @@
try:
# should fail as this was the pinned object that is now collected
next_ptr.someInt = 0
+ assert False
except RuntimeError as ex:
assert "freed" in str(ex)
@@ -220,6 +226,117 @@
def test_young_and_stackroots_point_to_pinned(self):
self.not_pinned_and_stackroots_point_to_pinned(make_old=False)
+ def test_old_points_to_old_points_to_pinned_1(self):
+ #
+ # Scenario:
+ # stackroots points to 'root_ptr'. 'root_ptr' points to 'next_ptr'.
+ # 'next_ptr' points to the young and pinned 'pinned_ptr'. Here we
+ # remove the reference to 'next_ptr' from 'root_ptr' and check if it
+ # behaves as expected.
+ #
+ root_ptr = self.malloc(S)
+ root_ptr.someInt = 100
+ self.stackroots.append(root_ptr)
+ self.gc.collect()
+ root_ptr = self.stackroots[0]
+ #
+ next_ptr = self.malloc(S)
+ next_ptr.someInt = 200
+ self.write(root_ptr, 'next', next_ptr)
+ self.gc.collect()
+ next_ptr = root_ptr.next
+ #
+ # check if everything is as expected
+ assert not self.gc.is_in_nursery(llmemory.cast_ptr_to_adr(root_ptr))
+ assert not self.gc.is_in_nursery(llmemory.cast_ptr_to_adr(next_ptr))
+ assert root_ptr.someInt == 100
+ assert next_ptr.someInt == 200
+ #
+ pinned_ptr = self.malloc(S)
+ pinned_ptr.someInt = 300
+ assert self.gc.pin(llmemory.cast_ptr_to_adr(pinned_ptr))
+ self.write(next_ptr, 'next', pinned_ptr)
+ self.gc.collect()
+ #
+ # validate everything is as expected with 3 rounds of GC collecting
+ for _ in range(3):
+ self.gc.collect()
+ assert next_ptr.next == pinned_ptr
+ assert self.gc.is_in_nursery(llmemory.cast_ptr_to_adr(pinned_ptr))
+ assert pinned_ptr.someInt == 300
+ assert root_ptr.someInt == 100
+ assert next_ptr.someInt == 200
+ #
+ # remove the reference to the pinned object
+ self.write(next_ptr, 'next', root_ptr)
+ self.gc.minor_collection()
+ # the minor collection visits all old objects pointing to pinned ones.
+ # therefore the pinned object should be gone
+ try:
+ pinned_ptr.someInt == 300
+ assert False
+ except RuntimeError as ex:
+ assert "freed" in str(ex)
+
+ def test_old_points_to_old_points_to_pinned_2(self):
+ #
+ # Scenario:
+ # stackroots points to 'root_ptr'. 'root_ptr' points to 'next_ptr'.
+ # 'next_ptr' points to the young and pinned 'pinned_ptr'. Here we
+ # remove 'root_ptr' from the stackroots and check if it behaves as
+ # expected.
+ #
+ root_ptr = self.malloc(S)
+ root_ptr.someInt = 100
+ self.stackroots.append(root_ptr)
+ self.gc.collect()
+ root_ptr = self.stackroots[0]
+ #
+ next_ptr = self.malloc(S)
+ next_ptr.someInt = 200
+ self.write(root_ptr, 'next', next_ptr)
+ self.gc.collect()
+ next_ptr = root_ptr.next
+ #
+ # check if everything is as expected
+ assert not self.gc.is_in_nursery(llmemory.cast_ptr_to_adr(root_ptr))
+ assert not self.gc.is_in_nursery(llmemory.cast_ptr_to_adr(next_ptr))
+ assert root_ptr.someInt == 100
+ assert next_ptr.someInt == 200
+ #
+ pinned_ptr = self.malloc(S)
+ pinned_ptr.someInt = 300
+ assert self.gc.pin(llmemory.cast_ptr_to_adr(pinned_ptr))
+ self.write(next_ptr, 'next', pinned_ptr)
+ self.gc.collect()
+ #
+ # validate everything is as expected with 3 rounds of GC collecting
+ for _ in range(3):
+ self.gc.collect()
+ assert next_ptr.next == pinned_ptr
+ assert self.gc.is_in_nursery(llmemory.cast_ptr_to_adr(pinned_ptr))
+ assert pinned_ptr.someInt == 300
+ assert root_ptr.someInt == 100
+ assert next_ptr.someInt == 200
+ #
+ # remove the root from stackroots
+ self.stackroots.remove(root_ptr)
+ self.gc.minor_collection()
+ #
+ # the minor collection will still visit 'next_ptr', although
+ # 'root_ptr' is not part of the stackroots anymore. This makes
+ # sense as 'next_ptr' is removed only in the next major collection
+ assert next_ptr.next.someInt == 300
+ #
+ # now we do a major collection and everything should be gone
+ self.gc.collect()
+ try:
+ pinned_ptr.someInt == 300
+ assert False
+ except RuntimeError as ex:
+ assert "freed" in str(ex)
+
+
def test_pin_old(self):
ptr = self.malloc(S)
ptr.someInt = 100
@@ -535,7 +652,11 @@
assert self.gc.pinned_objects_in_nursery == 2
assert ptr_stackroot_1.someInt == 100
assert ptr_stackroot_2.someInt == 100
- py.test.raises(RuntimeError, 'ptr_not_stackroot.someInt') # should be freed
+ try:
+ ptr_not_stackroot.someInt = 100
+ assert False
+ except RuntimeError as ex:
+ assert "freed" in str(ex)
def fill_nursery_with_pinned_objects(self):
typeid = self.get_type_id(S)
More information about the pypy-commit
mailing list