Author: Armin Rigo <[email protected]>
Branch:
Changeset: r141:337b49208d45
Date: 2013-06-16 11:15 +0200
http://bitbucket.org/pypy/stmgc/changeset/337b49208d45/
Log: Fix, going in another direction than cb8059368058: stmgc_duplicate()
should not cause any minor collection --- the write barrier should
not.
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -414,7 +414,7 @@
return P; /* always returns its arg: the object is converted in-place */
}
-static gcptr LocalizePublic(struct tx_descriptor *d, gcptr R, gcptr L)
+static gcptr LocalizePublic(struct tx_descriptor *d, gcptr R)
{
assert(R->h_tid & GCFLAG_PUBLIC);
@@ -427,11 +427,13 @@
R->h_tid |= GCFLAG_PUBLIC_TO_PRIVATE;
+ /* note that stmgc_duplicate() usually returns a young object, but may
+ return an old one if the nursery is full at this moment. */
+ gcptr L = stmgc_duplicate(R);
assert(!(L->h_tid & GCFLAG_BACKUP_COPY));
assert(!(L->h_tid & GCFLAG_STUB));
assert(!(L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED));
- L->h_tid &= ~(GCFLAG_OLD |
- GCFLAG_VISITED |
+ L->h_tid &= ~(GCFLAG_VISITED |
GCFLAG_PUBLIC |
GCFLAG_PREBUILT_ORIGINAL |
GCFLAG_PUBLIC_TO_PRIVATE |
@@ -471,7 +473,7 @@
return P;
}
- gcptr R, L, W;
+ gcptr R, W;
R = stm_read_barrier(P);
if (is_private(R))
@@ -483,13 +485,6 @@
struct tx_descriptor *d = thread_descriptor;
assert(d->active >= 1);
- L = NULL;
- if (R->h_tid & GCFLAG_PUBLIC)
- {
- retry:
- L = stmgc_duplicate(R);
- }
-
/* We need the collection_lock for the sequel; this is required notably
because we're about to edit flags on a protected object.
*/
@@ -499,20 +494,21 @@
if (R->h_tid & GCFLAG_PUBLIC)
{
- if (L == NULL)
- {
- /* Oups, the flags on R changed while we where waiting for
- the collection_lock. */
- spinlock_release(d->public_descriptor->collection_lock);
- goto retry;
- }
/* Make and return a new (young) private copy of the public R.
- Add R into the list 'public_with_young_copy'.
+ Add R into the list 'public_with_young_copy', unless W is
+ actually an old object, in which case we need to record W.
*/
assert(R->h_tid & GCFLAG_OLD);
- gcptrlist_insert(&d->public_with_young_copy, R);
- W = LocalizePublic(d, R, L);
+ W = LocalizePublic(d, R);
assert(is_private(W));
+
+ if (W->h_tid & GCFLAG_OLD)
+ {
+ W->h_tid |= GCFLAG_WRITE_BARRIER;
+ record_write_barrier(W);
+ }
+ else
+ gcptrlist_insert(&d->public_with_young_copy, R);
}
else
{
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -31,14 +31,20 @@
static char *collect_and_allocate_size(size_t size); /* forward */
-inline static char *allocate_nursery(size_t size)
+inline static char *allocate_nursery(size_t size, int can_collect)
{
struct tx_descriptor *d = thread_descriptor;
char *cur = d->nursery_current;
char *end = cur + size;
d->nursery_current = end;
if (end > d->nursery_end) {
- cur = collect_and_allocate_size(size);
+ if (can_collect) {
+ cur = collect_and_allocate_size(size);
+ }
+ else {
+ d->nursery_current = cur;
+ cur = NULL;
+ }
}
return cur;
}
@@ -46,7 +52,7 @@
gcptr stm_allocate(size_t size, unsigned long tid)
{
/* XXX inline the fast path */
- gcptr P = (gcptr)allocate_nursery(size);
+ gcptr P = (gcptr)allocate_nursery(size, 1);
assert(tid == (tid & STM_USER_TID_MASK));
P->h_tid = tid;
P->h_revision = stm_private_rev_num;
@@ -56,7 +62,10 @@
gcptr stmgc_duplicate(gcptr P)
{
size_t size = stmcb_size(P);
- gcptr L = (gcptr)allocate_nursery(size);
+ gcptr L = (gcptr)allocate_nursery(size, 0);
+ if (L == NULL)
+ return stmgc_duplicate_old(P);
+
memcpy(L, P, size);
L->h_tid &= ~GCFLAG_OLD;
return L;
@@ -290,7 +299,14 @@
teardown_minor_collect(d);
/* clear the nursery */
+#if defined(_GC_DEBUG) && _GC_DEBUG >= 2
+ stm_free(d->nursery_base, GC_NURSERY);
+ d->nursery_base = stm_malloc(GC_NURSERY);
memset(d->nursery_base, 0, GC_NURSERY);
+ d->nursery_end = d->nursery_base + GC_NURSERY;
+#else
+ memset(d->nursery_base, 0, GC_NURSERY);
+#endif
d->nursery_current = d->nursery_base;
assert(!stmgc_minor_collect_anything_to_do(d));
diff --git a/c4/test/support.py b/c4/test/support.py
--- a/c4/test/support.py
+++ b/c4/test/support.py
@@ -464,7 +464,8 @@
assert 42 < (p.h_tid & 0xFFFF) < 521
def check_nursery_free(p):
- assert p.h_tid == p.h_revision == 0
+ #assert p.h_tid == p.h_revision == 0
+ assert not lib._stm_can_access_memory(p)
def check_inaccessible(p):
assert not lib._stm_can_access_memory(p)
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
@@ -2,6 +2,9 @@
from support import *
+COLLECT_MOVES_NURSERY = True
+
+
def setup_function(f):
lib.stm_clear_between_tests()
lib.stm_initialize_tests(getattr(f, 'max_aborts', 0))
@@ -30,7 +33,8 @@
p1 = lib.stm_pop_root()
check_not_free(p1)
check_not_free(p3)
- assert p2 in seen # the pointer location was reused
+ if not COLLECT_MOVES_NURSERY:
+ assert p2 in seen # the pointer location was reused
def test_nursery_follows():
p1 = nalloc_refs(1)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit