Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r123:171f8b47b009
Date: 2013-06-14 15:18 +0200
http://bitbucket.org/pypy/stmgc/changeset/171f8b47b009/

Log:    Next test

diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -391,14 +391,6 @@
 #endif
 }
 
-gcptr stmgc_duplicate(gcptr P)
-{
-  size_t size = stmcb_size(P);
-  gcptr L = stm_malloc(size);
-  memcpy(L, P, size);
-  return L;
-}
-
 static gcptr LocalizeProtected(struct tx_descriptor *d, gcptr P)
 {
   gcptr B;
@@ -447,6 +439,7 @@
                 0);
   L->h_revision = stm_private_rev_num;
   g2l_insert(&d->public_to_private, R, L);
+  gcptrlist_insert(&d->public_to_young, R);
   fprintf(stderr, "write_barrier: adding %p -> %p to public_to_private\n",
           R, L);
 
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -172,7 +172,6 @@
 gcptr stm_get_private_from_protected(long);  /* debugging */
 gcptr stm_get_read_obj(long);  /* debugging */
 void stm_clear_read_cache(void);  /* debugging */
-gcptr stmgc_duplicate(gcptr);
 
 int DescriptorInit(void);
 void DescriptorDone(void);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -26,13 +26,13 @@
     stm_free(d->nursery_base, GC_NURSERY);
 
     gcptrlist_delete(&d->old_objects_to_trace);
+    gcptrlist_delete(&d->public_to_young);
 }
 
 static char *collect_and_allocate_size(size_t size);  /* forward */
 
-gcptr stm_allocate(size_t size, unsigned long tid)
+inline static char *allocate_nursery(size_t size)
 {
-    /* XXX inline the fast path */
     struct tx_descriptor *d = thread_descriptor;
     char *cur = d->nursery_current;
     char *end = cur + size;
@@ -40,15 +40,47 @@
     if (end > d->nursery_end) {
         cur = collect_and_allocate_size(size);
     }
-    gcptr P = (gcptr)cur;
+    return cur;
+}
+
+gcptr stm_allocate(size_t size, unsigned long tid)
+{
+    /* XXX inline the fast path */
+    gcptr P = (gcptr)allocate_nursery(size);
     assert(tid == (tid & STM_USER_TID_MASK));
     P->h_tid = tid;
     P->h_revision = stm_private_rev_num;
     return P;
 }
 
+gcptr stmgc_duplicate(gcptr P)
+{
+    size_t size = stmcb_size(P);
+    gcptr L = (gcptr)allocate_nursery(size);
+    memcpy(L, P, size);
+    L->h_tid &= ~GCFLAG_OLD;
+    return L;
+}
+
 /************************************************************/
 
+static inline gcptr create_old_object_copy(gcptr obj)
+{
+    assert(!(obj->h_tid & GCFLAG_NURSERY_MOVED));
+    assert(!(obj->h_tid & GCFLAG_VISITED));
+    assert(!(obj->h_tid & GCFLAG_WRITE_BARRIER));
+    assert(!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL));
+    assert(!(obj->h_tid & GCFLAG_OLD));
+
+    size_t size = stmcb_size(obj);
+    gcptr fresh_old_copy = stm_malloc(size);
+    memcpy(fresh_old_copy, obj, size);
+    fresh_old_copy->h_tid |= GCFLAG_OLD;
+
+    fprintf(stderr, "minor: %p is copied to %p\n", obj, fresh_old_copy);
+    return fresh_old_copy;
+}
+
 static void visit_if_young(gcptr *root)
 {
     gcptr obj = *root;
@@ -60,12 +92,8 @@
     }
     else {
         /* a nursery object */
-        assert(!(obj->h_tid & GCFLAG_WRITE_BARRIER));
-        assert(!(obj->h_tid & GCFLAG_OLD));
-        assert(!(obj->h_tid & GCFLAG_PREBUILT_ORIGINAL));
-
         /* make a copy of it outside */
-        fresh_old_copy = stmgc_duplicate(obj);
+        fresh_old_copy = create_old_object_copy(obj);
         obj->h_tid |= GCFLAG_NURSERY_MOVED;
         obj->h_revision = (revision_t)fresh_old_copy;
 
@@ -77,22 +105,40 @@
     }
 }
 
-static void mark_young_roots(gcptr *root, gcptr *end)
+static void mark_young_roots(struct tx_descriptor *d)
 {
+    gcptr *root = d->shadowstack;
+    gcptr *end = *d->shadowstack_end_ref;
+
     /* XXX use a way to avoid walking all roots again and again */
     for (; root != end; root++) {
         visit_if_young(root);
     }
 }
 
+static void mark_public_to_young(struct tx_descriptor *d)
+{
+    long i, size = d->public_to_young.size;
+    gcptr *items = d->public_to_young.items;
+
+    for (i = 0; i < size; i++) {
+        gcptr P = items[i];
+        wlog_t *item;
+
+        G2L_FIND(d->public_to_private, P, item, continue);
+        visit_if_young(&item->val);
+    }
+    gcptrlist_clear(&d->public_to_young);
+}
+
 static void visit_all_outside_objects(struct tx_descriptor *d)
 {
     while (gcptrlist_size(&d->old_objects_to_trace) > 0) {
         gcptr obj = gcptrlist_pop(&d->old_objects_to_trace);
 
-        assert(!(obj->h_tid & GCFLAG_OLD));
+        assert(obj->h_tid & GCFLAG_OLD);
         assert(!(obj->h_tid & GCFLAG_WRITE_BARRIER));
-        obj->h_tid |= GCFLAG_OLD | GCFLAG_WRITE_BARRIER;
+        obj->h_tid |= GCFLAG_WRITE_BARRIER;
 
         stmcb_trace(obj, &visit_if_young);
     }
@@ -123,13 +169,15 @@
     /* acquire the "collection lock" first */
     setup_minor_collect(d);
 
-    mark_young_roots(d->shadowstack, *d->shadowstack_end_ref);
+    mark_young_roots(d);
 
 #if 0
     mark_private_from_protected(d);
+#endif
 
     mark_public_to_young(d);
 
+#if 0
     mark_private_old_pointing_to_young(d);
 #endif
 
diff --git a/c4/nursery.h b/c4/nursery.h
--- a/c4/nursery.h
+++ b/c4/nursery.h
@@ -10,7 +10,8 @@
     char *nursery_current;                              \
     char *nursery_end;                                  \
     char *nursery_base;                                 \
-    struct GcPtrList old_objects_to_trace;
+    struct GcPtrList old_objects_to_trace;              \
+    struct GcPtrList public_to_young;
 
 struct tx_descriptor;  /* from et.h */
 
@@ -18,5 +19,6 @@
 void stmgc_done_nursery(void);
 void stmgc_minor_collect(void);
 int stmgc_minor_collect_anything_to_do(struct tx_descriptor *);
+gcptr stmgc_duplicate(gcptr);
 
 #endif
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -71,6 +71,7 @@
     gcptr stm_get_read_obj(long index);
     void *STUB_THREAD(gcptr);
     void stm_clear_read_cache(void);
+    int in_nursery(gcptr);
 
     gcptr getptr(gcptr, long);
     void setptr(gcptr, long, gcptr);
@@ -183,6 +184,13 @@
         rawsetlong(obj, index, newvalue);
     }
 
+    int in_nursery(gcptr obj)
+    {
+        struct tx_descriptor *d = thread_descriptor;
+        return (d->nursery_base <= (char*)obj &&
+                ((char*)obj) < d->nursery_end);
+    }
+
     gcptr pseudoprebuilt(size_t size, int tid)
     {
         gcptr x = calloc(1, size);
diff --git a/c4/test/test_nursery.py b/c4/test/test_nursery.py
--- a/c4/test/test_nursery.py
+++ b/c4/test/test_nursery.py
@@ -49,3 +49,25 @@
     lib.stm_finalize()
     check_inaccessible(p1)
     lib.stm_initialize_tests(0)
+
+def test_local_copy_out_of_nursery():
+    p1 = palloc(HDR + WORD)
+    lib.rawsetlong(p1, 0, 420063)
+    assert not lib.in_nursery(p1)
+    assert p1.h_revision != lib.get_private_rev_num()
+    #
+    p2 = lib.stm_write_barrier(p1)
+    assert lib.rawgetlong(p2, 0) == 420063
+    lib.rawsetlong(p2, 0, -91467)
+    assert lib.in_nursery(p2)
+    assert p2.h_revision == lib.get_private_rev_num()
+    #
+    lib.stm_push_root(p1)
+    minor_collect()
+    p1b = lib.stm_pop_root()
+    assert p1b == p1
+    assert lib.rawgetlong(p1b, 0) == 420063
+    #
+    p3 = lib.stm_read_barrier(p1)
+    assert not lib.in_nursery(p3) and p3 != p2
+    assert lib.rawgetlong(p3, 0) == -91467
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to