Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r86015:1d29fd069ef0
Date: 2016-08-04 17:40 +0200
http://bitbucket.org/pypy/pypy/changeset/1d29fd069ef0/

Log:    Issue #2363: extracted a unit test that fails

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
@@ -1,6 +1,7 @@
 import py
 from rpython.rtyper.lltypesystem import lltype, llmemory, llarena
 from rpython.memory.gc.incminimark import IncrementalMiniMarkGC, WORD
+from rpython.memory.gc.incminimark import GCFLAG_VISITED
 from test_direct import BaseDirectGCTest
 
 T = lltype.GcForwardReference()
@@ -981,3 +982,56 @@
         self.gc.major_collection_step()   # should not crash reading 'ptr1'!
 
         del self.gc.TEST_VISIT_SINGLE_STEP
+
+
+    def test_pin_bug2(self):
+        #
+        # * we have an old object A that points to a pinned object B
+        #
+        # * we unpin B
+        #
+        # * the next minor_collection() is done in STATE_MARKING==1
+        #   when the object A is already black
+        #
+        # * _minor_collection() => _visit_old_objects_pointing_to_pinned()
+        #   which will move the now-unpinned B out of the nursery, to B'
+        #
+        # At that point we need to take care of colors, otherwise we
+        # get a black object (A) pointing to a white object (B'),
+        # which must never occur.
+        #
+        ptrA = self.malloc(T)
+        ptrA.someInt = 42
+        adrA = llmemory.cast_ptr_to_adr(ptrA)
+        res = self.gc.pin(adrA)
+        assert res
+
+        ptrC = self.malloc(S)
+        self.stackroots.append(ptrC)
+
+        ptrB = self.malloc(S)
+        ptrB.data = ptrA
+        self.stackroots.append(ptrB)
+
+        self.gc.collect()
+        ptrB = self.stackroots[-1]    # now old and outside the nursery
+        ptrC = self.stackroots[-2]    # another random old object, traced later
+        adrB = llmemory.cast_ptr_to_adr(ptrB)
+
+        self.gc.minor_collection()
+        assert self.gc.gc_state == self.STATE_SCANNING
+        self.gc.major_collection_step()
+        assert self.gc.gc_state == self.STATE_MARKING
+        assert not (self.gc.header(adrB).tid & GCFLAG_VISITED)  # not black yet
+
+        self.gc.TEST_VISIT_SINGLE_STEP = True
+        self.gc.major_collection_step()
+        assert self.gc.gc_state == self.STATE_MARKING
+        assert self.gc.header(adrB).tid & GCFLAG_VISITED    # now black
+        # but ptrC is not traced yet, which is why we're still in STATE_MARKING
+        assert self.gc.old_objects_pointing_to_pinned.tolist() == [adrB]
+
+        self.gc.unpin(adrA)
+
+        self.gc.DEBUG = 2
+        self.gc.minor_collection()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to