Commits

Armin Rigo committed 3e503e6

Fix. See "subtle".

Comments (0)

Files changed (3)

   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;
 
     }
 }
 
-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)
       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;
     }
 
   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;
 
 
   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;
     }
       */
       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);
             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);
         }
 
     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);
 
 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)))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.