Author: Gregor Wegberg <c...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit