Author: Remi Meier <remi.me...@inf.ethz.ch>
Branch: c8-private-pages
Changeset: r1534:8c3e4f9f95a9
Date: 2015-01-16 11:42 +0100
http://bitbucket.org/pypy/stmgc/changeset/8c3e4f9f95a9/

Log:    make old allocations happen in the sharing segment, fix not tracing
        them and add a test

diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -151,8 +151,9 @@
 
     if (copy_from_segnum == -1) {
         /* this page is only accessible in the sharing segment so far (new
-           allocation). We can thus simply mark it accessible here and
-           not care about its contents so far. */
+           allocation). We can thus simply mark it accessible here. */
+        pagecopy(get_virtual_page(my_segnum, pagenum),
+                 get_virtual_page(0, pagenum));
         release_all_privatization_locks();
         return;
     }
@@ -287,9 +288,6 @@
             break;
 
         if (first_cl->next == INEV_RUNNING) {
-#if STM_TESTS
-            stm_abort_transaction();
-#endif
             /* need to reach safe point if an INEV transaction
                is waiting for us, otherwise deadlock */
             break;
@@ -473,6 +471,15 @@
 {
     if (!_stm_validate())
         stm_abort_transaction();
+
+#if STM_TESTS
+    if (STM_PSEGMENT->transaction_state != TS_INEVITABLE
+        && STM_PSEGMENT->last_commit_log_entry->next == INEV_RUNNING) {
+        /* abort for tests... */
+        stm_abort_transaction();
+    }
+#endif
+
 }
 
 
@@ -1043,6 +1050,7 @@
             if (i == 0 || (get_page_status_in(i, page) != PAGE_NO_ACCESS)) {
                 /* shared or private, but never segfault */
                 char *dst = REAL_ADDRESS(get_segment_base(i), frag);
+                dprintf(("-> flush %p to seg %lu\n", frag, i));
                 memcpy(dst, src, frag_size);
             }
         }
diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -58,8 +58,13 @@
     if (addr == NULL)
         stm_fatalerror("not enough memory!");
 
-    if (LIKELY(addr + size <= uninitialized_page_start))
+    if (LIKELY(addr + size <= uninitialized_page_start)) {
+        dprintf(("allocate_outside_nursery_large(%lu): %p, page=%lu\n",
+                 size, (char*)(addr - stm_object_pages),
+                 (uintptr_t)(addr - stm_object_pages) / 4096UL));
+
         return (stm_char*)(addr - stm_object_pages);
+    }
 
 
     /* uncommon case: need to initialize some more pages */
@@ -95,9 +100,15 @@
     stm_char *p = allocate_outside_nursery_large(size_rounded_up);
     object_t *o = (object_t *)p;
 
-    memset(get_virtual_address(STM_SEGMENT->segment_num, o), 0, 
size_rounded_up);
+    // sharing seg0 needs to be current:
+    assert(STM_SEGMENT->segment_num == 0);
+    memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0, size_rounded_up);
     o->stm_flags = GCFLAG_WRITE_BARRIER;
 
+    if (testing_prebuilt_objs == NULL)
+        testing_prebuilt_objs = list_create();
+    LIST_APPEND(testing_prebuilt_objs, o);
+
     dprintf(("allocate_old(%lu): %p, seg=%d, page=%lu\n",
              size_rounded_up, p,
              get_segment_of_linear_address(stm_object_pages + (uintptr_t)p),
@@ -374,7 +385,7 @@
 {
     /* this is called by _stm_largemalloc_sweep() */
     object_t *obj = (object_t *)(data - stm_object_pages);
-    //dprintf(("keep obj %p ? -> %d\n", obj, mark_visited_test(obj)));
+    dprintf(("keep obj %p ? -> %d\n", obj, mark_visited_test(obj)));
     if (!mark_visited_test_and_clear(obj)) {
         /* This is actually needed in order to avoid random write-read
            conflicts with objects read and freed long in the past.
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -78,14 +78,16 @@
                 *pobj = pforwarded_array[1];    /* already moved */
                 return;
             }
-            else {
-                /* really has a shadow */
-                nobj = find_existing_shadow(obj);
-                obj->stm_flags &= ~GCFLAG_HAS_SHADOW;
-                realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
-                size = stmcb_size_rounded_up((struct object_s *)realobj);
-                goto copy_large_object;
-            }
+
+            /* really has a shadow */
+            nobj = find_existing_shadow(obj);
+            obj->stm_flags &= ~GCFLAG_HAS_SHADOW;
+            realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
+            size = stmcb_size_rounded_up((struct object_s *)realobj);
+
+            dprintf(("has_shadow(%p): %p, sz:%lu\n",
+                     obj, nobj, size));
+            goto copy_large_object;
         }
 
         realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
@@ -454,6 +456,8 @@
 
     tree_insert(STM_PSEGMENT->nursery_objects_shadows,
                 (uintptr_t)obj, (uintptr_t)nobj);
+
+    dprintf(("allocate_shadow(%p): %p\n", obj, nobj));
     return nobj;
 }
 
diff --git a/c8/stm/pages.c b/c8/stm/pages.c
--- a/c8/stm/pages.c
+++ b/c8/stm/pages.c
@@ -63,7 +63,7 @@
 
 static void page_mark_accessible(long segnum, uintptr_t pagenum)
 {
-    assert(get_page_status_in(segnum, pagenum) == PAGE_NO_ACCESS);
+    assert(segnum==0 || get_page_status_in(segnum, pagenum) == PAGE_NO_ACCESS);
     dprintf(("page_mark_accessible(%lu) in seg:%ld\n", pagenum, segnum));
 
     dprintf(("RW(seg%ld, page%lu)\n", segnum, pagenum));
@@ -82,7 +82,7 @@
 __attribute__((unused))
 static void page_mark_inaccessible(long segnum, uintptr_t pagenum)
 {
-    assert(get_page_status_in(segnum, pagenum) == PAGE_ACCESSIBLE);
+    assert(segnum==0 || get_page_status_in(segnum, pagenum) == 
PAGE_ACCESSIBLE);
     dprintf(("page_mark_inaccessible(%lu) in seg:%ld\n", pagenum, segnum));
 
     set_page_status_in(segnum, pagenum, PAGE_NO_ACCESS);
diff --git a/c8/stm/pages.h b/c8/stm/pages.h
--- a/c8/stm/pages.h
+++ b/c8/stm/pages.h
@@ -63,7 +63,7 @@
 static inline bool get_page_status_in(long segnum, uintptr_t pagenum)
 {
     /* reading page status requires "read"-lock: */
-    assert(STM_PSEGMENT->privatization_lock);
+    assert(STM_SEGMENT->segment_num==0 || STM_PSEGMENT->privatization_lock);
 
     OPT_ASSERT(segnum < 8 * sizeof(struct page_shared_s));
     volatile struct page_shared_s *ps = (volatile struct page_shared_s *)
diff --git a/c8/stm/smallmalloc.c b/c8/stm/smallmalloc.c
--- a/c8/stm/smallmalloc.c
+++ b/c8/stm/smallmalloc.c
@@ -169,6 +169,8 @@
             (_allocate_small_slowpath(size) - stm_object_pages);
 
     *fl = result->next;
+    dprintf(("allocate_outside_nursery_small(%lu): %p\n",
+             size, (char*)((char *)result - stm_object_pages)));
     return (stm_char*)
         ((char *)result - stm_object_pages);
 }
@@ -178,7 +180,9 @@
     stm_char *p = allocate_outside_nursery_small(size_rounded_up);
     object_t *o = (object_t *)p;
 
-    memset(get_virtual_address(STM_SEGMENT->segment_num, o), 0, 
size_rounded_up);
+    // sharing seg0 needs to be current:
+    assert(STM_SEGMENT->segment_num == 0);
+    memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0, size_rounded_up);
     o->stm_flags = GCFLAG_WRITE_BARRIER;
 
     dprintf(("allocate_old_small(%lu): %p, seg=%d, page=%lu\n",
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -497,8 +497,8 @@
         self.tls = [_allocate_thread_local() for i in range(self.NB_THREADS)]
         self.current_thread = 0
         # force-switch back to segment 0 so that when we do something
-        # outside of transactions before the test, it happens in seg0
-        self.switch_to_segment(0)
+        # outside of transactions before the test, it happens in sharing seg0
+        lib._stm_test_switch_segment(-1)
 
     def teardown_method(self, meth):
         lib.stmcb_expand_marker = ffi.NULL
diff --git a/c8/test/test_gcpage.py b/c8/test/test_gcpage.py
--- a/c8/test/test_gcpage.py
+++ b/c8/test/test_gcpage.py
@@ -281,3 +281,11 @@
         p1 = self.pop_root()
         assert stm_get_char(p1) == 'o'
         assert stm_get_char(p2) == 't'
+
+    def test_keepalive_prebuilt(self):
+        stm_allocate_old(64)
+        self.start_transaction()
+        assert lib._stm_total_allocated() == 64 + LMO # large malloc'd
+        stm_major_collect()
+        assert lib._stm_total_allocated() == 64 + LMO # large malloc'd
+        self.commit_transaction()
diff --git a/c8/test/test_random.py b/c8/test/test_random.py
--- a/c8/test/test_random.py
+++ b/c8/test/test_random.py
@@ -11,7 +11,7 @@
         self.executed = []
 
     def do(self, cmd):
-        color = ">> \033[%dm" % (31 + (self.thread_num + 5) % 6)
+        color = ">> \033[%dm" % (31 + (self.thread_num + 6) % 6)
         print >> sys.stderr, color + cmd + "\033[0m"
         self.executed.append(cmd)
         exec cmd in globals(), self.content
@@ -579,7 +579,7 @@
             op_assert_size,
             op_assert_modified,
             op_minor_collect,
-            #op_major_collect,
+            op_major_collect,
         ]
         for _ in range(2000):
             # make sure we are in a transaction:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to