[pypy-commit] stmgc default: merge heads
arigo
noreply at buildbot.pypy.org
Tue Jun 25 16:43:40 CEST 2013
Author: Armin Rigo <arigo at 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:
More information about the pypy-commit
mailing list