Author: Armin Rigo <[email protected]>
Branch:
Changeset: r321:7c03d107c940
Date: 2013-06-30 19:11 +0200
http://bitbucket.org/pypy/stmgc/changeset/7c03d107c940/
Log: Redo the hack about END_MARKERs in the shadowstack.
diff --git a/c4/gcpage.c b/c4/gcpage.c
--- a/c4/gcpage.c
+++ b/c4/gcpage.c
@@ -320,13 +320,20 @@
static void mark_roots(gcptr *root, gcptr *end)
{
- //assert(*root == END_MARKER);
- //root++;
+ assert(*root == END_MARKER_ON);
+ root++;
+
while (root != end) {
- gcptr o = *root;
- visit(root);
- dprintf(("visit stack root: %p -> %p\n", o, *root));
- (void)o; /* silence "warning: unused variable 'o'" */
+ gcptr item = *root;
+ if (((revision_t)item) & ~((revision_t)END_MARKER_OFF |
+ (revision_t)END_MARKER_ON)) {
+ /* 'item' is a regular, non-null pointer */
+ visit(root);
+ dprintf(("visit stack root: %p -> %p\n", item, *root));
+ }
+ else if (item == END_MARKER_OFF) {
+ *root = END_MARKER_ON;
+ }
root++;
}
}
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -323,12 +323,30 @@
static void mark_young_roots(struct tx_descriptor *d)
{
- gcptr *root = d->shadowstack;
+ /* we walk the shadowstack from the end, replacing any END_MARKER_OFF
+ found with END_MARKER_ON. When we reach an END_MARKER_ON, we know
+ that we have already seen the rest of the stack in the previous
+ nursery collection, so we stop.
+ */
gcptr *end = *d->shadowstack_end_ref;
- /* XXX use a way to avoid walking all roots again and again */
- for (; root != end; root++) {
- visit_if_young(root);
+ while (1) {
+ assert(end > d->shadowstack);
+ gcptr item = *--end;
+
+ if (((revision_t)item) & ~((revision_t)END_MARKER_OFF |
+ (revision_t)END_MARKER_ON)) {
+ /* 'item' is a regular, non-null pointer */
+ visit_if_young(end);
+ }
+ else if (item != NULL) {
+ if (item == END_MARKER_OFF)
+ *end = END_MARKER_ON;
+ else {
+ assert(item == END_MARKER_ON);
+ break;
+ }
+ }
}
}
diff --git a/c4/nursery.h b/c4/nursery.h
--- a/c4/nursery.h
+++ b/c4/nursery.h
@@ -18,6 +18,9 @@
# error "GC_NURSERY must be a multiple of GC_NURSERY_SECTION"
#endif
+#define END_MARKER_OFF ((gcptr) 16)
+#define END_MARKER_ON ((gcptr) 24)
+
#define NURSERY_FIELDS_DECL \
/* the nursery */ \
diff --git a/c4/stmsync.c b/c4/stmsync.c
--- a/c4/stmsync.c
+++ b/c4/stmsync.c
@@ -25,14 +25,14 @@
}
stm_shadowstack = d->shadowstack;
d->shadowstack_end_ref = &stm_shadowstack;
- //stm_push_root(END_MARKER);
+ stm_push_root(END_MARKER_ON);
}
static void done_shadowstack(void)
{
struct tx_descriptor *d = thread_descriptor;
- //gcptr x = stm_pop_root();
- //assert(x == END_MARKER);
+ gcptr x = stm_pop_root();
+ assert(x == END_MARKER_ON);
assert(stm_shadowstack == d->shadowstack);
stm_shadowstack = NULL;
free(d->shadowstack);
@@ -77,6 +77,7 @@
long volatile v_atomic;
stm_push_root(arg);
+ stm_push_root(END_MARKER_OFF);
if (!(v_atomic = thread_descriptor->atomic))
CommitTransaction();
@@ -98,14 +99,7 @@
long counter, result;
counter = v_counter;
d->atomic = v_atomic;
- stm_shadowstack = v_saved_value + 1; /* skip the 'arg', pushed above */
- // if (!d->atomic) {
- // /* In non-atomic mode, we are now between two transactions.
- // It means that in the next transaction's collections we know
- // that we won't need to access the shadow stack beyond its
- // current position. So we add an end marker. */
- // stm_push_root(END_MARKER);
- // }
+ stm_shadowstack = v_saved_value + 2; /*skip the two values pushed above*/
do {
v_counter = counter + 1;
@@ -135,7 +129,7 @@
/* invoke the callback in the new transaction */
arg = v_saved_value[0];
result = callback(arg, counter);
- assert(stm_shadowstack == v_saved_value + 1);
+ assert(stm_shadowstack == v_saved_value + 2);
v_atomic = d->atomic;
if (!d->atomic)
@@ -154,7 +148,9 @@
BeginInevitableTransaction();
}
- stm_pop_root(); /* pop the 'arg' */
+ gcptr x = stm_pop_root(); /* pop the END_MARKER */
+ assert(x == END_MARKER_OFF || x == END_MARKER_ON);
+ stm_pop_root(); /* pop the 'arg' */
assert(stm_shadowstack == v_saved_value);
}
diff --git a/c4/test/test_random.py b/c4/test/test_random.py
--- a/c4/test/test_random.py
+++ b/c4/test/test_random.py
@@ -305,12 +305,16 @@
#
self.roots = self.roots_outside_perform[:]
self.startrev()
- # XXX stm_perform_transaction() adds one root for the unused arg
+ # XXX stm_perform_transaction() adds one root for the unused arg,
+ # and one for an END_MARKER
+ end_marker = lib.stm_pop_root()
+ assert int(ffi.cast("revision_t", end_marker)) in [16, 24]
arg = lib.stm_pop_root()
assert arg == ffi.NULL
self.pop_roots()
self.push_roots()
lib.stm_push_root(arg)
+ lib.stm_push_root(end_marker)
self.check_valid(self.roots)
#
try:
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit