Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit