[pypy-commit] stmgc copy-over-original: merge default

Raemi noreply at buildbot.pypy.org
Thu Jul 11 10:17:33 CEST 2013


Author: Remi Meier <meierrem at student.ethz.ch>
Branch: copy-over-original
Changeset: r388:dba9439565bd
Date: 2013-07-11 10:14 +0200
http://bitbucket.org/pypy/stmgc/changeset/dba9439565bd/

Log:	merge default

diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -52,6 +52,12 @@
 // global and per-thread-data
 time_t default_seed;
 gcptr shared_roots[SHARED_ROOTS];
+
+#define CACHE_MASK 65535
+#define CACHE_ENTRIES ((CACHE_MASK + 1) / sizeof(char *))
+#define CACHE_AT(cache, obj) (*(gcptr *)((char *)(cache)               \
+                                         + ((revision_t)(obj) & CACHE_MASK)))
+
 struct thread_data {
     unsigned int thread_seed;
     gcptr roots[MAXROOTS];
@@ -61,6 +67,7 @@
     int steps_left;
     int interruptible;
     int atomic;
+    revision_t writeable[CACHE_ENTRIES];
 };
 __thread struct thread_data td;
 
@@ -140,6 +147,7 @@
     }
 }
 
+__thread revision_t temp_cache[CACHE_ENTRIES];
 void pop_roots()
 {
     int i;
@@ -148,6 +156,8 @@
             td.roots[i] = stm_pop_root();
         check(td.roots[i]);
     }
+    /* some objects may have changed positions */
+    memset(td.writeable, 0, sizeof(td.writeable));
 }
 
 void del_root(int idx)
@@ -227,6 +237,7 @@
     if (p != NULL) {
         check(p);
         w = stm_write_barrier(p);
+        CACHE_AT(td.writeable, w) = w;
         check(w);
         assert(is_private(w));
     }
@@ -298,6 +309,8 @@
 void setup_thread()
 {
     int i;
+    memset(&td, 0, sizeof(struct thread_data));
+
     td.thread_seed = default_seed++;
     td.steps_left = STEPS_PER_THREAD;
     td.interruptible = 0;
@@ -395,7 +408,10 @@
         break;
     case 7: // set 'p' as *next in one of the roots
         check(_r);
-        w_r = (nodeptr)write_barrier(_r);
+        if (CACHE_AT(td.writeable, _r) == _r)
+            w_r = (nodeptr)_r;
+        else
+            w_r = (nodeptr)write_barrier(_r);
         check((gcptr)w_r);
         check(p);
         w_r->next = (struct node*)p;
@@ -454,7 +470,10 @@
             assert(w_t->id == stm_id((gcptr)_t));
         }
         else {
-            w_t = (nodeptr)write_barrier(_t);
+            if (CACHE_AT(td.writeable, _t) == _t)
+                w_t = (nodeptr)_t;
+            else
+                w_t = (nodeptr)write_barrier(_t);
             w_t->id = stm_id((gcptr)w_t);
             assert(w_t->id == stm_id((gcptr)_t));
         }
@@ -470,7 +489,10 @@
             assert(w_t->hash == stm_hash((gcptr)_t));
         }
         else {
-            w_t = (nodeptr)write_barrier(_t);
+            if (CACHE_AT(td.writeable, _t) == _t)
+                w_t = (nodeptr)_t;
+            else
+                w_t = (nodeptr)write_barrier(_t);
             w_t->hash = stm_hash((gcptr)w_t);
             assert(w_t->hash == stm_hash((gcptr)_t));
         }
@@ -538,6 +560,8 @@
     
     td.interruptible = 0;
     pop_roots();
+
+    memset(&td.writeable, 0, sizeof(td.writeable));
 }
 
 
@@ -558,6 +582,7 @@
     stm_push_root(end_marker);
 
     int p = run_me();
+
     if (p == -1) // maybe restart transaction
         return get_rand(3) != 1;
 
@@ -567,6 +592,10 @@
 int run_me()
 {
     gcptr p = NULL;
+
+    // clear cache of writeables:
+    memset(&td.writeable, 0, sizeof(td.writeable));
+
     while (td.steps_left-->0 || td.atomic) {
         if (td.steps_left % 8 == 0)
             fprintf(stdout, "#");
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -207,8 +207,8 @@
                                    (revision_t)END_MARKER_ON)) {
             /* 'item' is a regular, non-null pointer */
             visit_if_young(end);
-            
-            /* if old, private or protected, this object needs to be
+            item = *end;
+            /* if private or protected, this object needs to be
                traced again in the next minor_collect if it is
                currently in old_objects_to_trace. Because then
                it may be seen as write-ready in the view of
@@ -216,7 +216,7 @@
                pw = write_barrier(); push_root(pw);
                minor_collect(); pw = pop_root(); // pw still write-ready
             */
-            if (item && item->h_tid & GCFLAG_OLD
+            if (item
                 && !(item->h_tid & GCFLAG_WRITE_BARRIER) /* not set in
                                                           obj_to_trace*/
                 && (item->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED
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
@@ -250,6 +250,25 @@
     assert getptr(pr, 0) == q
     assert getptr(pr, 0) != q2
 
+def test_write_barrier_after_minor_collect_young_to_old():
+    p = nalloc_refs(1)
+    pw = lib.stm_write_barrier(p)
+
+    lib.stm_push_root(pw)
+    minor_collect()
+    r = nalloc(HDR)
+    pw = lib.stm_pop_root()
+
+    check_nursery_free(p)
+    assert pw.h_tid & GCFLAG_OLD
+    rawsetptr(pw, 0, r)
+    
+    lib.stm_push_root(pw)
+    minor_collect()
+    pw = lib.stm_pop_root()
+    check_nursery_free(r)
+
+    assert getptr(pw, 0) != r
 
 def test_id_young_to_old():
     # move out of nursery with shadow original


More information about the pypy-commit mailing list