[pypy-commit] stmgc default: Pass this test

arigo noreply at buildbot.pypy.org
Fri Jun 21 11:24:25 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r214:ae4b3bacf4c0
Date: 2013-06-21 11:24 +0200
http://bitbucket.org/pypy/stmgc/changeset/ae4b3bacf4c0/

Log:	Pass this test

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -484,6 +484,8 @@
                 GCFLAG_WRITE_BARRIER     |
                 0);
   L->h_revision = stm_private_rev_num;
+  assert(stm_private_rev_num < 0);
+  assert(stm_private_rev_num & 1);
   g2l_insert(&d->public_to_private, R, L);
   fprintf(stderr, "write_barrier: adding %p -> %p to public_to_private\n",
           R, L);
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -195,8 +195,11 @@
         return;
 
  restart:
-    if (obj->h_tid & GCFLAG_VISITED)
+    if (obj->h_tid & GCFLAG_VISITED) {
+        fprintf(stderr, "[already visited: %p]\n", obj);
+        assert(obj == *pobj);
         return;    /* already seen */
+    }
 
     if (obj->h_revision & 1) {
         assert(!(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
@@ -246,8 +249,11 @@
             B->h_tid |= GCFLAG_VISITED;
         }
         else {
+            /* a private_from_protected with a stolen backup copy B */
             assert(!(B->h_tid & GCFLAG_BACKUP_COPY));
-            abort();  // XXX
+            gcptr obj1 = B;
+            visit(&obj1);     /* xxx recursion? */
+            obj->h_revision = (revision_t)obj1;
         }
     }
     obj->h_tid |= GCFLAG_VISITED;
@@ -287,8 +293,12 @@
 {
     //assert(*root == END_MARKER);
     //root++;
-    while (root != end)
-        visit(root++);
+    while (root != end) {
+        gcptr o = *root;
+        visit(root);
+        fprintf(stderr, "visit stack root: %p -> %p\n", o, *root);
+        root++;
+    }
 }
 
 static void mark_all_stack_roots(void)
@@ -354,8 +364,13 @@
            case that obj->h_revision doesn't have GCFLAG_VISITED, but
            just removing it is very wrong --- we want 'd' to abort.
         */
+        if (obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
+            assert(IS_POINTER(obj->h_revision));
+            obj = (gcptr)obj->h_revision;
+        }
+
         revision_t v = obj->h_revision;
-        if (IS_POINTER(v) && !(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)) {
+        if (IS_POINTER(v)) {
             /* has a more recent revision.  Oups. */
             fprintf(stderr,
                     "ABRT_COLLECT_MAJOR: %p was read but modified already\n",
@@ -539,7 +554,8 @@
            collection was not preceeded by a minor collection if the
            thread is busy in a system call for example.
         */
-        if (stmgc_minor_collect_anything_to_do(d)) {
+        if (stmgc_minor_collect_anything_to_do(d) ||
+            (d->public_descriptor->stolen_objects.size != 0)) {
             /* Hack: temporarily pretend that we "are" the other thread...
              */
             thread_descriptor = d;
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -235,12 +235,13 @@
         if (L == NULL)
             continue;
         assert(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
+        assert(IS_POINTER(L->h_revision));
 
         g2l_insert(&d->public_to_private, B, L);
 
         /* this is definitely needed: all keys in public_to_private
            must appear in list_of_read_objects */
-        fprintf(stderr, "n.readobj: %p\n", B);
+        fprintf(stderr, "n.readobj: %p -> %p\n", B, L);
         assert(!(B->h_tid & GCFLAG_STUB));
         gcptrlist_insert(&d->list_of_read_objects, B);
 
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -487,7 +487,9 @@
     return p.h_tid & GCFLAG_STUB
 
 def check_not_free(p):
+    print >> sys.stderr, "[checking %r..." % p,
     assert 42 < (p.h_tid & 0xFFFF) < 521
+    print >> sys.stderr, "ok]"
 
 def check_nursery_free(p):
     #assert p.h_tid == p.h_revision == 0
diff --git a/c4/test/test_gcpage.py b/c4/test/test_gcpage.py
--- a/c4/test/test_gcpage.py
+++ b/c4/test/test_gcpage.py
@@ -315,10 +315,12 @@
     assert follow_revision(p1).h_tid & GCFLAG_BACKUP_COPY
 
 def test_backup_stolen():
-    py.test.skip("in-progress")
     p = palloc(HDR)
     def f1(r):
         p1 = lib.stm_write_barrier(p)   # private copy
+        lib.stm_push_root(p1)
+        minor_collect()
+        p1 = lib.stm_pop_root()
         lib.stm_commit_transaction()
         lib.stm_begin_inevitable_transaction()
         assert classify(p) == "public"
@@ -329,9 +331,13 @@
             assert c == 0
             p1b = lib.stm_write_barrier(p1)
             assert p1b == p1
+            assert not lib.in_nursery(p1)
             assert classify(p1) == "private_from_protected"
             assert classify(follow_revision(p1)) == "backup"
+            lib.stm_push_root(p1)
             r.wait_while_in_parallel()
+            p1b = lib.stm_pop_root()
+            assert p1b == p1
             check_not_free(p1)
             assert classify(p1) == "private_from_protected"
             assert classify(follow_revision(p1)) == "public"  # has been stolen


More information about the pypy-commit mailing list