[pypy-commit] stmgc default: Next important behavior of minor collections (see test).

arigo noreply at buildbot.pypy.org
Sat Jun 15 19:03:41 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r136:ed12efb977c7
Date: 2013-06-15 19:03 +0200
http://bitbucket.org/pypy/stmgc/changeset/ed12efb977c7/

Log:	Next important behavior of minor collections (see test).

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -97,7 +97,14 @@
         /* not a nursery object */
     }
     else {
-        /* a nursery object */
+        /* it's a nursery object.  Was it already moved? */
+
+        if (UNLIKELY(obj->h_tid & GCFLAG_NURSERY_MOVED)) {
+            /* yes: just fix the ref. */
+            *root = (gcptr)obj->h_revision;
+            return;
+        }
+
         /* make a copy of it outside */
         fresh_old_copy = create_old_object_copy(obj);
         obj->h_tid |= GCFLAG_NURSERY_MOVED;
@@ -126,11 +133,12 @@
 {
     /* "public_with_young_copy" lists the public copies that may have
        a more recent (or in-progress) private or protected object that
-       is young.  Note that public copies themselves are always old.
+       is young.  Note that public copies themselves are always old
+       (short of a few exceptions that don't end up in this list).
 
-       The list should only contain public objects, but beyong that, be
-       careful and ignore any strange object: it can show up because of
-       aborted transactions (and then some different changes).
+       The list should only contain old public objects, but beyong that,
+       be careful and ignore any strange object: it can show up because
+       of aborted transactions (and then some different changes).
     */
     long i, size = d->public_with_young_copy.size;
     gcptr *items = d->public_with_young_copy.items;
@@ -138,6 +146,7 @@
     for (i = 0; i < size; i++) {
         gcptr P = items[i];
         assert(P->h_tid & GCFLAG_PUBLIC);
+        assert(P->h_tid & GCFLAG_OLD);
 
         revision_t v = ACCESS_ONCE(P->h_revision);
         wlog_t *item;
@@ -247,10 +256,6 @@
 
     mark_young_roots(d);
 
-#if 0
-    mark_private_from_protected(d);
-#endif
-
     mark_public_to_young(d);
 
     visit_all_outside_objects(d);
diff --git a/c4/test/test_nursery.py b/c4/test/test_nursery.py
--- a/c4/test/test_nursery.py
+++ b/c4/test/test_nursery.py
@@ -261,3 +261,14 @@
     assert plist == [p3]
     assert classify(p3) == "public"
     assert not lib.in_nursery(p3)
+
+def test_move_to_one_place():
+    p1 = nalloc(HDR)
+    lib.stm_push_root(p1)
+    lib.stm_push_root(p1)
+    lib.stm_push_root(p1)
+    minor_collect()
+    p2a = lib.stm_pop_root()
+    p2b = lib.stm_pop_root()
+    p2c = lib.stm_pop_root()
+    assert p2a == p2b == p2c
diff --git a/c4/test/test_random.py b/c4/test/test_random.py
--- a/c4/test/test_random.py
+++ b/c4/test/test_random.py
@@ -207,7 +207,7 @@
         return lib._stm_nonrecord_barrier(ptr)
 
     def is_private(self, ptr):
-        return classify(ptr) == "private"
+        return classify(ptr) in ("private", "private_from_protected")
 
     def check_valid(self, lst):
         lst = list(lst)


More information about the pypy-commit mailing list