[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