Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r278:9935b830ffc8 Date: 2013-06-25 16:43 +0200 http://bitbucket.org/pypy/stmgc/changeset/9935b830ffc8/
Log: merge heads diff --git a/c4/atomic_ops.h b/c4/atomic_ops.h --- a/c4/atomic_ops.h +++ b/c4/atomic_ops.h @@ -2,7 +2,7 @@ #define _SRCSTM_ATOMIC_OPS_ #include <assert.h> - +#define IMPLIES(a, b) (!(a) || (b)) /* Ask the compiler to really reload the revision_t argument from memory. That's all that this macro does; it does not imply any type of barrier. diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -1031,8 +1031,9 @@ stub->h_tid = (L->h_tid & STM_USER_TID_MASK) | GCFLAG_PUBLIC | GCFLAG_STUB | GCFLAG_OLD; + stub->h_revision = ((revision_t)L) | 2; + assert(!(L->h_tid & GCFLAG_HAS_ID)); - stub->h_revision = ((revision_t)L) | 2; if (L->h_original) { stub->h_original = L->h_original; } @@ -1040,8 +1041,14 @@ stub->h_original = (revision_t)L; } else { - L->h_original = (revision_t)stub; + /* There shouldn't be a public, young object without + a h_original. They only come from stealing which + always sets h_original */ assert(0); + /* L->h_original = (revision_t)stub; */ + /* if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { */ + /* ((gcptr)L->h_revision)->h_original = (revision_t)stub; */ + /* } */ } item->val = stub; @@ -1165,12 +1172,6 @@ { /* copy the backup copy B back over the now-protected object P, and then free B, which will not be used any more. */ - assert(!(P->h_original) - || (B->h_original == (revision_t)P->h_original)); - assert(!(P->h_original && !B->h_original)); - if (P->h_original && !B->h_original) // might occur because of - B->h_original = P->h_original; //replace_ptr_to_protected_with_stub - size_t size = stmcb_size(B); assert(B->h_tid & GCFLAG_BACKUP_COPY); memcpy(((char *)P) + offsetof(struct stm_object_s, h_revision), diff --git a/c4/nursery.c b/c4/nursery.c --- a/c4/nursery.c +++ b/c4/nursery.c @@ -162,7 +162,7 @@ else if (p->h_tid & GCFLAG_OLD) { /* old objects must have an h_original xOR be the original itself. */ - /* dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p)); */ + dprintf(("stm_id(%p) is old, orig=0 fst: %p\n", p, p)); return (revision_t)p; } diff --git a/c4/steal.c b/c4/steal.c --- a/c4/steal.c +++ b/c4/steal.c @@ -53,7 +53,13 @@ stub->h_original = (revision_t)obj; } else { - obj->h_original = (revision_t)stub; + /* There shouldn't be a public, young object without + a h_original. But there can be protected ones. */ + assert(!(obj->h_tid & GCFLAG_PUBLIC)); + obj->h_original = (revision_t)stub; + if (obj->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { + ((gcptr)obj->h_revision)->h_original = (revision_t)stub; + } } g2l_insert(&sd->all_stubs, obj, stub); @@ -93,23 +99,23 @@ if (L->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) { gcptr B = (gcptr)L->h_revision; /* the backup copy */ - if (L->h_original) { - /* L has an original, may be GCFLAG_HAS_ID */ - B->h_original = L->h_original; - L->h_tid &= ~GCFLAG_HAS_ID; - } - else if (L->h_tid & GCFLAG_OLD) { - /* If old, it must be the original */ - assert(!(L->h_tid & GCFLAG_HAS_ID)); - /* original must be L */ + /* On young objects here, h_original is always set + and never GCFLAG_HAS_ID. This is because a stealing + thread can only reach a priv_from_prot object through + public old stubs/objects that serve as originals if + needed. + If h_original is set, then it is already set in the + backup, too. + */ + assert(!(L->h_tid & GCFLAG_HAS_ID)); + assert(IMPLIES(!(L->h_tid & GCFLAG_OLD), L->h_original)); + assert(IMPLIES(L->h_tid & GCFLAG_OLD, + (B->h_original == (revision_t)L) + || (B->h_original == L->h_original))); + if (!L->h_original && L->h_tid & GCFLAG_OLD) { + /* If old, L must be the original */ B->h_original = (revision_t)L; } - else { - /* we can make the backup the "original" - since L hasn't decided yet */ - L->h_original = (revision_t)B; - assert(0); - } /* B is now a backup copy, i.e. a protected object, and we own the foreign thread's collection_lock, so we can read/write the diff --git a/c4/test/test_et.py b/c4/test/test_et.py --- a/c4/test/test_et.py +++ b/c4/test/test_et.py @@ -539,6 +539,7 @@ assert not (p1.h_tid & GCFLAG_HAS_ID) r1w = lib.stm_write_barrier(r1) + lib.setptr(p1, 1, r1w) assert classify(r1w) == "private_from_protected" assert not (r1w.h_tid & GCFLAG_OLD) if c: _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit