[pypy-commit] stmgc default: hg merge fix-1

arigo noreply at buildbot.pypy.org
Tue Jun 18 21:05:52 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r189:d849db4efe62
Date: 2013-06-18 21:05 +0200
http://bitbucket.org/pypy/stmgc/changeset/d849db4efe62/

Log:	hg merge fix-1

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -202,6 +202,7 @@
   gcptrlist_insert(&d->list_of_read_objects, P);
 
  add_in_recent_reads_cache:
+  assert(!(P->h_tid & GCFLAG_NURSERY_MOVED));
   fxcache_add(&d->recent_reads_cache, P);
   return P;
 
@@ -235,7 +236,8 @@
     }
 }
 
-static gcptr _match_public_to_private(gcptr P, gcptr pubobj, gcptr privobj)
+static gcptr _match_public_to_private(gcptr P, gcptr pubobj, gcptr privobj,
+                                      int from_stolen)
 {
   gcptr org_pubobj = pubobj;
   while ((pubobj->h_revision & 3) == 0)
@@ -251,6 +253,10 @@
       assert(is_private(privobj));
       if (P != org_pubobj)
         fprintf(stderr, "| actually %p ", org_pubobj);
+      if (from_stolen)
+        fprintf(stderr, "-stolen");
+      else
+        assert(org_pubobj->h_tid & GCFLAG_PUBLIC_TO_PRIVATE);
       fprintf(stderr, "-public_to_private-> %p private\n", privobj);
       return privobj;
     }
@@ -265,7 +271,8 @@
 
   G2L_LOOP_FORWARD(d->public_to_private, item)
     {
-      R = _match_public_to_private(P, item->addr, item->val);
+      assert(item->addr->h_tid & GCFLAG_PUBLIC_TO_PRIVATE);
+      R = _match_public_to_private(P, item->addr, item->val, 0);
       if (R != NULL)
         return R;
 
@@ -276,7 +283,9 @@
 
   for (i = 0; i < size; i += 2)
     {
-      R = _match_public_to_private(P, items[i], items[i + 1]);
+      if (items[i + 1] == NULL)
+        continue;
+      R = _match_public_to_private(P, items[i], items[i + 1], 1);
       if (R != NULL)
         return R;
     }
@@ -532,11 +541,12 @@
       */
       if (R->h_tid & GCFLAG_NURSERY_MOVED)
         {
-          /* Bah, the object turned into this kind of stub while we
-             were waiting for the collection_lock, because it was
-             stolen by someone else.  Use R->h_revision instead. */
+          /* Bah, the object turned into this kind of stub, possibly
+             while we were waiting for the collection_lock, because it
+             was stolen by someone else.  Use R->h_revision instead. */
           assert(IS_POINTER(R->h_revision));
           R = (gcptr)R->h_revision;
+          assert(R->h_tid & GCFLAG_PUBLIC);
         }
       assert(R->h_tid & GCFLAG_OLD);
       W = LocalizePublic(d, R);
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -154,6 +154,13 @@
             gcptr O = stmgc_duplicate_old(L);
             L->h_revision = (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.
+               It is mostly fine because it is anyway identical to O.  But
+               the issue is if the target thread adds a public_to_private
+               off O later: the write barrier will miss it if it only sees
+               L. */
+            gcptrlist_insert2(&foreign_pd->stolen_objects, L, NULL);
             L = O;
             fprintf(stderr, "\t---> %p\n", L);
         }
@@ -217,17 +224,20 @@
 
     for (i = 0; i < size; i += 2) {
         gcptr B = items[i];
+        assert(!(B->h_tid & GCFLAG_BACKUP_COPY));  /* already removed */
+
+        /* to be on the safe side --- but actually needed, see the
+           gcptrlist_insert2(L, NULL) above */
+        fxcache_remove(&d->recent_reads_cache, B);
+
         gcptr L = items[i + 1];
-
+        if (L == NULL)
+            continue;
         assert(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
-        assert(!(B->h_tid & GCFLAG_BACKUP_COPY));  /* already removed */
 
         g2l_insert(&d->public_to_private, B, L);
 
-        /* to be on the safe side */
-        fxcache_remove(&d->recent_reads_cache, B);
-
-        /* but this is definitely needed: all keys in public_to_private
+        /* this is definitely needed: all keys in public_to_private
            must appear in list_of_read_objects */
         fprintf(stderr, "n.readobj: %p\n", B);
         gcptrlist_insert(&d->list_of_read_objects, B);
diff --git a/c4/stmsync.c b/c4/stmsync.c
--- a/c4/stmsync.c
+++ b/c4/stmsync.c
@@ -77,6 +77,9 @@
 
 gcptr stm_read_barrier(gcptr obj)
 {
+    //if (FXCACHE_AT(obj) == obj)
+    //    fprintf(stderr, "read_barrier: in cache: %p\n", obj);
+
     /* XXX inline in the caller, optimize to get the smallest code */
     if (UNLIKELY((obj->h_revision != stm_private_rev_num) &&
                  (FXCACHE_AT(obj) != obj)))


More information about the pypy-commit mailing list