[pypy-commit] pypy gc-minimark-pinning: More comments, and one critical fix (see e.g. test_print_leak).

arigo noreply at buildbot.pypy.org
Sat May 12 18:45:33 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: gc-minimark-pinning
Changeset: r55060:dc1599b68fe4
Date: 2012-05-12 18:44 +0200
http://bitbucket.org/pypy/pypy/changeset/dc1599b68fe4/

Log:	More comments, and one critical fix (see e.g. test_print_leak).

diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -820,9 +820,10 @@
         return True
 
     def unpin(self, obj):
-        if self.header(obj).tid & GCFLAG_PINNED:
-            self.pinned_objects_in_nursery -= 1
-            self.header(obj).tid &= ~GCFLAG_PINNED
+        ll_assert(self.header(obj).tid & GCFLAG_PINNED != 0,
+                  "unpin: object is already not pinned")
+        self.pinned_objects_in_nursery -= 1
+        self.header(obj).tid &= ~GCFLAG_PINNED
 
     def shrink_array(self, obj, smallerlength):
         #
@@ -965,6 +966,14 @@
             # similarily, all objects should have this flag:
             ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS != 0,
                       "missing GCFLAG_TRACK_YOUNG_PTRS")
+        else:
+            # exception: pinned objects are in the nursery and nursery
+            # objects never have GCFLAG_TRACK_YOUNG_PTRS
+            ll_assert(self.is_in_nursery(obj),
+                                  "pinned object not in nursery")
+            ll_assert(self.header(obj).tid & GCFLAG_TRACK_YOUNG_PTRS == 0,
+                      "pinned nursery object with GCFLAG_TRACK_YOUNG_PTRS")
+        #
         # the GCFLAG_VISITED should not be set between collections
         ll_assert(self.header(obj).tid & GCFLAG_VISITED == 0,
                   "unexpected GCFLAG_VISITED")
@@ -1535,6 +1544,9 @@
             if hdr.tid & GCFLAG_VISITED:
                 return
             hdr.tid |= GCFLAG_VISITED
+            # XXX note that this assumes that the pinned object has no more
+            # references, because it will not be traced!  It's ok as long
+            # as we only pin strings and similar objects.
             ll_assert(not self.header(obj).tid & GCFLAG_HAS_CARDS, "support cards with pinning")
             self.pinned_objects_in_nursery += 1
             self.surviving_pinned_objects.append(
@@ -1676,6 +1688,7 @@
         # Debugging checks
         ll_assert(self.nursery_free == self.nursery,
                   "nursery not empty in major_collection()")
+        # ^^^ but note that there may still be pinned objects
         self.debug_check_consistency()
         #
         # Note that a major collection is non-moving.  The goal is only to
@@ -1859,8 +1872,13 @@
         # flag set, then the object should be in 'prebuilt_root_objects',
         # and the GCFLAG_VISITED will be reset at the end of the
         # collection.
+        #
+        # Finally, pinned objects in the nursery are ignored (and not
+        # traced; this is the same as during minor collection).  We don't
+        # set GCFLAG_VISITED on them because nobody would clear it.
+        #
         hdr = self.header(obj)
-        if hdr.tid & (GCFLAG_VISITED | GCFLAG_NO_HEAP_PTRS):
+        if hdr.tid & (GCFLAG_VISITED | GCFLAG_NO_HEAP_PTRS | GCFLAG_PINNED):
             return
         #
         # It's the first time.  We set the flag.


More information about the pypy-commit mailing list