Author: Gregor Wegberg <[email protected]>
Branch: gc-incminimark-pinning
Changeset: r71813:f5617eea321d
Date: 2014-05-12 12:12 +0200
http://bitbucket.org/pypy/pypy/changeset/f5617eea321d/

Log:    started with object pinning implementation inside incminimark.

        Implemented the pin()/unpin() methods. This work is based on the
        `gc-minimark-pinning` branch.

diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -83,6 +83,7 @@
 #    minimarkpage.py (if they are small), or raw-malloced (if they are not
 #    small).  Collected by regular mark-n-sweep during major collections.
 #
+# XXX update doc string to contain object pinning (groggi)
 
 WORD = LONG_BIT // 8
 NULL = llmemory.NULL
@@ -136,7 +137,13 @@
 # a minor collection.
 GCFLAG_VISITED_RMY   = first_gcflag << 8
 
-_GCFLAG_FIRST_UNUSED = first_gcflag << 9    # the first unused bit
+# The following flag is set on nursery objects of which we expect not to
+# move.  This means that a young object with this flag is not moved out
+# of the nursery during a minor collection. See pin()/unpin() for further
+# details.
+GCFLAG_PINNED        = first_gcflag << 9
+
+_GCFLAG_FIRST_UNUSED = first_gcflag << 10    # the first unused bit
 
 
 # States for the incremental GC
@@ -361,6 +368,15 @@
         # minor collection.
         self.nursery_objects_shadows = self.AddressDict()
         #
+        # A sorted deque containing all pinned objects *before* the last
+        # minor collection. This deque must be consulted when considering
+        # next nursery ceiling.
+        self.nursery_barriers = self.AddressDeque()
+        #
+        # Counter tracking how many pinned objects currently reside inside
+        # the nursery.
+        self.pinned_objects_in_nursery = 0
+        #
         # Allocate a nursery.  In case of auto_nursery_size, start by
         # allocating a very small nursery, enough to do things like look
         # up the env var, which requires the GC; and then really
@@ -896,12 +912,42 @@
 
     def pin(self, obj):
         debug_start("groggi-incminimark-pin")
+        # Tries to pin the given 'obj'.  On success this method returns True,
+        # otherwise False. There are multiple reasons why a call returns False
+        # and it should be always expected that pinning is likely to fail
+        # (return False).
+
+        # XXX what happens if nursery is full of pinned objects? (groggi)
+        # XXX what happens if pinned object references movable data? (groggi)
+
+        if not self.is_in_nursery(obj):
+            # Old objects are already non-moving, therefore pinning
+            # makes no sense. If you run into this case, you may forgot
+            # to check if can_move(obj) already returns True in which
+            # case a call to pin() is unnecessary.
+            return False
+        if self.header(obj).tid & GCFLAG_PINNED:
+            # Already pinned, we do not allow to pin it again.
+            # Reason: It would be possible that the first caller unpins
+            # while the second caller thinks it's still pinned.
+            return False
+
+        self.header(obj).tid |= GCFLAG_PINNED
+        self.pinned_objects_in_nursery += 1
+        debug_print("pinned_objects_in_nursery: ", 
self.pinned_objects_in_nursery)
         debug_stop("groggi-incminimark-pin")
-        return False
+        return True
 
 
     def unpin(self, obj):
+        # Unpins a previously pinned 'obj'.  This should only be called
+        # after a pin(obj).
         debug_start("groggi-incminimark-unpin")
+        ll_assert(self.header(obj) & GCFLAG_PINNED != 0,
+            "unpin: object is already not pinned")
+        self.header(obj).tid &= ~GCFLAG_PINNED
+        self.pinned_objects_in_nursery -= 1
+        debug_print("pinned_objects_in_nursery: ", 
self.pinned_objects_in_nursery)
         debug_stop("groggi-incminimark-unpin")
 
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to