Author: Armin Rigo <[email protected]>
Branch:
Changeset: r124:bbee0ad53806
Date: 2013-06-14 15:48 +0200
http://bitbucket.org/pypy/stmgc/changeset/bbee0ad53806/
Log: Next test
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -450,17 +450,30 @@
return L;
}
+static inline gcptr check_flag_write_barrier(gcptr W)
+{
+ if (W->h_tid & GCFLAG_WRITE_BARRIER)
+ {
+ struct tx_descriptor *d = thread_descriptor;
+ gcptrlist_insert(&d->private_old_pointing_to_young, W);
+ W->h_tid &= ~GCFLAG_WRITE_BARRIER;
+ }
+ return W;
+}
+
gcptr stm_WriteBarrier(gcptr P)
{
+ if (P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED)
+ return check_flag_write_barrier(P);
+
gcptr R, W;
+ R = stm_read_barrier(P);
+ if (is_private(R))
+ return check_flag_write_barrier(R);
+
struct tx_descriptor *d = thread_descriptor;
assert(d->active >= 1);
- R = stm_read_barrier(P);
-
- if (is_private(R))
- return R;
-
spinlock_acquire(d->public_descriptor->collection_lock, 'L');
if (d->public_descriptor->stolen_objects.size != 0)
stm_normalize_stolen_objects(d);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -27,6 +27,7 @@
gcptrlist_delete(&d->old_objects_to_trace);
gcptrlist_delete(&d->public_to_young);
+ gcptrlist_delete(&d->private_old_pointing_to_young);
}
static char *collect_and_allocate_size(size_t size); /* forward */
@@ -131,6 +132,13 @@
gcptrlist_clear(&d->public_to_young);
}
+static void mark_private_old_pointing_to_young(struct tx_descriptor *d)
+{
+ /* trace the objects recorded earlier by stmgc_write_barrier() */
+ gcptrlist_move(&d->old_objects_to_trace,
+ &d->private_old_pointing_to_young);
+}
+
static void visit_all_outside_objects(struct tx_descriptor *d)
{
while (gcptrlist_size(&d->old_objects_to_trace) > 0) {
@@ -177,9 +185,7 @@
mark_public_to_young(d);
-#if 0
mark_private_old_pointing_to_young(d);
-#endif
visit_all_outside_objects(d);
#if 0
@@ -216,8 +222,8 @@
if (d->nursery_current == d->nursery_base /*&&
!g2l_any_entry(&d->young_objects_outside_nursery)*/ ) {
/* there is no young object */
- //assert(gcptrlist_size(&d->private_old_pointing_to_young) == 0);
- //assert(gcptrlist_size(&d->public_to_young) == 0);
+ assert(gcptrlist_size(&d->private_old_pointing_to_young) == 0);
+ assert(gcptrlist_size(&d->public_to_young) == 0);
return 0;
}
else {
diff --git a/c4/nursery.h b/c4/nursery.h
--- a/c4/nursery.h
+++ b/c4/nursery.h
@@ -11,7 +11,8 @@
char *nursery_end; \
char *nursery_base; \
struct GcPtrList old_objects_to_trace; \
- struct GcPtrList public_to_young;
+ struct GcPtrList public_to_young; \
+ struct GcPtrList private_old_pointing_to_young;
struct tx_descriptor; /* from et.h */
diff --git a/c4/stmsync.c b/c4/stmsync.c
--- a/c4/stmsync.c
+++ b/c4/stmsync.c
@@ -87,8 +87,8 @@
gcptr stm_write_barrier(gcptr obj)
{
/* XXX inline in the caller */
- if (UNLIKELY((obj->h_revision != stm_private_rev_num) &
- ((obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) == 0)))
+ if (UNLIKELY((obj->h_revision != stm_private_rev_num) |
+ ((obj->h_tid & GCFLAG_WRITE_BARRIER) != 0)))
obj = stm_WriteBarrier(obj);
return obj;
}
diff --git a/c4/test/test_nursery.py b/c4/test/test_nursery.py
--- a/c4/test/test_nursery.py
+++ b/c4/test/test_nursery.py
@@ -71,3 +71,24 @@
p3 = lib.stm_read_barrier(p1)
assert not lib.in_nursery(p3) and p3 != p2
assert lib.rawgetlong(p3, 0) == -91467
+
+def test_outer2inner(): # test mark_private_old_pointing_to_young()
+ p1 = nalloc_refs(1)
+ lib.stm_push_root(p1)
+ minor_collect()
+ check_nursery_free(p1)
+ p1 = lib.stm_pop_root()
+ assert classify(p1) == "private"
+ p2 = nalloc(HDR + WORD)
+ lib.setlong(p2, 0, 8972981)
+ lib.setptr(p1, 0, p2)
+ #
+ lib.stm_push_root(p1)
+ minor_collect()
+ p1b = lib.stm_pop_root()
+ assert p1b == p1
+ check_nursery_free(p2)
+ p2b = lib.getptr(p1b, 0)
+ assert p2b != p2
+ check_not_free(p2b)
+ assert lib.getlong(p2b, 0) == 8972981
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit