[pypy-commit] pypy stmgc-c7: import stmgc/c4e8d6220b74. Add two missing files.

arigo noreply at buildbot.pypy.org
Thu Mar 13 13:26:50 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r69929:d5cd283ea582
Date: 2014-03-13 11:44 +0100
http://bitbucket.org/pypy/pypy/changeset/d5cd283ea582/

Log:	import stmgc/c4e8d6220b74. Add two missing files.

diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-ae62acdb5d7c
+c4e8d6220b74
diff --git a/rpython/translator/stm/src_stm/stm/weakref.c b/rpython/translator/stm/src_stm/stm/weakref.c
new file mode 100644
--- /dev/null
+++ b/rpython/translator/stm/src_stm/stm/weakref.c
@@ -0,0 +1,149 @@
+/* Imported by rpython/translator/stm/import_stmgc.py */
+#ifndef _STM_CORE_H_
+# error "must be compiled via stmgc.c"
+#endif
+
+#define WEAKREF_PTR(wr, sz)  ((object_t * TLPREFIX *)(((stm_char *)(wr)) + (sz) - sizeof(void*)))
+
+object_t *stm_allocate_weakref(ssize_t size_rounded_up)
+{
+    OPT_ASSERT(size_rounded_up > sizeof(struct object_s));
+    OPT_ASSERT(size_rounded_up == 16); /* no reason for it to be anything else */
+
+    object_t *obj = stm_allocate(size_rounded_up);
+    assert(_is_in_nursery(obj)); /* because it's so small */
+
+    LIST_APPEND(STM_PSEGMENT->young_weakrefs, obj);
+    return obj;
+}
+
+
+object_t *stm_setup_prebuilt_weakref(object_t *obj)
+{
+    ssize_t size = 16;
+
+    obj = stm_setup_prebuilt(obj);
+    *WEAKREF_PTR(obj, size) = stm_setup_prebuilt(*WEAKREF_PTR(obj, size));
+    return obj;
+}
+
+
+static void _set_weakref_in_all_segments(object_t *weakref, object_t *value)
+{
+    ssize_t size = 16;
+
+    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 *****/
+
+static void stm_move_young_weakrefs()
+{
+    /* The code relies on the fact that no weakref can be an old object
+       weakly pointing to a young object.  Indeed, weakrefs are immutable
+       so they cannot point to an object that was created after it.
+    */
+    LIST_FOREACH_R(
+        STM_PSEGMENT->young_weakrefs,
+        object_t * /*item*/,
+        ({
+            /* weakrefs are so small, they always are in the nursery. Never
+               a young outside nursery object. */
+            assert(_is_in_nursery(item));
+            object_t *TLPREFIX *pforwarded_array = (object_t *TLPREFIX *)item;
+
+            /* the following checks are done like in nursery.c: */
+            if (!(item->stm_flags & GCFLAG_HAS_SHADOW)
+                || (pforwarded_array[0] != GCWORD_MOVED)) {
+                /* weakref dies */
+                continue;
+            }
+
+            item = pforwarded_array[1]; /* moved location */
+
+            assert(!_is_young(item));
+
+            ssize_t size = 16;
+            object_t *pointing_to = *WEAKREF_PTR(item, size);
+            assert(pointing_to != NULL);
+
+            if (_is_in_nursery(pointing_to)) {
+                object_t *TLPREFIX *pforwarded_array = (object_t *TLPREFIX *)pointing_to;
+                /* the following checks are done like in nursery.c: */
+                if (!(pointing_to->stm_flags & GCFLAG_HAS_SHADOW)
+                    || (pforwarded_array[0] != GCWORD_MOVED)) {
+                    /* pointing_to dies */
+                    _set_weakref_in_all_segments(item, NULL);
+                    continue;   /* no need to remember in old_weakrefs */
+                }
+                else {
+                    /* moved location */
+                    _set_weakref_in_all_segments(item, pforwarded_array[1]);
+                }
+            }
+            else {
+                /* young outside nursery object or old object */
+                if (tree_contains(STM_PSEGMENT->young_outside_nursery,
+                                  (uintptr_t)pointing_to)) {
+                    /* still in the tree -> wasn't seen by the minor collection,
+                       so it doesn't survive */
+                    _set_weakref_in_all_segments(item, NULL);
+                    continue;   /* no need to remember in old_weakrefs */
+                }
+                /* pointing_to was already old */
+            }
+            LIST_APPEND(STM_PSEGMENT->old_weakrefs, item);
+        }));
+    list_clear(STM_PSEGMENT->young_weakrefs);
+}
+
+
+/***** Major collection *****/
+
+
+static void stm_visit_old_weakrefs(void)
+{
+    long i;
+    for (i = 0; i < NB_SEGMENTS; i++) {
+        struct stm_priv_segment_info_s *pseg = get_priv_segment(i);
+        struct list_s *lst;
+
+        lst = pseg->old_weakrefs;
+        uintptr_t n = list_count(lst);
+        while (n > 0) {
+            object_t *weakref = (object_t *)list_item(lst, --n);
+            if (!mark_visited_test(weakref)) {
+                /* weakref dies */
+                list_set_item(lst, n, list_pop_item(lst));
+                continue;
+            }
+
+            ssize_t size = 16;
+            object_t *pointing_to = *WEAKREF_PTR(weakref, size);
+            assert(pointing_to != NULL);
+            if (!mark_visited_test(pointing_to)) {
+                //assert(flag_page_private[(uintptr_t)weakref / 4096UL] != PRIVATE_PAGE);
+                _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));
+                continue;
+            }
+            else {
+                /* it survives! */
+            }
+        }
+    }
+}
diff --git a/rpython/translator/stm/src_stm/stm/weakref.h b/rpython/translator/stm/src_stm/stm/weakref.h
new file mode 100644
--- /dev/null
+++ b/rpython/translator/stm/src_stm/stm/weakref.h
@@ -0,0 +1,10 @@
+/* Imported by rpython/translator/stm/import_stmgc.py */
+#ifndef _SRCSTM_WEAKREF_H
+#define _SRCSTM_WEAKREF_H
+
+object_t *stm_allocate_weakref(ssize_t size_rounded_up);
+static void stm_move_young_weakrefs(void);
+static void stm_visit_old_weakrefs(void);
+
+
+#endif
diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -283,6 +283,9 @@
    static structure, but it should never be used anyway.) */
 object_t *stm_setup_prebuilt(object_t *);
 
+/* The same, if the prebuilt object is actually a weakref. */
+object_t *stm_setup_prebuilt_weakref(object_t *);
+
 /* Hash, id.  The id is just the address of the object (of the address
    where it *will* be after the next minor collection).  The hash is the
    same, mangled -- except on prebuilt objects, where it can be


More information about the pypy-commit mailing list