Author: Remi Meier <remi.me...@inf.ethz.ch>
Branch: c8-new-page-handling
Changeset: r1428:3587e00868fd
Date: 2014-09-26 13:56 +0200
http://bitbucket.org/pypy/stmgc/changeset/3587e00868fd/

Log:    do multi-page slicing

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -32,11 +32,13 @@
                 continue;
         }
 
+        dprintf(("import slice obj=%p off=%lu pg=%lu\n",
+                 obj, SLICE_OFFSET(undo->slice), current_page_num));
         char *src, *dst;
         if (src_segment_base != NULL)
             src = REAL_ADDRESS(src_segment_base, oslice);
         else
-            src = undo->backup;
+            src = undo->backup + SLICE_OFFSET(undo->slice);
         dst = REAL_ADDRESS(STM_SEGMENT->segment_base, oslice);
         memcpy(dst, src, SLICE_SIZE(undo->slice));
     }
@@ -469,19 +471,33 @@
        if 'obj' is merely an overflow object.  FIX ME, likely by copying
        the overflow number logic from c7. */
 
-    assert(first_page == end_page);  /* XXX! */
-    /* XXX do the case where first_page != end_page in pieces.  Maybe also
-       use mprotect() again to mark pages of the object as read-only, and
-       only stick it into modified_old_objects page-by-page?  Maybe it's
-       possible to do card-marking that way, too. */
+    acquire_modified_objs_lock(STM_SEGMENT->segment_num);
+    uintptr_t slice_sz;
+    uintptr_t in_page_offset = (uintptr_t)obj % 4096UL;
+    uintptr_t remaining_obj_sz = obj_size;
+    for (page = first_page; page <= end_page; page++) {
+        /* XXX Maybe also use mprotect() again to mark pages of the object as 
read-only, and
+           only stick it into modified_old_objects page-by-page?  Maybe it's
+           possible to do card-marking that way, too. */
+        OPT_ASSERT(remaining_obj_sz);
 
-    uintptr_t slice = obj_size;
-    assert(SLICE_OFFSET(slice) == 0 && SLICE_SIZE(slice) == obj_size);
+        slice_sz = remaining_obj_sz;
+        if (in_page_offset + slice_sz > 4096UL) {
+            /* not over page boundaries */
+            slice_sz = 4096UL - in_page_offset;
+        }
 
-    acquire_modified_objs_lock(STM_SEGMENT->segment_num);
-    STM_PSEGMENT->modified_old_objects = list_append3(
-        STM_PSEGMENT->modified_old_objects,
-        (uintptr_t)obj, (uintptr_t)bk_obj, slice);
+        STM_PSEGMENT->modified_old_objects = list_append3(
+            STM_PSEGMENT->modified_old_objects,
+            (uintptr_t)obj,     /* obj */
+            (uintptr_t)bk_obj,  /* bk_addr */
+            NEW_SLICE(obj_size - remaining_obj_sz, slice_sz));
+
+        remaining_obj_sz -= slice_sz;
+        in_page_offset = (in_page_offset + slice_sz) % 4096UL; /* mostly 0 */
+    }
+    OPT_ASSERT(remaining_obj_sz == 0);
+
     release_modified_objs_lock(STM_SEGMENT->segment_num);
 
     /* done fiddling with protection and privatization */
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -108,6 +108,7 @@
 };
 #define SLICE_OFFSET(slice)  ((slice) >> 16)
 #define SLICE_SIZE(slice)    ((int)((slice) & 0xFFFF))
+#define NEW_SLICE(offset, size) (((uint64_t)(offset)) << 16 | (size))
 
 /* The model is: we have a global chained list, from 'commit_log_root',
    of 'struct stm_commit_log_entry_s' entries.  Every one is fully
diff --git a/c8/test/test_basic.py b/c8/test/test_basic.py
--- a/c8/test/test_basic.py
+++ b/c8/test/test_basic.py
@@ -733,6 +733,7 @@
         assert self.get_stm_thread_local().last_abort__bytes_in_nursery == 0
 
     def test_abort_in_segfault_handler(self):
+        py.test.skip("not doing that anymore")
         lp1 = stm_allocate_old(16)
         lp2 = stm_allocate_old(16)
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to