Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r129:0fdcdfbbc387
Date: 2013-06-14 20:20 +0200
http://bitbucket.org/pypy/stmgc/changeset/0fdcdfbbc387/

Log:    Revert the gcflag_xyz() functions; instead found a way to keep the
        assertion error message readable, by using "static const" values.

        More progress.

diff --git a/c4/dbgmem.c b/c4/dbgmem.c
--- a/c4/dbgmem.c
+++ b/c4/dbgmem.c
@@ -22,6 +22,7 @@
     intptr_t align = ((intptr_t)p) & (PAGE_SIZE-1);
     p = ((char *)p) - align;
     sz += align;
+    fprintf(stderr, "dbgmem: %p, %ld, %d\n", p, (long)sz, prot);
     int err = mprotect(p, sz, prot);
     assert(err == 0);
 }
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -33,7 +33,7 @@
 static int is_private(gcptr P)
 {
   return (P->h_revision == stm_private_rev_num) ||
-            gcflag_private_from_protected(P);
+    (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
 }
 int _stm_is_private(gcptr P)
 {
@@ -80,7 +80,7 @@
   revision_t v;
 
  restart_all:
-  if (gcflag_private_from_protected(P))
+  if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
     {
       assert(!(P->h_revision & 1));   /* pointer to the backup copy */
 
@@ -95,14 +95,14 @@
   /* else, for the rest of this function, we can assume that P was not
      a private copy */
 
-  if (gcflag_public(P))
+  if (P->h_tid & GCFLAG_PUBLIC)
     {
       /* follow the chained list of h_revision's as long as they are
          regular pointers.  We will only find more public objects
          along this chain.
       */
     restart_all_public:
-      assert(gcflag_public(P));
+      assert(P->h_tid & GCFLAG_PUBLIC);
       v = ACCESS_ONCE(P->h_revision);
       if (!(v & 1))  // "is a pointer", i.e.
         {            //      "has a more recent revision"
@@ -112,7 +112,7 @@
 
           gcptr P_prev = P;
           P = (gcptr)v;
-          assert(gcflag_public(P));
+          assert(P->h_tid & GCFLAG_PUBLIC);
 
           v = ACCESS_ONCE(P->h_revision);
 
@@ -145,7 +145,7 @@
          because *we* have an entry in d->public_to_private.  (It might
          also be someone else.)
       */
-      if (gcflag_public_to_private(P))
+      if (P->h_tid & GCFLAG_PUBLIC_TO_PRIVATE)
         {
           wlog_t *item;
         retry_public_to_private:;
@@ -154,7 +154,7 @@
           /* We have a key in 'public_to_private'.  The value is the
              corresponding private object. */
           P = item->val;
-          assert(!gcflag_public(P));
+          assert(!(P->h_tid & GCFLAG_PUBLIC));
           assert(is_private(P));
           fprintf(stderr, "read_barrier: %p -> %p public_to_private\n", G, P);
           return P;
@@ -229,7 +229,7 @@
       fprintf(stderr, "read_barrier: %p -> stealing %p...\n  ", G, P);
       stm_steal_stub(P);
 
-      assert(gcflag_public(P));
+      assert(P->h_tid & GCFLAG_PUBLIC);
       goto restart_all_public;
     }
 }
@@ -245,8 +245,8 @@
   if (pubobj == P || ((P->h_revision & 3) == 2 &&
                       pubobj->h_revision == P->h_revision))
     {
-      assert(!gcflag_stub(org_pubobj));
-      assert(!gcflag_public(privobj));
+      assert(!(org_pubobj->h_tid & GCFLAG_STUB));
+      assert(!(privobj->h_tid & GCFLAG_PUBLIC));
       assert(is_private(privobj));
       if (P != org_pubobj)
         fprintf(stderr, "| actually %p ", org_pubobj);
@@ -299,7 +299,7 @@
       return P;
     }
 
-  if (gcflag_private_from_protected(P))
+  if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
     {
       /* private too, with a backup copy */
       assert(!(P->h_revision & 1));
@@ -307,7 +307,7 @@
       return P;
     }
 
-  if (gcflag_public(P))
+  if (P->h_tid & GCFLAG_PUBLIC)
     {
       fprintf(stderr, "public ");
 
@@ -323,7 +323,7 @@
             }
 
           P = (gcptr)v;
-          assert(gcflag_public(P));
+          assert(P->h_tid & GCFLAG_PUBLIC);
           fprintf(stderr, "-> %p public ", P);
         }
 
@@ -354,12 +354,12 @@
     {
       P = (gcptr)(v - 2);
       fprintf(stderr, "-foreign-> %p ", P);
-      if (gcflag_private_from_protected(P))
+      if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
         {
           P = (gcptr)P->h_revision;     /* the backup copy */
           fprintf(stderr, "-backup-> %p ", P);
         }
-      if (!gcflag_public(P))
+      if (!(P->h_tid & GCFLAG_PUBLIC))
         {
           fprintf(stderr, "protected by someone else!\n");
           return (gcptr)-1;
@@ -397,10 +397,10 @@
 
   assert(P->h_revision != stm_private_rev_num);
   assert(P->h_revision & 1);
-  assert(!gcflag_public_to_private(P));
-  assert(!gcflag_backup_copy(P));
-  assert(!gcflag_stub(P));
-  assert(!gcflag_private_from_protected(P));
+  assert(!(P->h_tid & GCFLAG_PUBLIC_TO_PRIVATE));
+  assert(!(P->h_tid & GCFLAG_BACKUP_COPY));
+  assert(!(P->h_tid & GCFLAG_STUB));
+  assert(!(P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
 
   B = stmgc_duplicate(P);
   B->h_tid |= GCFLAG_BACKUP_COPY;
@@ -415,7 +415,7 @@
 
 static gcptr LocalizePublic(struct tx_descriptor *d, gcptr R)
 {
-  assert(gcflag_public(R));
+  assert(R->h_tid & GCFLAG_PUBLIC);
 
 #ifdef _GC_DEBUG
   wlog_t *entry;
@@ -427,9 +427,9 @@
   R->h_tid |= GCFLAG_PUBLIC_TO_PRIVATE;
 
   gcptr L = stmgc_duplicate(R);
-  assert(!gcflag_backup_copy(L));
-  assert(!gcflag_stub(L));
-  assert(!gcflag_private_from_protected(L));
+  assert(!(L->h_tid & GCFLAG_BACKUP_COPY));
+  assert(!(L->h_tid & GCFLAG_STUB));
+  assert(!(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
   L->h_tid &= ~(GCFLAG_OLD               |
                 GCFLAG_VISITED           |
                 GCFLAG_PUBLIC            |
@@ -451,10 +451,10 @@
 
 static inline void record_write_barrier(gcptr P)
 {
-  if (gcflag_write_barrier(P))
+  if (P->h_tid & GCFLAG_WRITE_BARRIER)
     {
       P->h_tid &= ~GCFLAG_WRITE_BARRIER;
-      gcptrlist_insert(&thread_descriptor->old_with_young_pointers_inside, P);
+      gcptrlist_insert(&thread_descriptor->old_objects_to_trace, P);
     }
 }
 
@@ -463,9 +463,9 @@
   if (is_private(P))
     {
       /* If we have GCFLAG_WRITE_BARRIER in P, then list it into
-         old_with_young_pointers_inside: it's a private object that may
-         be modified by the program after we return, and the mutation
-         may be to write young pointers (in fact it's a common case).
+         old_objects_to_trace: it's a private object that may be
+         modified by the program after we return, and the mutation may
+         be to write young pointers (in fact it's a common case).
       */
       record_write_barrier(P);
       return P;
@@ -490,20 +490,20 @@
   if (d->public_descriptor->stolen_objects.size != 0)
     stm_normalize_stolen_objects(d);
 
-  if (gcflag_public(R))
+  if (R->h_tid & GCFLAG_PUBLIC)
     {
       /* Make and return a new (young) private copy of the public R.
-         Add R into the list 'old_public_with_young_copy'.
+         Add R into the list 'public_with_young_copy'.
       */
-      assert(gcflag_old(R));
-      gcptrlist_insert(&d->old_public_with_young_copy, R);
+      assert(R->h_tid & GCFLAG_OLD);
+      gcptrlist_insert(&d->public_with_young_copy, R);
       W = LocalizePublic(d, R);
     }
   else
     {
       /* Turn the protected copy in-place into a private copy.  If it's
          an old object that still has GCFLAG_WRITE_BARRIER, then we must
-         also record it in the list 'old_with_young_pointers_inside'. */
+         also record it in the list 'old_objects_to_trace'. */
       W = LocalizeProtected(d, R);
       record_write_barrier(W);
     }
@@ -553,7 +553,7 @@
       v = ACCESS_ONCE(R->h_revision);
       if (!(v & 1))               // "is a pointer", i.e.
         {                         //   "has a more recent revision"
-          if (gcflag_private_from_protected(R))
+          if (R->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
             {
               /* such an object R might be listed in list_of_read_objects
                  before it was turned from protected to private */
@@ -811,7 +811,7 @@
       gcptr R = item->addr;
       revision_t v;
     retry:
-      assert(gcflag_public(R));
+      assert(R->h_tid & GCFLAG_PUBLIC);
       v = ACCESS_ONCE(R->h_revision);
       if (!(v & 1))            // "is a pointer", i.e.
         {                      //   "has a more recent revision"
@@ -831,7 +831,7 @@
         goto retry;
 
       gcptr L = item->val;
-      assert(gcflag_private_from_protected(L) ?
+      assert(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED ?
              L->h_revision == (revision_t)R :
              L->h_revision == stm_private_rev_num);
       assert(v != stm_private_rev_num);
@@ -855,7 +855,7 @@
       gcptr L = item->val;
       revision_t expected, v = L->h_revision;
 
-      if (gcflag_private_from_protected(L))
+      if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
         expected = (revision_t)R;
       else
         expected = stm_private_rev_num;
@@ -892,10 +892,10 @@
   G2L_LOOP_FORWARD(d->public_to_private, item)
     {
       gcptr L = item->val;
-      assert(!gcflag_visited(L));
-      assert(!gcflag_public_to_private(L));
-      assert(!gcflag_prebuilt_original(L));
-      assert(!gcflag_nursery_moved(L));
+      assert(!(L->h_tid & GCFLAG_VISITED));
+      assert(!(L->h_tid & GCFLAG_PUBLIC_TO_PRIVATE));
+      assert(!(L->h_tid & GCFLAG_PREBUILT_ORIGINAL));
+      assert(!(L->h_tid & GCFLAG_NURSERY_MOVED));
       assert(L->h_revision != localrev);   /* modified by AcquireLocks() */
 
 #ifdef DUMP_EXTRA
@@ -919,9 +919,9 @@
       gcptr R = item->addr;
       revision_t v = (revision_t)item->val;
 
-      assert(gcflag_public(R));
-      assert(gcflag_public_to_private(R));
-      assert(!gcflag_nursery_moved(R));
+      assert(R->h_tid & GCFLAG_PUBLIC);
+      assert(R->h_tid & GCFLAG_PUBLIC_TO_PRIVATE);
+      assert(!(R->h_tid & GCFLAG_NURSERY_MOVED));
       assert(R->h_revision != localrev);
 
 #ifdef DUMP_EXTRA
@@ -932,7 +932,7 @@
       ACCESS_ONCE(R->h_revision) = v;
 
 #if 0
-      if (gcflag_prebuilt_original(R))
+      if (R->h_tid & GCFLAG_PREBUILT_ORIGINAL)
         {
           /* cannot possibly get here more than once for a given value of R */
           pthread_mutex_lock(&mutex_prebuilt_gcroots);
@@ -957,7 +957,7 @@
   for (i = 0; i < size; i++)
     {
       gcptr P = items[i];
-      assert(gcflag_private_from_protected(P));
+      assert(P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
       P->h_tid &= ~GCFLAG_PRIVATE_FROM_PROTECTED;
 
       if (P->h_revision & 1)   // "is not a pointer"
@@ -972,7 +972,7 @@
       gcptr B = (gcptr)P->h_revision;
       P->h_revision = new_revision;
 
-      if (gcflag_public(B))
+      if (B->h_tid & GCFLAG_PUBLIC)
         {
           /* B was stolen */
           while (1)
@@ -987,7 +987,7 @@
         }
       else
         {
-          stm_free(B, stmcb_size(B));
+          //stm_free(B, stmcb_size(B));
         }
     };
   gcptrlist_clear(&d->private_from_protected);
@@ -1001,20 +1001,20 @@
   for (i = 0; i < size; i++)
     {
       gcptr P = items[i];
-      assert(gcflag_private_from_protected(P));
+      assert(P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
       assert(!(P->h_revision & 1));   // "is a pointer"
 
       gcptr B = (gcptr)P->h_revision;
-      if (gcflag_public(B))
+      if (B->h_tid & GCFLAG_PUBLIC)
         {
-          assert(!gcflag_backup_copy(B));
+          assert(!(B->h_tid & GCFLAG_BACKUP_COPY));
           P->h_tid &= ~GCFLAG_PRIVATE_FROM_PROTECTED;
           P->h_tid |= GCFLAG_PUBLIC;
           /* P becomes a public outdated object */
         }
       else
         {
-          assert(gcflag_backup_copy(B));
+          assert(B->h_tid & GCFLAG_BACKUP_COPY);
           memcpy(P, B, stmcb_size(P));
           P->h_tid &= ~GCFLAG_BACKUP_COPY;
         }
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -44,7 +44,7 @@
  * objects (which may be turned private again).  It may be left set on
  * public objects but is ignored there, because such objects are read-only.
  * The flag is removed once a write occurs and the object is recorded in
- * the list 'old_pointing_to_young'; it is set again at the next minor
+ * the list 'old_objects_to_trace'; it is set again at the next minor
  * collection.
  *
  * GCFLAG_NURSERY_MOVED is used temporarily during minor collections.
@@ -54,16 +54,16 @@
  * that is == 2 (mod 4): in this case they point to a protected/private
  * object that belongs to the thread 'STUB_THREAD(p_stub)'.
  */
-#define GCFLAG_OLD               (STM_FIRST_GCFLAG << 0)
-#define GCFLAG_VISITED           (STM_FIRST_GCFLAG << 1)
-#define GCFLAG_PUBLIC            (STM_FIRST_GCFLAG << 2)
-#define GCFLAG_PREBUILT_ORIGINAL (STM_FIRST_GCFLAG << 3)
-#define GCFLAG_PUBLIC_TO_PRIVATE (STM_FIRST_GCFLAG << 4)
-#define GCFLAG_WRITE_BARRIER     (STM_FIRST_GCFLAG << 5)
-#define GCFLAG_NURSERY_MOVED     (STM_FIRST_GCFLAG << 6)
-#define GCFLAG_BACKUP_COPY       (STM_FIRST_GCFLAG << 7)   /* debugging */
-#define GCFLAG_STUB              (STM_FIRST_GCFLAG << 8)   /* debugging */
-#define GCFLAG_PRIVATE_FROM_PROTECTED (STM_FIRST_GCFLAG << 9)
+static const revision_t GCFLAG_OLD                    = STM_FIRST_GCFLAG << 0;
+static const revision_t GCFLAG_VISITED                = STM_FIRST_GCFLAG << 1;
+static const revision_t GCFLAG_PUBLIC                 = STM_FIRST_GCFLAG << 2;
+static const revision_t GCFLAG_PREBUILT_ORIGINAL      = STM_FIRST_GCFLAG << 3;
+static const revision_t GCFLAG_PUBLIC_TO_PRIVATE      = STM_FIRST_GCFLAG << 4;
+static const revision_t GCFLAG_WRITE_BARRIER          = STM_FIRST_GCFLAG << 5;
+static const revision_t GCFLAG_NURSERY_MOVED          = STM_FIRST_GCFLAG << 6;
+static const revision_t GCFLAG_BACKUP_COPY  /*debug*/ = STM_FIRST_GCFLAG << 7;
+static const revision_t GCFLAG_STUB         /*debug*/ = STM_FIRST_GCFLAG << 8;
+static const revision_t GCFLAG_PRIVATE_FROM_PROTECTED = STM_FIRST_GCFLAG << 9;
 
 /* this value must be reflected in PREBUILT_FLAGS in stmgc.h */
 #define GCFLAG_PREBUILT  (GCFLAG_VISITED           | \
@@ -83,20 +83,6 @@
                          "PRIVATE_FROM_PROTECTED", \
                          NULL }
 
-#define _DECLARE_FLAG(funcname, flagname)       \
-    static inline _Bool funcname(gcptr P) {     \
-        return (P->h_tid & flagname) != 0; }
-_DECLARE_FLAG(gcflag_old,                    GCFLAG_OLD)
-_DECLARE_FLAG(gcflag_visited,                GCFLAG_VISITED)
-_DECLARE_FLAG(gcflag_public,                 GCFLAG_PUBLIC)
-_DECLARE_FLAG(gcflag_prebuilt_original,      GCFLAG_PREBUILT_ORIGINAL)
-_DECLARE_FLAG(gcflag_public_to_private,      GCFLAG_PUBLIC_TO_PRIVATE)
-_DECLARE_FLAG(gcflag_write_barrier,          GCFLAG_WRITE_BARRIER)
-_DECLARE_FLAG(gcflag_nursery_moved,          GCFLAG_NURSERY_MOVED)
-_DECLARE_FLAG(gcflag_backup_copy,            GCFLAG_BACKUP_COPY)
-_DECLARE_FLAG(gcflag_stub,                   GCFLAG_STUB)
-_DECLARE_FLAG(gcflag_private_from_protected, GCFLAG_PRIVATE_FROM_PROTECTED)
-
 /************************************************************/
 
 #define ABRT_MANUAL               0
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -26,8 +26,7 @@
     stm_free(d->nursery_base, GC_NURSERY);
 
     gcptrlist_delete(&d->old_objects_to_trace);
-    gcptrlist_delete(&d->public_to_young);
-    gcptrlist_delete(&d->private_old_pointing_to_young);
+    gcptrlist_delete(&d->public_with_young_copy);
 }
 
 static char *collect_and_allocate_size(size_t size);  /* forward */
@@ -67,11 +66,11 @@
 
 static inline gcptr create_old_object_copy(gcptr obj)
 {
-    assert(!gcflag_nursery_moved(obj));
-    assert(!gcflag_visited(obj));
-    assert(!gcflag_write_barrier(obj));
-    assert(!gcflag_prebuilt_original(obj));
-    assert(!gcflag_old(obj));
+    assert(!(obj->h_tid & GCFLAG_NURSERY_MOVED));
+    assert(!(obj->h_tid & GCFLAG_VISITED));
+    assert(!(obj->h_tid & GCFLAG_WRITE_BARRIER));
+    assert(!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL));
+    assert(!(obj->h_tid & GCFLAG_OLD));
 
     size_t size = stmcb_size(obj);
     gcptr fresh_old_copy = stm_malloc(size);
@@ -119,27 +118,27 @@
 
 static void mark_public_to_young(struct tx_descriptor *d)
 {
-    /* "public_to_young" contains ptrs to the public copies used as
-       key of "public_to_private", but only the ones that were added
-       since the last minor collection.  Once the transaction commit,
-       they stay in "public_to_young", and so they become public
-       objects whose h_revision is a public stub, which itself points
-       (originally) to a protected young object.
+    /* "public_with_young_copy" lists the public copies that may have
+       a more recent (or in-progress) private or protected object that
+       is young.  Note that public copies themselves are always old.
 
-       Be careful and accept more or less any object in the list, which
-       can show up because of aborted transactions.
+       The list should only contain public objects, but beyong that, be
+       careful and ignore any strange object: it can show up because of
+       aborted transactions (and then some different changes).
     */
-    long i, size = d->public_to_young.size;
-    gcptr *items = d->public_to_young.items;
+    long i, size = d->public_with_young_copy.size;
+    gcptr *items = d->public_with_young_copy.items;
 
     for (i = 0; i < size; i++) {
         gcptr P = items[i];
-        assert(gcflag_public(P));
+        assert(P->h_tid & GCFLAG_PUBLIC);
 
         revision_t v = ACCESS_ONCE(P->h_revision);
         wlog_t *item;
         G2L_FIND(d->public_to_private, P, item, goto not_in_public_to_private);
 
+        /* found P in 'public_to_private' */
+
         if (!(v & 1)) {   // "is a pointer"
             /* P is both a key in public_to_private and an outdated copy.
                We are in a case where we know the transaction will not
@@ -153,6 +152,7 @@
 
         fprintf(stderr, "public_to_young: %p -> %p in public_to_private\n",
                 item->addr, item->val);
+        assert(_stm_is_private(item->val));
         visit_if_young(&item->val);
         continue;
 
@@ -199,14 +199,7 @@
         S->h_revision = ((revision_t)L) | 2;
     }
 
-    gcptrlist_clear(&d->public_to_young);
-}
-
-static void mark_private_old_pointing_to_young(struct tx_descriptor *d)
-{
-    /* trace the objects recorded earlier by stmgc_write_barrier() */
-    gcptrlist_move(&d->old_objects_to_trace,
-                   &d->private_old_pointing_to_young);
+    gcptrlist_clear(&d->public_with_young_copy);
 }
 
 static void visit_all_outside_objects(struct tx_descriptor *d)
@@ -214,8 +207,8 @@
     while (gcptrlist_size(&d->old_objects_to_trace) > 0) {
         gcptr obj = gcptrlist_pop(&d->old_objects_to_trace);
 
-        assert(gcflag_old(obj));
-        assert(!gcflag_write_barrier(obj));
+        assert(obj->h_tid & GCFLAG_OLD);
+        assert(!(obj->h_tid & GCFLAG_WRITE_BARRIER));
         obj->h_tid |= GCFLAG_WRITE_BARRIER;
 
         stmcb_trace(obj, &visit_if_young);
@@ -225,8 +218,6 @@
 static void setup_minor_collect(struct tx_descriptor *d)
 {
     spinlock_acquire(d->public_descriptor->collection_lock, 'M');  /*minor*/
-    assert(gcptrlist_size(&d->old_objects_to_trace) == 0);
-
     if (d->public_descriptor->stolen_objects.size != 0)
         stm_normalize_stolen_objects(d);
 }
@@ -234,6 +225,7 @@
 static void teardown_minor_collect(struct tx_descriptor *d)
 {
     assert(gcptrlist_size(&d->old_objects_to_trace) == 0);
+    assert(gcptrlist_size(&d->public_with_young_copy) == 0);
     assert(gcptrlist_size(&d->public_descriptor->stolen_objects) == 0);
 
     spinlock_release(d->public_descriptor->collection_lock);
@@ -255,8 +247,6 @@
 
     mark_public_to_young(d);
 
-    mark_private_old_pointing_to_young(d);
-
     visit_all_outside_objects(d);
 #if 0
     fix_list_of_read_objects(d);
@@ -292,8 +282,7 @@
     if (d->nursery_current == d->nursery_base /*&&
         !g2l_any_entry(&d->young_objects_outside_nursery)*/ ) {
         /* there is no young object */
-        assert(gcptrlist_size(&d->private_old_pointing_to_young) == 0);
-        assert(gcptrlist_size(&d->public_to_young) == 0);
+        assert(gcptrlist_size(&d->public_with_young_copy) == 0);
         return 0;
     }
     else {
diff --git a/c4/nursery.h b/c4/nursery.h
--- a/c4/nursery.h
+++ b/c4/nursery.h
@@ -11,8 +11,7 @@
     char *nursery_end;                                  \
     char *nursery_base;                                 \
     struct GcPtrList old_objects_to_trace;              \
-    struct GcPtrList old_public_with_young_copy;        \
-    struct GcPtrList old_with_young_pointers_inside;
+    struct GcPtrList public_with_young_copy;
 
 struct tx_descriptor;  /* from et.h */
 
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -55,7 +55,7 @@
 static void replace_ptr_to_protected_with_stub(gcptr *pobj)
 {
     gcptr stub, obj = *pobj;
-    if (obj == NULL || gcflag_public(obj))
+    if (obj == NULL || (obj->h_tid & GCFLAG_PUBLIC) != 0)
         return;
 
     /* we use 'all_stubs', a dictionary, in order to try to avoid
@@ -98,7 +98,7 @@
     /* L might be a private_from_protected, or just a protected copy.
        To know which case it is, read GCFLAG_PRIVATE_FROM_PROTECTED.
     */
-    if (gcflag_private_from_protected(L)) {
+    if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
         gcptr B = (gcptr)L->h_revision;     /* the backup copy */
 
         /* B is now a backup copy, i.e. a protected object, and we own
@@ -107,9 +107,9 @@
         */
         B->h_tid &= ~GCFLAG_BACKUP_COPY;
 
-        if (gcflag_public_to_private(B)) {
+        if (B->h_tid & GCFLAG_PUBLIC_TO_PRIVATE) {
             /* already stolen */
-            assert(gcflag_public(B));
+            assert(B->h_tid & GCFLAG_PUBLIC);
             fprintf(stderr, "already stolen: %p -> %p <-> %p\n", P, L, B);
             L = B;
             goto already_stolen;
@@ -125,7 +125,7 @@
         }
     }
     else {
-        if (gcflag_public(L)) {
+        if (L->h_tid & GCFLAG_PUBLIC) {
             /* already stolen */
             fprintf(stderr, "already stolen: %p -> %p\n", P, L);
             goto already_stolen;
@@ -139,7 +139,7 @@
        thread's collection_lock, so we can read/write the flags.  Change
        it from protected to public.
     */
-    assert(!gcflag_public(L));
+    assert(!(L->h_tid & GCFLAG_PUBLIC));
     L->h_tid |= GCFLAG_PUBLIC;
 
     /* Note that all protected or backup copies have a h_revision that
@@ -192,8 +192,8 @@
         gcptr B = items[i];
         gcptr L = items[i + 1];
 
-        assert(gcflag_private_from_protected(L));
-        assert(!gcflag_backup_copy(B));  /* already removed */
+        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);
 
@@ -218,7 +218,7 @@
         gcptr B = items[i];
         gcptr L = items[i + 1];
 
-        assert(gcflag_private_from_protected(L));
+        assert(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
         if (B == obj)
             return L;
     }
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -502,14 +502,16 @@
     lib.AbortTransaction(lib.ABRT_MANUAL)
 
 def classify(p):
-    private = (p.h_revision == lib.get_private_rev_num() or
-               (p.h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) != 0)
+    private_from_protected = (p.h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) != 0
+    private_other = p.h_revision == lib.get_private_rev_num()
     public  = (p.h_tid & GCFLAG_PUBLIC) != 0
     backup  = (p.h_tid & GCFLAG_BACKUP_COPY) != 0
     stub    = (p.h_tid & GCFLAG_STUB) != 0
-    assert private + public + backup <= 1
+    assert private_from_protected + private_other + public + backup <= 1
     assert (public, stub) != (False, True)
-    if private:
+    if private_from_protected:
+        return "private_from_protected"
+    if private_other:
         return "private"
     if public:
         if stub:
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
@@ -52,7 +52,7 @@
     assert classify(p) == "protected"
     p2 = lib.stm_write_barrier(p)
     assert p2 == p       # does not move
-    assert classify(p) == "private"
+    assert classify(p) == "private_from_protected"
     pback = follow_revision(p)
     assert classify(pback) == "backup"
     assert list_of_private_from_protected() == [p]
@@ -65,7 +65,7 @@
     org_r = p.h_revision
     assert classify(p) == "protected"
     lib.setlong(p, 0, 927122)
-    assert classify(p) == "private"
+    assert classify(p) == "private_from_protected"
     pback = follow_revision(p)
     assert pback and pback != p
     assert pback.h_revision == org_r
@@ -73,7 +73,7 @@
                            GCFLAG_BACKUP_COPY)
     assert lib.rawgetlong(pback, 0) == 78927812
     assert lib.rawgetlong(p, 0) == 927122
-    assert classify(p) == "private"
+    assert classify(p) == "private_from_protected"
     assert classify(pback) == "backup"
 
 def test_prebuilt_is_public():
@@ -263,13 +263,13 @@
             lib.rawsetlong(p2, 0, -451112)
             pback = follow_revision(p1)
             pback_.append(pback)
-            assert classify(p1) == "private"
+            assert classify(p1) == "private_from_protected"
             assert classify(pback) == "backup"
             assert lib.stm_read_barrier(p) == p1
             assert lib.stm_read_barrier(p1) == p1
             assert pback.h_revision & 1
             r.wait_while_in_parallel()
-            assert classify(p1) == "private"
+            assert classify(p1) == "private_from_protected"
             assert classify(pback) == "public"
             assert pback.h_tid & GCFLAG_PUBLIC_TO_PRIVATE
             assert lib.stm_read_barrier(p) == p1
@@ -322,7 +322,7 @@
         if c == 0:
             lib.setlong(p, 0, -38383)
             assert lib.getlong(p, 0) == -38383
-            assert classify(p) == "private"
+            assert classify(p) == "private_from_protected"
             abort_and_retry()
     perform_transaction(cb)
 
diff --git a/c4/test/test_nursery.py b/c4/test/test_nursery.py
--- a/c4/test/test_nursery.py
+++ b/c4/test/test_nursery.py
@@ -168,18 +168,29 @@
     assert classify(p0) == "protected"
     assert lib.rawgetlong(p0, 0) == 81211
 
+def test_old_private_from_protected():
+    p0 = oalloc(HDR + WORD)
+    assert classify(p0) == "protected"
+    lib.setlong(p0, 0, 29820298)
+    assert classify(p0) == "private_from_protected"
+    lib.stm_commit_transaction()
+    lib.stm_begin_inevitable_transaction()
+    assert classify(p0) == "protected"
+    assert lib.getlong(p0, 0) == 29820298
+    assert classify(p0) == "protected"
+
 def test_old_private_from_protected_to_young_private():
     p0 = oalloc_refs(1)
     assert classify(p0) == "protected"
     p1 = nalloc(HDR)
     lib.setptr(p0, 0, p1)
-    assert classify(p0) == "private"   # private_from_protected
+    assert classify(p0) == "private_from_protected"
     lib.stm_push_root(p0)
     minor_collect()
     p0b = lib.stm_pop_root()
     assert p0b == p0
     check_nursery_free(p1)
-    assert classify(p0) == "private"   # private_from_protected
+    assert classify(p0) == "private_from_protected"
     p2 = lib.getptr(p0, 0)
     assert not lib.in_nursery(p2)
     check_not_free(p2)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to