[pypy-commit] stmgc default: merge heads

arigo noreply at buildbot.pypy.org
Tue Jun 25 16:43:40 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r278:9935b830ffc8
Date: 2013-06-25 16:43 +0200
http://bitbucket.org/pypy/stmgc/changeset/9935b830ffc8/

Log:	merge heads

diff --git a/c4/atomic_ops.h b/c4/atomic_ops.h
--- a/c4/atomic_ops.h
+++ b/c4/atomic_ops.h
@@ -2,7 +2,7 @@
 #define _SRCSTM_ATOMIC_OPS_
 
 #include <assert.h>
-
+#define IMPLIES(a, b)   (!(a) || (b))
 
 /* Ask the compiler to really reload the revision_t argument from memory.
    That's all that this macro does; it does not imply any type of barrier.
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1031,8 +1031,9 @@
       stub->h_tid = (L->h_tid & STM_USER_TID_MASK) | GCFLAG_PUBLIC
                                                    | GCFLAG_STUB
                                                    | GCFLAG_OLD;
+      stub->h_revision = ((revision_t)L) | 2;
+
       assert(!(L->h_tid & GCFLAG_HAS_ID));
-      stub->h_revision = ((revision_t)L) | 2;
       if (L->h_original) {
         stub->h_original = L->h_original;
       }
@@ -1040,8 +1041,14 @@
         stub->h_original = (revision_t)L;
       }
       else {
-        L->h_original = (revision_t)stub;
+        /* There shouldn't be a public, young object without
+           a h_original. They only come from stealing which
+           always sets h_original */
         assert(0);
+        /* L->h_original = (revision_t)stub; */
+        /* if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { */
+        /*   ((gcptr)L->h_revision)->h_original = (revision_t)stub; */
+        /* } */
       }
       
       item->val = stub;
@@ -1165,12 +1172,6 @@
         {
           /* copy the backup copy B back over the now-protected object P,
              and then free B, which will not be used any more. */
-          assert(!(P->h_original) 
-                 || (B->h_original == (revision_t)P->h_original));
-          assert(!(P->h_original && !B->h_original));
-          if (P->h_original && !B->h_original) // might occur because of
-            B->h_original = P->h_original; //replace_ptr_to_protected_with_stub
-
           size_t size = stmcb_size(B);
           assert(B->h_tid & GCFLAG_BACKUP_COPY);
           memcpy(((char *)P) + offsetof(struct stm_object_s, h_revision),
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -162,7 +162,7 @@
     else if (p->h_tid & GCFLAG_OLD) {
         /* old objects must have an h_original xOR be
            the original itself. */
-        /* dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p)); */
+        dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p));
         return (revision_t)p;
     }
     
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -53,7 +53,13 @@
         stub->h_original = (revision_t)obj;
     }
     else {
-        obj->h_original = (revision_t)stub;
+        /* There shouldn't be a public, young object without
+           a h_original. But there can be protected ones. */
+        assert(!(obj->h_tid & GCFLAG_PUBLIC));
+        obj->h_original = (revision_t)stub;        
+        if (obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
+            ((gcptr)obj->h_revision)->h_original = (revision_t)stub;
+        }
     }
 
     g2l_insert(&sd->all_stubs, obj, stub);
@@ -93,23 +99,23 @@
     if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
         gcptr B = (gcptr)L->h_revision;     /* the backup copy */
         
-        if (L->h_original) {
-            /* L has an original, may be GCFLAG_HAS_ID */
-            B->h_original = L->h_original;
-            L->h_tid &= ~GCFLAG_HAS_ID;
-        }
-        else if (L->h_tid & GCFLAG_OLD) {
-            /* If old, it must be the original */
-            assert(!(L->h_tid & GCFLAG_HAS_ID));
-            /* original must be L */
+        /* On young objects here, h_original is always set
+         and never GCFLAG_HAS_ID. This is because a stealing
+         thread can only reach a priv_from_prot object through
+         public old stubs/objects that serve as originals if
+         needed.
+         If h_original is set, then it is already set in the
+         backup, too.
+        */
+        assert(!(L->h_tid & GCFLAG_HAS_ID));
+        assert(IMPLIES(!(L->h_tid & GCFLAG_OLD), L->h_original));
+        assert(IMPLIES(L->h_tid & GCFLAG_OLD,
+                       (B->h_original == (revision_t)L) 
+                       || (B->h_original == L->h_original)));
+        if (!L->h_original && L->h_tid & GCFLAG_OLD) {
+            /* If old, L must be the original */
             B->h_original = (revision_t)L;
         }
-        else {
-            /* we can make the backup the "original"
-             since L hasn't decided yet */
-            L->h_original = (revision_t)B;
-            assert(0);
-        }
 
         /* B is now a backup copy, i.e. a protected object, and we own
            the foreign thread's collection_lock, so we can read/write the
diff --git a/c4/test/test_et.py b/c4/test/test_et.py
--- a/c4/test/test_et.py
+++ b/c4/test/test_et.py
@@ -539,6 +539,7 @@
             assert not (p1.h_tid & GCFLAG_HAS_ID)
             
         r1w = lib.stm_write_barrier(r1)
+        lib.setptr(p1, 1, r1w)
         assert classify(r1w) == "private_from_protected"
         assert not (r1w.h_tid & GCFLAG_OLD)
         if c:


More information about the pypy-commit mailing list