[pypy-commit] stmgc c7-more-segments: in-progress

arigo noreply at buildbot.pypy.org
Sun Mar 16 09:46:32 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: c7-more-segments
Changeset: r1028:c06abb7b21ca
Date: 2014-03-16 09:46 +0100
http://bitbucket.org/pypy/stmgc/changeset/c06abb7b21ca/

Log:	in-progress

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -238,26 +238,30 @@
     return false;
 }
 
-static void synchronize_overflow_object_now(object_t *obj)
+static void synchronize_object_now(object_t *obj, bool assume_local_private)
 {
-    abort();//XXX
-#if 0
+    /* Copy around the version of 'obj' that lives in our own segment.
+       It is first copied into the shared pages, and then into other
+       segments' own private pages.
+    */
     assert(!_is_young(obj));
-    assert((obj->stm_flags & GCFLAG_SMALL_UNIFORM) == 0);
     assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
 
-    char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
-    ssize_t obj_size = stmcb_size_rounded_up((struct object_s *)realobj);
-    assert(obj_size >= 16);
     uintptr_t start = (uintptr_t)obj;
-    uintptr_t end = start + obj_size;
     uintptr_t first_page = start / 4096UL;
-    uintptr_t last_page = (end - 1) / 4096UL;
 
-    do {
-        if (flag_page_private[first_page] != SHARED_PAGE) {
-            /* The page is a PRIVATE_PAGE.  We need to diffuse this fragment
-               of our object from our own segment to all other segments. */
+    if (obj->stm_flags & GCFLAG_SMALL_UNIFORM) {
+        abort();//XXX WRITE THE FAST CASE
+    }
+    else {
+        char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
+        ssize_t obj_size = stmcb_size_rounded_up((struct object_s *)realobj);
+        assert(obj_size >= 16);
+        uintptr_t end = start + obj_size;
+        uintptr_t last_page = (end - 1) / 4096UL;
+        long i, myself = STM_SEGMENT->segment_num;
+
+        for (; first_page <= last_page; first_page++) {
 
             uintptr_t copy_size;
             if (first_page == last_page) {
@@ -265,86 +269,44 @@
                 copy_size = end - start;
             }
             else {
-                /* this is a non-final fragment, going up to the page's end */
+                /* this is a non-final fragment, going up to the
+                   page's end */
                 copy_size = 4096 - (start & 4095);
             }
-
             /* double-check that the result fits in one page */
             assert(copy_size > 0);
             assert(copy_size + (start & 4095) <= 4096);
 
-            long i;
-            char *src = REAL_ADDRESS(STM_SEGMENT->segment_base, start);
-            for (i = 0; i < NB_SEGMENTS; i++) {
-                abort();//XXX
-                if (i != STM_SEGMENT->segment_num) {
-                    char *dst = REAL_ADDRESS(get_segment_base(i), start);
+            /* First copy the object into the shared page, if needed */
+            assert(IMPLY(assume_local_private,
+                         is_private_page(myself, first_page)));
+
+            if (assume_local_private || is_private_page(myself, first_page)) {
+                char *src = REAL_ADDRESS(STM_SEGMENT->segment_base, start);
+                char *dst = REAL_ADDRESS(stm_object_pages, start);
+                if (copy_size == 4096)
+                    pagecopy(dst, src);
+                else
                     memcpy(dst, src, copy_size);
-                }
             }
-        }
-
-        start = (start + 4096) & ~4095;
-    } while (first_page++ < last_page);
-#endif
-}
-
-static void synchronize_object_now(object_t *obj)
-{
-    /* Assume that the version of 'obj' in the shared pages is up-to-date.
-       Assume also that the version in our own private page is up-to-date.
-       This function updates the private page of other threads.
-    */
-    assert(!_is_young(obj));
-    assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
-
-    uintptr_t start = (uintptr_t)obj;
-    uintptr_t first_page = start / 4096UL;
-    long i;
-
-    if (obj->stm_flags & GCFLAG_SMALL_UNIFORM) {
-        abort();//XXX WRITE THE FAST CASE
-    }
-    else {
-        char *realobj = REAL_ADDRESS(stm_object_pages, obj);
-        ssize_t obj_size = stmcb_size_rounded_up((struct object_s *)realobj);
-        assert(obj_size >= 16);
-        uintptr_t end = start + obj_size;
-        uintptr_t last_page = (end - 1) / 4096UL;
-
-        for (; first_page <= last_page; first_page++) {
 
             for (i = 1; i < NB_SEGMENTS; i++) {
-
-                if (i == STM_SEGMENT->segment_num)
+                if (i == myself)
                     continue;
-
                 if (!is_private_page(i, first_page))
                     continue;
 
-                /* The page is a PRIVATE_PAGE.  We need to diffuse this
+                /* The page is a private page.  We need to diffuse this
                    fragment of object from the shared page to this private
                    page. */
-
-                uintptr_t copy_size;
-                if (first_page == last_page) {
-                    /* this is the final fragment */
-                    copy_size = end - start;
-                }
-                else {
-                    /* this is a non-final fragment, going up to the
-                       page's end */
-                    copy_size = 4096 - (start & 4095);
-                }
-
-                /* double-check that the result fits in one page */
-                assert(copy_size > 0);
-                assert(copy_size + (start & 4095) <= 4096);
-
                 char *src = REAL_ADDRESS(stm_object_pages, start);
                 char *dst = REAL_ADDRESS(get_segment_base(i), start);
-                memcpy(dst, src, copy_size);
+                if (copy_size == 4096)
+                    pagecopy(dst, src);
+                else
+                    memcpy(dst, src, copy_size);
             }
+
             start = (start + 4096) & ~4095;
         }
     }
@@ -356,13 +318,11 @@
         return;
 
     LIST_FOREACH_R(STM_PSEGMENT->large_overflow_objects, object_t *,
-                   synchronize_overflow_object_now(item));
+                   synchronize_object_now(item, false));
 }
 
 static void push_modified_to_other_segments(void)
 {
-    char *local_base = STM_SEGMENT->segment_base;
-
     LIST_FOREACH_R(
         STM_PSEGMENT->modified_old_objects,
         object_t * /*item*/,
@@ -378,14 +338,8 @@
                minor_collection() */
             assert((item->stm_flags & GCFLAG_WRITE_BARRIER) != 0);
 
-            /* copy the modified object to the shared copy */
-            char *src = REAL_ADDRESS(local_base, item);
-            char *dst = REAL_ADDRESS(stm_object_pages, item);
-            ssize_t size = stmcb_size_rounded_up((struct object_s *)src);
-            memcpy(dst, src, size);
-
             /* copy the object to the other private pages as needed */
-            synchronize_object_now(item);
+            synchronize_object_now(item, true);
         }));
 
     list_clear(STM_PSEGMENT->modified_old_objects);
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -231,4 +231,4 @@
     asm("/* workaround for llvm bug */");
 }
 
-static void synchronize_overflow_object_now(object_t *obj);
+static void synchronize_object_now(object_t *obj, bool assume_local_private);
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -199,7 +199,7 @@
                content); or add the object to 'large_overflow_objects'.
             */
             if (STM_PSEGMENT->minor_collect_will_commit_now)
-                synchronize_overflow_object_now(obj);
+                synchronize_object_now(obj, false);
             else
                 LIST_APPEND(STM_PSEGMENT->large_overflow_objects, obj);
         }


More information about the pypy-commit mailing list