Author: Remi Meier <[email protected]>
Branch: 
Changeset: r248:78c58b8aabfa
Date: 2013-06-24 09:10 +0200
http://bitbucket.org/pypy/stmgc/changeset/78c58b8aabfa/

Log:    add some comments; add hash_mangling

diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -88,13 +88,45 @@
 }
 
 /************************************************************/
-
+/* Each object has a h_original pointer to an old copy of 
+   the same object (e.g. an old revision), the "original". 
+   The memory location of this old object is used as the ID 
+   for this object. If h_original is NULL *and* it is an
+   old object copy, it itself is the original. This invariant
+   must be upheld by all code dealing with h_original.
+   The original copy must never be moved again. Also, it may
+   be just a stub-object.
+   
+   If we want the ID of an object which is still young,
+   we must preallocate an old shadow-original that is used
+   as the target of the young object in a minor collection.
+   In this case, we set the HAS_ID flag on the young obj
+   to notify minor_collect.
+   This flag can be lost if the young obj is stolen. Then
+   the stealing thread uses the shadow-original itself and
+   minor_collect must not overwrite it again.
+   Also, if there is already a backup-copy around, we use
+   this instead of allocating another old object to use as 
+   the shadow-original.
+ */
 
 revision_t stm_hash(gcptr p)
 {
     return stm_id(p);
 }
 
+
+static revision_t mangle_hash(revision_t n)
+{
+    /* To hash pointers in dictionaries.  Assumes that i shows some
+       alignment (to 4, 8, maybe 16 bytes), so we use the following
+       formula to avoid the trailing bits being always 0.
+       This formula is reversible: two different values of 'i' will
+       always give two different results.
+    */
+    return n ^ (n >> 4);
+}
+
 revision_t stm_id(gcptr p)
 {
     struct tx_descriptor *d = thread_descriptor;
@@ -104,15 +136,23 @@
     if (p->h_original) { /* fast path */
         fprintf(stderr, "stm_id(%p) has orig fst: %p\n", 
                 p, (gcptr)p->h_original);
-        return p->h_original;
+        return mangle_hash(p->h_original);
     } 
     else if (!(p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
                && (p->h_tid & GCFLAG_OLD)) {
         /* we can be sure that p->h_original doesn't
-           get set during the if and the else-if */
+           get set during the if and the else-if 
+           
+           XXX: check for priv_from_protected may not be 
+           necessary. only if this func may be called on 
+           another thread's young objects that are made 
+           old at the same time, and we see the OLD flag 
+           before h_original has been set.
+        */
         fprintf(stderr, "stm_id(%p) is old, orig=0 fst: %p\n", p, p);
-        return (revision_t)p;
+        return mangle_hash((revision_t)p);
     }
+
     
     spinlock_acquire(d->public_descriptor->collection_lock, 'I');
     /* old objects must have an h_original xOR be
@@ -137,7 +177,6 @@
         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
             
@@ -157,7 +196,7 @@
     }
     
     spinlock_release(d->public_descriptor->collection_lock);
-    return result;
+    return mangle_hash(result);
 }
 
 revision_t stm_pointer_equal(gcptr p1, gcptr p2)
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -93,7 +93,6 @@
             assert(!(L->h_tid & GCFLAG_HAS_ID));
             /* original must be L */
             B->h_original = (revision_t)L;
-            assert(0);
         }
         else {
             /* we can make the backup the "original"
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
@@ -216,12 +216,10 @@
 def test_id_private_from_protected():
     # read and write from protected
     p = oalloc(HDR)
-    pid = lib.stm_id(p)
     porig = follow_original(p)
     # impl detail {
     # old objects have id==itself, if not set differently
     assert porig == ffi.NULL
-    assert ffi.cast("gcptr", pid) == p
     # }
 
     p1 = oalloc(HDR)
@@ -237,7 +235,6 @@
     assert p2id == lib.stm_id(p2w)
     # impl detail {
     assert p2w.h_original == 0
-    assert follow_revision(p2w).h_original == lib.stm_id(p2w)
     # }
     
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to