[pypy-commit] stmgc implement-id: amazingly seems to not crash..

Raemi noreply at buildbot.pypy.org
Fri Jun 21 13:46:56 CEST 2013


Author: Remi Meier <meierrem at student.ethz.ch>
Branch: implement-id
Changeset: r220:c0ff042ed265
Date: 2013-06-21 13:08 +0200
http://bitbucket.org/pypy/stmgc/changeset/c0ff042ed265/

Log:	amazingly seems to not crash..

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -446,8 +446,9 @@
 
   B = stmgc_duplicate_old(P);
   B->h_tid |= GCFLAG_BACKUP_COPY;
-  if (P->h_tid & GCFLAG_OLD)
-    B->h_original = P;
+  if (!(P->h_original) && (P->h_tid & GCFLAG_OLD)) {
+      B->h_original = (revision_t)P;
+  }
   
   P->h_tid |= GCFLAG_PRIVATE_FROM_PROTECTED;
   P->h_revision = (revision_t)B;
@@ -475,8 +476,10 @@
   /* note that stmgc_duplicate() usually returns a young object, but may
      return an old one if the nursery is full at this moment. */
   gcptr L = stmgc_duplicate(R);
-  if (!(L->h_original))
+  if (!(L->h_original)) {
+    assert(R->h_tid & GCFLAG_OLD); // if not, force stm_id??
     L->h_original = (revision_t)R;
+  }
 
   assert(!(L->h_tid & GCFLAG_BACKUP_COPY));
   assert(!(L->h_tid & GCFLAG_STUB));
@@ -1010,10 +1013,16 @@
                                                    | GCFLAG_OLD;
       assert(!(L->h_tid & GCFLAG_HAS_ID));
       stub->h_revision = ((revision_t)L) | 2;
-      if (L->h_original)
+      if (L->h_original) {
         stub->h_original = L->h_original;
-      else
+      }
+      else if (L->h_tid & GCFLAG_OLD) {
+        stub->h_original = (revision_t)L;
+      }
+      else {
         L->h_original = (revision_t)stub;
+      }
+      
       item->val = stub;
 
     } G2L_LOOP_END;
@@ -1091,12 +1100,13 @@
               if (bool_cas(&B->h_revision, v, (revision_t)P))
                 break;
             }
-        }
-      else if (P->h_tid & GCFLAG_HAS_ID) {
-        /* The backup is the "id object".  */
+        }      
+      else if (P->h_original == (revision_t)B) {
+        /* The backup is the "id object" */
+        assert(!(P->h_tid & GCFLAG_HAS_ID));
+
         B->h_tid &= ~GCFLAG_BACKUP_COPY;
         B->h_tid |= GCFLAG_PUBLIC;
-        P->h_tid &= ~GCFLAG_HAS_ID;
         B->h_revision = (revision_t)P;
       }
       else
@@ -1139,10 +1149,10 @@
              stealing will follow its h_revision (to B).
           */
         }
-      else if (P->h_tid & GCFLAG_HAS_ID) {
+      else if (P->h_original == (revision_t)B) {
         /* The backup is the "id object".  P becomes outdated. */
+        assert(!(P->h_tid & GCFLAG_HAS_ID));
         P->h_tid |= GCFLAG_PUBLIC;
-        P->h_tid &= ~GCFLAG_HAS_ID;
         B->h_tid |= GCFLAG_PUBLIC;
         B->h_tid &= ~GCFLAG_BACKUP_COPY;
         if (!(P->h_tid & GCFLAG_OLD)) P->h_tid |= GCFLAG_NURSERY_MOVED;
@@ -1152,7 +1162,8 @@
         {
           /* copy the backup copy B back over the now-protected object P,
              and then free B, which will not be used any more. */
-          assert(B->h_original == P);
+          assert(!(P->h_original) 
+                 || (B->h_original == (revision_t)P->h_original));
           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
@@ -101,93 +101,51 @@
     struct tx_descriptor *d = thread_descriptor;
     revision_t result;
 
+    spinlock_acquire(d->public_descriptor->collection_lock, 'I');
     if (p->h_original) {
-        fprintf(stderr, "stm_id(%p) has original: %p\n", p, (gcptr)p->h_original);
+        spinlock_release(d->public_descriptor->collection_lock);
         return p->h_original;
     }
 
-    spinlock_acquire(d->public_descriptor->collection_lock, 'I');
+    /* old objects must have an h_original OR be
+       the original itself. 
+       if some thread stole p when it was still young,
+       it must have set h_original. stealing an old obj
+       makes the old obj "original".
+    */
     if (p->h_tid & GCFLAG_OLD) {
         /* it must be this exact object */
         result = (revision_t)p;
     }
     else {
-        /* must create shadow original object */
-        gcptr O = stmgc_duplicate_old(p);
-        p->h_original = (revision_t)O;
-        p->h_tid |= GCFLAG_HAS_ID;
-        O->h_tid |= GCFLAG_PUBLIC;
-        
-        result = (revision_t)O;
-        
-        fprintf(stderr, "stm_id(%p): is young, preallocate old id-copy %p\n",
-                p, O);
-    }
-
-
-    if (p->h_original) {
-        // maybe in the meantime?
-        fprintf(stderr, "stm_id(%p) has original NOW: %p\n", p, (gcptr)p->h_original);
-        spinlock_release(d->public_descriptor->collection_lock);
-        return p->h_original;
-    }
-    
-    //p->h_original == NULL
-
-    if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
-        gcptr B = (gcptr)p->h_revision;
-        if (p->h_tid & GCFLAG_OLD) {
-            /* may have become old after becoming priv_from_prot */
-            if (B->h_tid & GCFLAG_BACKUP_COPY) {
-                B->h_original = p;
-                result = (revision_t)p;
-                fprintf(stderr, "stm_id(%p): is priv_from_prot and old. make ");
-            }
-            else {
-                /* someone stole and assumes the backup as the ID */
-                p->h_original = B;
-                result = (revision_t)B;
-            }
-        }
-        else {
-            // use backup copy as ID object
-            p->h_tid |= GCFLAG_HAS_ID; // see AbortPrivateFromProtected
+        /* must create shadow original object or use
+           backup, if exists */
+        if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
+            gcptr B = (gcptr)p->h_revision;
+            /* don't set, otherwise nursery will copy over backup */
+            //p->h_tid |= GCFLAG_HAS_ID; // see AbortPrivateFromProtected
             p->h_original = (revision_t)B;
             // B->h_tid |= GCFLAG_PUBLIC; done by CommitPrivateFromProtected
             
             result = (revision_t)B;
-            fprintf(stderr,
-                    "stm_id(%p): is private_from_protected, make the backup %p an id-copy\n",
-                    p, B);
         }
-    } 
-    else if (!(p->h_tid & GCFLAG_OLD)) {//(is_in_nursery(p)) {
-        // preallocate old "original" outside;
-        // like stealing
-        gcptr O = stmgc_duplicate_old(p);
-        //p->h_revision = (revision_t)O;
-        p->h_original = (revision_t)O;
-        p->h_tid |= GCFLAG_HAS_ID;
-        O->h_tid |= GCFLAG_PUBLIC;
-        
-        result = (revision_t)O;
-        
-        fprintf(stderr, "stm_id(%p): is young, preallocate old id-copy %p\n",
-                p, O);
+        else {
+            gcptr O = stmgc_duplicate_old(p);
+            p->h_original = (revision_t)O;
+            p->h_tid |= GCFLAG_HAS_ID;
+            O->h_tid |= GCFLAG_PUBLIC;
+            
+            result = (revision_t)O;
+        }
     }
-    else {// if (p->h_tid & GCFLAG_OLD) {
-        /* obj is old, possibly private or protected */
-        /* last, because there are old private(_from_public) objects */
-        result = (revision_t)p;
-        fprintf(stderr, "stm_id(%p): is itself\n", p);
-    }
-
+    
     spinlock_release(d->public_descriptor->collection_lock);
     return result;
 }
 
 revision_t stm_pointer_equal(gcptr p1, gcptr p2)
 {
+    /* XXX: */
     return stm_id(p1) == stm_id(p2);
 }
 
@@ -245,11 +203,6 @@
             /* already has a place to go to */
             gcptr id_obj = (gcptr)obj->h_original;
 
-            /* assert(!(id_obj->h_tid & GCFLAG_BACKUP_COPY));
-               well, if it is still a backup, then it wasn't
-               stolen. We can use it for our young obj.
-             */
-
             copy_to_old_id_copy(obj, id_obj);
             fresh_old_copy = id_obj;
             obj->h_tid &= ~GCFLAG_HAS_ID;
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -81,10 +81,16 @@
                                                    | GCFLAG_STUB
                                                    | GCFLAG_OLD;
     stub->h_revision = ((revision_t)obj) | 2;
-    if (obj->h_original)
+    if (obj->h_original) {
         stub->h_original = obj->h_original;
-    else
+    }
+    else if (obj->h_tid & GCFLAG_OLD) {
+        stub->h_original = (revision_t)obj;
+    }
+    else {
         obj->h_original = (revision_t)stub;
+    }
+
     g2l_insert(&sd->all_stubs, obj, stub);
 
     if (!(obj->h_tid & GCFLAG_OLD))
@@ -113,19 +119,19 @@
     if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
         gcptr B = (gcptr)L->h_revision;     /* the backup copy */
         
-        if(L->h_tid & GCFLAG_HAS_ID) {
-            /* if L has ID, then the backup is the "original" */
-            assert(L->h_original == (revision_t)B);
-            L->h_tid &= ~GCFLAG_HAS_ID; // now it's simply stolen
-        } 
+        if (L->h_original) {
+            /* may have HAS_ID */
+            B->h_original = L->h_original;
+        }
         else if (L->h_tid & GCFLAG_OLD) {
-            /* became old after becoming priv_from_protected 
-             make L the original
-             */
+            assert(!(L->h_tid & GCFLAG_HAS_ID));
+            /* original must be L */
             B->h_original = (revision_t)L;
         }
-        /* otherwise: L is the original */
-        assert (!(B->h_tid & GCFLAG_HAS_ID));
+        else {
+            /* we can make the backup the "original" */
+            L->h_original = (revision_t)B;
+        }
 
         /* 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
@@ -169,8 +175,10 @@
 
         fprintf(stderr, "stolen: %p -> %p\n", P, L);
 
+        
         if (!(L->h_tid & GCFLAG_OLD)) { 
             gcptr O;
+            
             if (L->h_tid & GCFLAG_HAS_ID) {
                 /* use id-copy for us */
                 O = (gcptr)L->h_original;
@@ -184,6 +192,7 @@
                 L->h_revision = (revision_t)O;
                 L->h_original = (revision_t)O;
             }
+
             L->h_tid |= GCFLAG_PUBLIC | GCFLAG_NURSERY_MOVED;
             /* subtle: we need to remove L from the fxcache of the target
                thread, otherwise its read barrier might not trigger on it.
@@ -195,6 +204,7 @@
             L = O;
             fprintf(stderr, "\t---> %p\n", L);
         }
+
         assert(L->h_tid & GCFLAG_OLD);
     }
 


More information about the pypy-commit mailing list