[pypy-commit] stmgc default: Fix

arigo noreply at buildbot.pypy.org
Sun Jun 16 17:29:03 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r152:9507e1b05a3c
Date: 2013-06-16 17:17 +0200
http://bitbucket.org/pypy/stmgc/changeset/9507e1b05a3c/

Log:	Fix

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -286,6 +286,10 @@
 static void _check_flags(gcptr P)
 {
   struct tx_descriptor *d = thread_descriptor;
+  if (P->h_tid & GCFLAG_STUB)
+    {
+      fprintf(stderr, "S");
+    }
   int is_old = (P->h_tid & GCFLAG_OLD) != 0;
   int in_nurs = (d->nursery_base <= (char*)P && ((char*)P) < d->nursery_end);
   if (in_nurs)
@@ -344,9 +348,9 @@
             }
 
           P = (gcptr)v;
-          _check_flags(P);
           assert(P->h_tid & GCFLAG_PUBLIC);
           fprintf(stderr, "-> %p public ", P);
+          _check_flags(P);
         }
 
       gcptr L = _find_public_to_private(P);
@@ -370,8 +374,8 @@
   if (STUB_THREAD(P) == d->public_descriptor)
     {
       P = (gcptr)(v - 2);
+      fprintf(stderr, "-> %p ", P);
       _check_flags(P);
-      fprintf(stderr, "-> %p ", P);
     }
   else
     {
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -112,7 +112,24 @@
         /* it's a nursery object.  Was it already moved? */
 
         if (UNLIKELY(obj->h_tid & GCFLAG_NURSERY_MOVED)) {
-            /* yes: just fix the ref. */
+
+            /* yes, but was it actually a public object in the nursery?
+               (such objects are always NURSERY_MOVED) */
+            if (obj->h_tid & GCFLAG_PUBLIC) {
+
+                /* follow the chain of revisions.  Necessary, otherwise
+                   we could end up with 'obj' being an incomplete stub. */
+                while (1) {
+                    revision_t v = ACCESS_ONCE(obj->h_revision);
+                    if (!IS_POINTER(v))
+                        break;
+                    obj = (gcptr)v;
+                }
+                *root = obj;
+                return;
+            }
+
+            /* common case: multiple refs, just fix the ref. */
             *root = (gcptr)obj->h_revision;
             return;
         }
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
@@ -506,5 +506,5 @@
 
 def test_more_multi_thread():
     #py.test.skip("more random tests")
-    for i in range(100):
+    for i in range(45, 100):
         yield test_multi_thread, 1200 + i


More information about the pypy-commit mailing list