[pypy-commit] stmgc c7-weakref: some cleanup

Remi Meier noreply at buildbot.pypy.org
Thu Mar 13 09:27:22 CET 2014


Author: Remi Meier
Branch: c7-weakref
Changeset: r991:0679cfa51e66
Date: 2014-03-13 09:26 +0100
http://bitbucket.org/pypy/stmgc/changeset/0679cfa51e66/

Log:	some cleanup

diff --git a/c7/stm/weakref.c b/c7/stm/weakref.c
--- a/c7/stm/weakref.c
+++ b/c7/stm/weakref.c
@@ -8,13 +8,31 @@
     OPT_ASSERT(size_rounded_up > sizeof(struct object_s));
     object_t *obj = stm_allocate(size_rounded_up);
 
-    assert(_is_in_nursery(obj)); /* see assert(0) which depends on it */
-
     LIST_APPEND(STM_PSEGMENT->young_weakrefs, obj);
     return obj;
 }
 
 
+void _set_weakref_in_all_segments(object_t *weakref, object_t *value)
+{
+    char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, weakref);
+    ssize_t size = stmcb_size_rounded_up((struct object_s *)realobj);
+
+    stm_char *point_to_loc = (stm_char*)WEAKREF_PTR(weakref, size);
+    if (flag_page_private[(uintptr_t)point_to_loc / 4096UL] == PRIVATE_PAGE) {
+        long i;
+        for (i = 0; i < NB_SEGMENTS; i++) {
+            char *base = get_segment_base(i);   /* two different segments */
+
+            object_t ** ref_loc = (object_t **)REAL_ADDRESS(base, point_to_loc);
+            *ref_loc = value;
+        }
+    }
+    else {
+        *WEAKREF_PTR(weakref, size) = value;
+    }
+}
+
 /***** Minor collection *****/
 
 void stm_move_young_weakrefs()
@@ -40,16 +58,13 @@
                 item = pforwarded_array[1]; /* moved location */
             }
             else {
-                /* tell me if we need this (requires synchronizing in case
-                   of private pages) */
-                assert(0);
-                /* /\* young outside nursery object *\/ */
-                /* if (tree_contains(STM_PSEGMENT->young_outside_nursery, */
-                /*                   (uintptr_t)item)) { */
-                /*     /\* still in the tree -> wasn't seen by the minor collection, */
-                /*        so it doesn't survive *\/ */
-                /*     continue; */
-                /* } */
+                /* young outside nursery object */
+                if (tree_contains(STM_PSEGMENT->young_outside_nursery,
+                                  (uintptr_t)item)) {
+                    /* still in the tree -> wasn't seen by the minor collection,
+                       so it doesn't survive */
+                    continue;
+                }
             }
             assert(!_is_young(item));
 
@@ -64,14 +79,12 @@
                 if (!(pointing_to->stm_flags & GCFLAG_HAS_SHADOW)
                     || (pforwarded_array[0] != GCWORD_MOVED)) {
                     /* pointing_to dies */
-                    *WEAKREF_PTR(item, size) = NULL;
-                    synchronize_overflow_object_now(item);
+                    _set_weakref_in_all_segments(item, NULL);
                     continue;   /* no need to remember in old_weakrefs */
                 }
                 else {
                     /* moved location */
-                    *WEAKREF_PTR(item, size) = pforwarded_array[1];
-                    synchronize_overflow_object_now(item);
+                    _set_weakref_in_all_segments(item, pforwarded_array[1]);
                 }
             }
             else {
@@ -80,8 +93,7 @@
                                   (uintptr_t)pointing_to)) {
                     /* still in the tree -> wasn't seen by the minor collection,
                        so it doesn't survive */
-                    *WEAKREF_PTR(item, size) = NULL;
-                    synchronize_overflow_object_now(item);
+                    _set_weakref_in_all_segments(item, NULL);
                     continue;   /* no need to remember in old_weakrefs */
                 }
                 /* pointing_to was already old */
@@ -118,10 +130,7 @@
             assert(pointing_to != NULL);
             if (!mark_visited_test(pointing_to)) {
                 //assert(flag_page_private[(uintptr_t)weakref / 4096UL] != PRIVATE_PAGE);
-                *WEAKREF_PTR(weakref, size) = NULL;
-                if (flag_page_private[(uintptr_t)weakref / 4096UL] == PRIVATE_PAGE) {
-                    synchronize_overflow_object_now(weakref);
-                }
+                _set_weakref_in_all_segments(weakref, NULL);
 
                 /* we don't need it in this list anymore */
                 list_set_item(lst, n, list_pop_item(lst));
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -286,8 +286,13 @@
     lib._set_type_id(o, tid)
     return o
 
-def stm_allocate_weakref(point_to_obj):
-    o = lib.stm_allocate_weakref(HDR + WORD)
+def stm_allocate_weakref(point_to_obj, size=None):
+    if size is None:
+        o = lib.stm_allocate_weakref(HDR + WORD)
+    else:
+        assert size >= HDR + WORD
+        o = lib.stm_allocate_weakref(size)
+
     tid = 421420
     lib._set_type_id(o, tid)
     lib._set_weakref(o, point_to_obj)
diff --git a/c7/test/test_weakref.py b/c7/test/test_weakref.py
--- a/c7/test/test_weakref.py
+++ b/c7/test/test_weakref.py
@@ -143,6 +143,37 @@
         self.start_transaction()
         assert stm_get_weakref(lp1) == ffi.NULL
 
+    def test_multiple_threads_w_big_weakref(self):
+        self.start_transaction()
+        lp0 = stm_allocate(1024)
+        self.push_root(lp0)
+        self.commit_transaction()
+
+        self.start_transaction()
+        lp0 = self.pop_root()
+        self.push_root(lp0)
+        stm_write(lp0) # privatize page
+
+        self.push_root_no_gc()
+        lp2 = stm_allocate(48)
+        lp1 = stm_allocate_weakref(
+            lp2, size=lib._STM_FAST_ALLOC + 16)    # no collection here
+        self.pop_root()
+
+        self.push_root(lp0)
+        self.push_root(lp1)
+        self.commit_transaction()
+        # lp2 dies
+        lp1 = self.pop_root()
+        self.push_root(lp1)
+
+        assert stm_get_weakref(lp1) == ffi.NULL
+
+        self.switch(1)
+
+        self.start_transaction()
+        assert stm_get_weakref(lp1) == ffi.NULL
+
 
 
 


More information about the pypy-commit mailing list