[pypy-commit] stmgc default: Finish prebuilt.c, according to its test (which I forgot to check-in earlier)
arigo
noreply at buildbot.pypy.org
Sun Mar 2 20:03:13 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r927:d8c4f5b49016
Date: 2014-03-02 20:03 +0100
http://bitbucket.org/pypy/stmgc/changeset/d8c4f5b49016/
Log: Finish prebuilt.c, according to its test (which I forgot to check-in
earlier)
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -536,11 +536,10 @@
major_clear_write_locks();
/* marking */
- mark_objects_to_trace = list_create();
+ LIST_CREATE(mark_objects_to_trace);
mark_visit_from_modified_objects();
mark_visit_from_roots();
- list_free(mark_objects_to_trace);
- mark_objects_to_trace = NULL;
+ LIST_FREE(mark_objects_to_trace);
/* cleanup */
clean_up_segment_lists();
diff --git a/c7/stm/list.h b/c7/stm/list.h
--- a/c7/stm/list.h
+++ b/c7/stm/list.h
@@ -15,6 +15,7 @@
free(lst);
}
+#define LIST_CREATE(lst) ((lst) = list_create())
#define LIST_FREE(lst) (list_free(lst), (lst) = NULL)
diff --git a/c7/stm/prebuilt.c b/c7/stm/prebuilt.c
--- a/c7/stm/prebuilt.c
+++ b/c7/stm/prebuilt.c
@@ -5,23 +5,26 @@
#define GCWORD_PREBUILT_MOVED ((object_t *) 42)
+static struct list_s *prebuilt_objects_to_trace;
-object_t *stm_setup_prebuilt(object_t *staticobj_invalid)
+
+static void prebuilt_trace(object_t **pstaticobj_invalid)
{
- /* All variable names in "_invalid" here mean that although the
- type is really "object_t *", it should not actually be accessed
- via %gs.
+ uintptr_t objaddr = (uintptr_t)*pstaticobj_invalid;
+ struct object_s *obj = (struct object_s *)objaddr;
- If the object was already moved, its first word was set to
+ if (obj == NULL)
+ return;
+
+ /* If the object was already moved, its first word was set to
GCWORD_PREBUILT_MOVED. In that case, the forwarding location,
i.e. where the object moved to, is stored in the second word.
*/
- uintptr_t objaddr = (uintptr_t)staticobj_invalid;
- struct object_s *obj = (struct object_s *)objaddr;
object_t **pforwarded_array = (object_t **)objaddr;
if (pforwarded_array[0] == GCWORD_PREBUILT_MOVED) {
- return pforwarded_array[1]; /* already moved */
+ *pstaticobj_invalid = pforwarded_array[1]; /* already moved */
+ return;
}
/* We need to make a copy of this object. */
@@ -32,7 +35,33 @@
char *realnobj = REAL_ADDRESS(stm_object_pages, nobj);
memcpy(realnobj, (char *)objaddr, size);
- // XXX REFERENCES HERE
+ /* Mark the original object */
+ pforwarded_array[0] = GCWORD_PREBUILT_MOVED;
+ pforwarded_array[1] = nobj;
- return nobj;
+ /* Done */
+ *pstaticobj_invalid = nobj;
+ LIST_APPEND(prebuilt_objects_to_trace, realnobj);
}
+
+object_t *stm_setup_prebuilt(object_t *staticobj_invalid)
+{
+ /* All variable names in "_invalid" here mean that although the
+ type is really "object_t *", it should not actually be accessed
+ via %gs.
+ */
+ LIST_CREATE(prebuilt_objects_to_trace);
+
+ object_t *obj = staticobj_invalid;
+ prebuilt_trace(&obj);
+
+ while (!list_is_empty(prebuilt_objects_to_trace)) {
+ struct object_s *realobj1 =
+ (struct object_s *)list_pop_item(prebuilt_objects_to_trace);
+ stmcb_trace(realobj1, &prebuilt_trace);
+ }
+
+ LIST_FREE(prebuilt_objects_to_trace);
+
+ return obj;
+}
diff --git a/c7/test/test_prebuilt.py b/c7/test/test_prebuilt.py
new file mode 100644
--- /dev/null
+++ b/c7/test/test_prebuilt.py
@@ -0,0 +1,63 @@
+from support import *
+import py
+import weakref
+
+
+prebuilt_dict = weakref.WeakKeyDictionary()
+
+def _prebuilt(size, tid):
+ assert size >= 16
+ assert (size & 7) == 0
+ myobj1 = ffi.new("char[]", size)
+ myobj = ffi.cast("object_t *", myobj1)
+ prebuilt_dict[myobj] = myobj1
+ ffi.cast("uint32_t *", myobj)[1] = tid
+ return myobj
+
+def prebuilt(size):
+ return _prebuilt(size, 42 + size)
+
+def prebuilt_refs(n):
+ return _prebuilt(HDR + n * WORD, 421420 + n)
+
+
+class TestPrebuilt(BaseTest):
+
+ def test_simple_prebuilt(self):
+ static1 = prebuilt(16)
+ ffi.cast("char *", static1)[8:11] = 'ABC'
+ print static1
+ lp = lib.stm_setup_prebuilt(static1)
+ #
+ self.start_transaction()
+ assert stm_get_char(lp, 8) == 'A'
+ assert stm_get_char(lp, 9) == 'B'
+ assert stm_get_char(lp, 10) == 'C'
+
+ def test_prebuilt_rec(self):
+ static1 = prebuilt_refs(2)
+ static2 = prebuilt(16)
+ ffi.cast("char *", static2)[8:11] = 'ABC'
+ ffi.cast("object_t **", static1)[1] = static2
+ lp1 = lib.stm_setup_prebuilt(static1)
+ #
+ self.start_transaction()
+ assert not stm_get_ref(lp1, 1)
+ lp2 = stm_get_ref(lp1, 0)
+ print lp2
+ assert stm_get_char(lp2, 8) == 'A'
+ assert stm_get_char(lp2, 9) == 'B'
+ assert stm_get_char(lp2, 10) == 'C'
+
+ def test_prebuilt_rec_cycle(self):
+ static1 = prebuilt_refs(1)
+ static2 = prebuilt_refs(1)
+ ffi.cast("object_t **", static1)[1] = static2
+ ffi.cast("object_t **", static2)[1] = static1
+ lp1 = lib.stm_setup_prebuilt(static1)
+ #
+ self.start_transaction()
+ lp2 = stm_get_ref(lp1, 0)
+ print lp2
+ assert lp2 != lp1
+ assert stm_get_ref(lp2, 0) == lp1
More information about the pypy-commit
mailing list