Author: Remi Meier <meier...@student.ethz.ch>
Branch: implement-id
Changeset: r216:04f0776e142a
Date: 2013-06-20 16:51 +0200
http://bitbucket.org/pypy/stmgc/changeset/04f0776e142a/

Log:    work in progress

diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -57,6 +57,9 @@
  * but converted from a protected.  These are precisely the objects
  * that have a backup copy (in h_revision), which gives a copy of the
  * original protected object.
+ * 
+ * GCFLAG_HAS_ID is set on young objects that have an old reserved
+ * memory to be copied to in minor collections (obj->h_original)
  */
 static const revision_t GCFLAG_OLD                    = STM_FIRST_GCFLAG << 0;
 static const revision_t GCFLAG_VISITED                = STM_FIRST_GCFLAG << 1;
@@ -68,6 +71,7 @@
 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;
+static const revision_t GCFLAG_HAS_ID                 = STM_FIRST_GCFLAG << 10;
 
 /* this value must be reflected in PREBUILT_FLAGS in stmgc.h */
 #define GCFLAG_PREBUILT  (GCFLAG_VISITED           | \
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -59,6 +59,7 @@
     assert(tid == (tid & STM_USER_TID_MASK));
     P->h_tid = tid;
     P->h_revision = stm_private_rev_num;
+    P->h_original = NULL;
     return P;
 }
 
@@ -71,6 +72,13 @@
 
     memcpy(L, P, size);
     L->h_tid &= ~GCFLAG_OLD;
+    L->h_tid &= ~GCFLAG_HAS_ID;
+
+    if (P->h_original)
+        L->h_original = P->h_original;
+    else
+        L->h_original = P;
+
     return L;
 }
 
@@ -80,11 +88,64 @@
     gcptr L = (gcptr)stmgcpage_malloc(size);
     memcpy(L, P, size);
     L->h_tid |= GCFLAG_OLD;
+    L->h_tid &= ~GCFLAG_HAS_ID;
+
+    if (P->h_original)
+        L->h_original = P->h_original;
+    else
+        L->h_original = P;
+
     return L;
 }
 
 /************************************************************/
 
+
+revision_t stm_hash(gcptr p)
+{
+    return stm_id(p);
+}
+
+revision_t stm_id(gcptr p)
+{
+    if (p->h_original) {
+        return p->h_original;
+    }
+    
+    //p->h_original == NULL
+    if (!(p->h_tid & GCFLAG_OLD)) {//(is_in_nursery(p)) {
+        // preallocate old "original" outside
+        // like stealing
+        gcptr O = stmgc_duplicate_old(L);
+        L->h_revision = (revision_t)O;
+        L->h_original = O;
+        L->h_tid |= GCFLAG_HAS_ID;
+        
+        
+        // could be stolen
+        if (p->h_tid & GCFLAG_NURSERY_MOVED) {
+            
+        }
+    }
+    else if (p->h_tid & GCFLAG_NURSERY_MOVED) {
+        if (p->h_tid & GCFLAG_PUBLIC) {
+            // moved by stealing
+            
+        }
+       
+    }
+    else {
+        assert(0);
+    }
+}
+
+revision_t stm_pointer_equal(gcptr p1, gcptr p2)
+{
+    return stm_id(p1) == stm_id(p2);
+}
+
+/************************************************************/
+
 static inline gcptr create_old_object_copy(gcptr obj)
 {
     assert(!(obj->h_tid & GCFLAG_PUBLIC));
@@ -100,6 +161,13 @@
     return fresh_old_copy;
 }
 
+static inline void copy_to_old_id_copy(gcptr obj, gcptr id)
+{
+    size_t size = stmcb_size(obj);
+    memcpy(id, obj, size);
+    id->h_tid &= ~GCFLAG_HAS_ID;
+}
+
 static void visit_if_young(gcptr *root)
 {
     gcptr obj = *root;
@@ -111,17 +179,25 @@
     }
     else {
         /* it's a nursery object.  Was it already moved? */
-
         if (UNLIKELY(obj->h_tid & GCFLAG_NURSERY_MOVED)) {
             /* yes.  Such an object can be a public object in the nursery
                too (such objects are always NURSERY_MOVED).  For all cases,
-               we can just fix the ref. */
+               we can just fix the ref. 
+               Can be stolen objects or those we already moved.
+            */
             *root = (gcptr)obj->h_revision;
             return;
         }
 
-        /* make a copy of it outside */
-        fresh_old_copy = create_old_object_copy(obj);
+        if (obj->h_tid & GCFLAG_HAS_ID) {
+            /* already has a place to go to */
+            fresh_old_copy = copy_to_old_id_copy(obj, obj->h_original);
+        } 
+        else {
+            /* make a copy of it outside */
+            fresh_old_copy = create_old_object_copy(obj);
+        }
+        
         obj->h_tid |= GCFLAG_NURSERY_MOVED;
         obj->h_revision = (revision_t)fresh_old_copy;
 
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -149,10 +149,20 @@
 
         fprintf(stderr, "stolen: %p -> %p\n", P, L);
 
-        /* Copy the object out of the other thread's nursery, if needed */
-        if (!(L->h_tid & GCFLAG_OLD)) {
-            gcptr O = stmgc_duplicate_old(L);
-            L->h_revision = (revision_t)O;
+        if (!(L->h_tid & GCFLAG_OLD)) { 
+            gcptr O;
+            if (L->h_tid & GCFLAG_HAS_ID) {
+                L->h_tid &= ~GCFLAG_HAS_ID;
+                L->h_revision = (revision_t)L->h_original;
+                copy_to_old_id_copy(L, L->h_original);
+                O = L->h_original;
+            } else {
+                /* Copy the object out of the other thread's nursery, 
+                   if needed */
+                O = stmgc_duplicate_old(L);
+                L->h_revision = (revision_t)O;
+                L->h_original = 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.
diff --git a/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -10,6 +10,7 @@
 typedef struct stm_object_s {
     revision_t h_tid;
     revision_t h_revision;
+    gcptr h_original;
 } *gcptr;
 
 
@@ -28,6 +29,14 @@
 /* allocate an object out of the local nursery */
 gcptr stm_allocate(size_t size, unsigned long tid);
 
+/* returns a never changing hash for the object */
+revision_t stm_hash(gcptr);
+/* returns an for the object which is unique during its lifetime */
+revision_t stm_id(gcptr);
+/* returns nonzero if the two object-copy pointers belong to the
+same original object */
+revision_t stm_pointer_equal(gcptr, gcptr);
+
 /* to push/pop objects into the local shadowstack */
 /* (could be turned into macros or something later) */
 void stm_push_root(gcptr);
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to