Author: Remi Meier <[email protected]>
Branch: stmgc-c4
Changeset: r68245:6c38f0067571
Date: 2013-11-19 17:16 +0100
http://bitbucket.org/pypy/pypy/changeset/6c38f0067571/

Log:    import stmgc

diff --git a/rpython/translator/stm/src_stm/et.c 
b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -184,7 +184,8 @@
               if (v & 2)
                 goto follow_stub;
 
-              /* we update P_prev->h_revision as a shortcut */
+              /* we update P_prev->h_revision as a shortcut
+                 P_prev->P->v  =>  P_prev->v */
               /* XXX check if this really gives a worse performance than only
                  doing this write occasionally based on a counter in d */
               P_prev->h_revision = v;
@@ -577,6 +578,7 @@
   B = stmgc_duplicate_old(P);
   B->h_tid |= GCFLAG_BACKUP_COPY;
   B->h_tid &= ~GCFLAG_HAS_ID;
+
   if (!(P->h_original) && (P->h_tid & GCFLAG_OLD)) {
     /* if P is old, it must be the original
        if P is young, it will create a shadow original later
diff --git a/rpython/translator/stm/src_stm/extra.c 
b/rpython/translator/stm/src_stm/extra.c
--- a/rpython/translator/stm/src_stm/extra.c
+++ b/rpython/translator/stm/src_stm/extra.c
@@ -90,21 +90,30 @@
     }
     assert(obj->h_tid & GCFLAG_OLD);
 
+    if (stm_is_registered(obj)) {
+        /* prevents stub->stub->stub->... */
+        /* only increment refcount: */
+        stm_register_integer_address((intptr_t)obj);
+        return (intptr_t)obj;
+    }
+
     spinlock_acquire(d->public_descriptor->collection_lock, 'P');
 
     /* it must have a h_original */
     gcptr orig;
-    if (obj->h_original == 0 || obj->h_tid & GCFLAG_PREBUILT_ORIGINAL) {
+    if ((!obj->h_original) || (obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)) {
         orig = obj;
     } else {
         orig = (gcptr)obj->h_original;
     }
     
-    if ((orig->h_tid & (GCFLAG_PUBLIC | GCFLAG_PREBUILT_ORIGINAL))
-        == (GCFLAG_PUBLIC | GCFLAG_PREBUILT_ORIGINAL)) {
-        /* public is not enough as public stubs may get replaced
-           by the protected object they point to, if they are in the 
-           same thread (I think...) */
+    if ((orig->h_tid & GCFLAG_PUBLIC) 
+        && (obj->h_tid & GCFLAG_PREBUILT_ORIGINAL)) {
+        /* we can't just use *any* public original because their
+           h_revision is not kept up-to-date during major collections.
+           Meaning it can point to some long gone object.
+           Prebuilt originals, however, always get visited in major
+           collections. */
         result = (intptr_t)orig;
     }
     else {
@@ -234,10 +243,11 @@
         /* must create shadow original object XXX: or use
            backup, if exists */
         gcptr O = (gcptr)stmgcpage_malloc(stmgc_size(p));
-        memcpy(O, p, stmgc_size(p)); /* at least major collections
-                                      depend on some content of id_copy.
-                                      remove after fixing that XXX */
+        memcpy(O, p, sizeof(struct stm_object_s));
+
         O->h_tid |= GCFLAG_OLD;
+        assert(O->h_original == 0);
+        assert(O->h_revision = -1);     /* debugging */
 
         p->h_original = (revision_t)O;
         p->h_tid |= GCFLAG_HAS_ID;
@@ -246,6 +256,7 @@
             gcptr B = (gcptr)p->h_revision;
             /* not stolen already: */
             assert(!(B->h_tid & GCFLAG_PUBLIC));
+            assert(!B->h_original);
             B->h_original = (revision_t)O;
         }
         
diff --git a/rpython/translator/stm/src_stm/gcpage.c 
b/rpython/translator/stm/src_stm/gcpage.c
--- a/rpython/translator/stm/src_stm/gcpage.c
+++ b/rpython/translator/stm/src_stm/gcpage.c
@@ -38,6 +38,13 @@
     }
 }
 
+static void check_consistent(gcptr obj) {
+    if ((obj->h_revision & 3) == 2)
+        assert(stm_pointer_equal(obj, (gcptr)(obj->h_revision-2)));
+    else if ((obj->h_revision & 1) == 0)
+        assert(stm_pointer_equal(obj, (gcptr)(obj->h_revision)));
+}
+
 
 /***** Support code *****/
 
@@ -218,6 +225,22 @@
 
 /***** registering of small stubs as integer addresses *****/
 
+_Bool stm_is_registered(gcptr obj)
+{
+    wlog_t *found;
+    _Bool res = 0;
+
+    stmgcpage_acquire_global_lock();
+    /* find and increment refcount; or insert */
+    G2L_FIND(registered_objs, obj, found, goto finish);
+    found->val = (gcptr)(((revision_t)found->val) + 1);
+    goto finish;
+    res = 1;
+ finish:
+    stmgcpage_release_global_lock();
+    return res;
+}
+
 void stm_register_integer_address(intptr_t adr)
 {                               /* needs to be inevitable! */
     wlog_t *found;
@@ -254,6 +277,7 @@
     /* become inevitable because we would have to re-register them
        on abort, but make sure only to re-register if not registered
        in the same aborted transaction (XXX) */
+    /* (obj will not move) */
     stm_become_inevitable("stm_unregister_integer_address()");
 
     stmgcpage_acquire_global_lock();
@@ -280,6 +304,10 @@
 
 static gcptr copy_over_original(gcptr obj, gcptr id_copy)
 {
+    /* no obj->h_revision = obj->h_original = id_copy */
+    assert(!((obj->h_revision <= ((revision_t)id_copy + 2)) && 
+             (obj->h_revision >= ((revision_t)id_copy))));
+
     assert(obj != id_copy);
     assert(id_copy == (gcptr)obj->h_original);
     assert(!(id_copy->h_revision & 1)); /* not head-revision itself */
@@ -541,11 +569,6 @@
                    == (GCFLAG_MARKED|GCFLAG_VISITED|GCFLAG_PUBLIC));
             continue;
         }
-        /* else if (R->h_original == 0) { */
-        /*     /\* the obj is an original and will therefore survive: *\/ */
-        /*     gcptr V = visit_public(R, NULL); */
-        /*     assert(V == R); */
-        /* } */
         else {
             assert(R->h_tid & GCFLAG_SMALLSTUB); /* only case for now */
             /* make sure R stays valid: */
diff --git a/rpython/translator/stm/src_stm/nursery.c 
b/rpython/translator/stm/src_stm/nursery.c
--- a/rpython/translator/stm/src_stm/nursery.c
+++ b/rpython/translator/stm/src_stm/nursery.c
@@ -187,6 +187,9 @@
 
             /* priv_from_prot's backup->h_originals already point
                to id_obj */
+            assert(IMPLIES(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED,
+                           ((gcptr)obj->h_revision)->h_original
+                           == obj->h_original));
         } 
         else {
             /* make a copy of it outside */
diff --git a/rpython/translator/stm/src_stm/revision 
b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-68677625f2be
+b89b61f0df98
diff --git a/rpython/translator/stm/src_stm/steal.c 
b/rpython/translator/stm/src_stm/steal.c
--- a/rpython/translator/stm/src_stm/steal.c
+++ b/rpython/translator/stm/src_stm/steal.c
@@ -84,6 +84,7 @@
         obj->h_original = (revision_t)stub; 
         stub->h_original = 0;   /* stub_malloc does not set to 0... */
         if (obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
+            assert(!(((gcptr)obj->h_revision)->h_original));
             ((gcptr)obj->h_revision)->h_original = (revision_t)stub;
         }
     }
diff --git a/rpython/translator/stm/src_stm/stmgc.h 
b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -42,7 +42,7 @@
    called on the result (push roots!) */
 intptr_t stm_allocate_public_integer_address(gcptr);
 void stm_unregister_integer_address(intptr_t); /* push roots too! */
-
+_Bool stm_is_registered(gcptr);
 
 /* returns a never changing hash for the object */
 revision_t stm_hash(gcptr);
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to