Author: Remi Meier <[email protected]>
Branch: weakref
Changeset: r409:1cf2347f286d
Date: 2013-07-18 14:45 +0200
http://bitbucket.org/pypy/stmgc/changeset/1cf2347f286d/

Log:    implementing immutables and trying to fix the stealing of weakrefs

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -516,8 +516,8 @@
         t = (nodeptr)read_barrier(ptrs[i]);
         w = t->weakref;
         if(w) {
+            assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
             if (w->node) {
-                assert(stm_get_tid((gcptr)w) == GCTID_WEAKREF);
                 check((gcptr)w->node);
                 return (gcptr)w->node;
             }
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -545,6 +545,7 @@
 
 gcptr stm_WriteBarrier(gcptr P)
 {
+  assert(!(P->h_tid & GCFLAG_IMMUTABLE));
   if (is_private(P))
     {
       /* If we have GCFLAG_WRITE_BARRIER in P, then list it into
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -72,6 +72,8 @@
 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;
+static const revision_t GCFLAG_IMMUTABLE              = STM_FIRST_GCFLAG << 11;
+
 
 /* this value must be reflected in PREBUILT_FLAGS in stmgc.h */
 #define GCFLAG_PREBUILT  (GCFLAG_VISITED           | \
@@ -89,6 +91,8 @@
                          "BACKUP_COPY",       \
                          "STUB",              \
                          "PRIVATE_FROM_PROTECTED", \
+                         "HAS_ID", \
+                         "IMMUTABLE", \
                          NULL }
 
 #define IS_POINTER(v)    (!((v) & 1))   /* even-valued number */
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -101,6 +101,13 @@
     return P;
 }
 
+gcptr stm_allocate_immutable(size_t size, unsigned long tid)
+{
+    gcptr P = stm_allocate(size, tid);
+    P->h_tid |= GCFLAG_IMMUTABLE;
+    return P;
+}
+
 gcptr stmgc_duplicate(gcptr P)
 {
     size_t size = stmgc_size(P);
diff --git a/c4/steal.c b/c4/steal.c
--- a/c4/steal.c
+++ b/c4/steal.c
@@ -21,9 +21,47 @@
 {
     gcptr stub, obj = *pobj;
     if (obj == NULL || (obj->h_tid & (GCFLAG_PUBLIC | GCFLAG_OLD)) ==
-                        (GCFLAG_PUBLIC | GCFLAG_OLD))
+                                     (GCFLAG_PUBLIC | GCFLAG_OLD))
         return;
 
+    if (obj->h_tid & GCFLAG_IMMUTABLE) {
+        assert(!(obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
+        /* old or young protected! mark as PUBLIC */
+        if (!(obj->h_tid & GCFLAG_PUBLIC)) {
+            if (!(obj->h_tid & GCFLAG_OLD)) {
+                gcptr O;
+                
+                if (obj->h_tid & GCFLAG_HAS_ID) {
+                    /* use id-copy for us */
+                    O = (gcptr)obj->h_original;
+                    obj->h_tid &= ~GCFLAG_HAS_ID;
+                    stm_copy_to_old_id_copy(obj, O);
+                    O->h_original = 0;
+                } else {
+                    O = stmgc_duplicate_old(obj);
+                    
+                    /* young and without original? */
+                    if (!(obj->h_original))
+                        obj->h_original = (revision_t)O;
+                }
+                obj->h_revision = (revision_t)O;
+                
+                O->h_tid |= GCFLAG_PUBLIC;
+                obj->h_tid |= (GCFLAG_NURSERY_MOVED | GCFLAG_PUBLIC);
+                /* here it is fine if it stays in read caches because
+                   the object is immutable anyway and there are no
+                   write_barriers allowed. */
+
+                dprintf(("steal prot immutable -> public: %p | %p\n", obj, O));
+                stub = obj;
+                goto done;
+            }
+            dprintf(("prot immutable -> public: %p\n", obj));
+            obj->h_tid |= GCFLAG_PUBLIC;
+        }
+        return;
+    }
+    
     /* we use 'all_stubs', a dictionary, in order to try to avoid
        duplicate stubs for the same object.  XXX maybe it would be
        better to use a fast approximative cache that stays around for
diff --git a/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -29,6 +29,9 @@
 
 /* allocate an object out of the local nursery */
 gcptr stm_allocate(size_t size, unsigned long tid);
+/* allocate an object that is be immutable. it cannot be changed with
+   a stm_write_barrier() or after the next commit */
+gcptr stm_allocate_immutable(size_t size, unsigned long tid);
 
 /* returns a never changing hash for the object */
 revision_t stm_hash(gcptr);
diff --git a/c4/weakref.c b/c4/weakref.c
--- a/c4/weakref.c
+++ b/c4/weakref.c
@@ -6,7 +6,7 @@
 gcptr stm_weakref_allocate(size_t size, unsigned long tid, gcptr obj)
 {
     stm_push_root(obj);
-    gcptr weakref = stm_allocate(size, tid);
+    gcptr weakref = stm_allocate_immutable(size, tid);
     obj = stm_pop_root();
     assert(!(weakref->h_tid & GCFLAG_OLD));   /* 'size' too big? */
     assert(stmgc_size(weakref) == size);
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to