[pypy-commit] pypy stm-thread-2: fixfixfix
arigo
noreply at buildbot.pypy.org
Fri Sep 7 14:54:52 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread-2
Changeset: r57209:611a5fd10cd4
Date: 2012-09-07 14:54 +0200
http://bitbucket.org/pypy/pypy/changeset/611a5fd10cd4/
Log: fixfixfix
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -59,8 +59,8 @@
# - GCFLAG_LOCAL_COPY: see stmimpl.rst. Used by C.
#
# - GCFLAG_VISITED: used temporarily to mark local objects found to be
-# surviving during a collection. Between collections, it can remain
-# set on the LOCAL COPY objects, but only on them.
+# surviving during a collection. Between collections, it is set on
+# the LOCAL COPY objects, but only on them.
#
# - GCFLAG_HAS_SHADOW: set on nursery objects whose id() or identityhash()
# was taken. Means that we already have a corresponding object allocated
@@ -337,6 +337,7 @@
llmemory.raw_memcopy(obj - size_gc_header,
localobj - size_gc_header,
totalsize)
+ self.header(localobj).tid |= GCFLAG_VISITED
return localobj
# ----------
diff --git a/pypy/rpython/memory/gc/stmtls.py b/pypy/rpython/memory/gc/stmtls.py
--- a/pypy/rpython/memory/gc/stmtls.py
+++ b/pypy/rpython/memory/gc/stmtls.py
@@ -162,9 +162,9 @@
debug_start("gc-local")
#
if end_of_transaction:
- self.replace_pointers_following_revision = GCFLAG_LOCAL_COPY
+ self.detect_flag_combination = GCFLAG_LOCAL_COPY | GCFLAG_VISITED
else:
- self.replace_pointers_following_revision = 0
+ self.detect_flag_combination = -1
#
# Move away the previous sharedarea_tls and start a new one.
from pypy.rpython.memory.gc.stmshared import StmGCThreadLocalAllocator
@@ -279,9 +279,11 @@
while self.copied_local_objects.non_empty():
obj = self.copied_local_objects.pop()
hdr = self.gc.header(obj)
- ll_assert(hdr.tid & GCFLAG_LOCAL_COPY != 0,"missing LOCAL_COPY [0]")
+ ll_assert(hdr.tid & GCFLAG_LOCAL_COPY, "missing LOCAL_COPY [0]")
ll_assert(hdr.tid & GCFLAG_GLOBAL == 0, "already GLOBAL [0]")
+ ll_assert(hdr.tid & GCFLAG_VISITED, "missing VISITED [0]")
hdr.tid |= GCFLAG_GLOBAL | GCFLAG_NOT_WRITTEN
+ hdr.tid &= ~(GCFLAG_VISITED | GCFLAG_LOCAL_COPY)
# don't touch 'revision' in this case
def _clear_version_for_global_object(self, hdr):
@@ -376,10 +378,10 @@
if flag_combination == 0:
return 0 # not marked as surviving, so far
- if flag_combination & self.replace_pointers_following_revision:
- # At a normal time, self.replace_pointers_following_revision
- # is 0 and this case is never seen. At end of transactions,
- # detect_flag_combination is GCFLAG_LOCAL_COPY.
+ if flag_combination == self.detect_flag_combination:
+ # At a normal time, self.detect_flag_combination is -1
+ # and this case is never seen. At end of transactions,
+ # detect_flag_combination is GCFLAG_LOCAL_COPY|GCFLAG_VISITED.
# This case is to force pointers to the LOCAL copy to be
# replaced with pointers to the GLOBAL copy.
return 2
@@ -497,8 +499,8 @@
"in a root: unexpected GCFLAG_GLOBAL")
ll_assert(localhdr.tid & GCFLAG_LOCAL_COPY != 0,
"in a root: missing GCFLAG_LOCAL_COPY")
- # localhdr.tid & GCFLAG_VISITED may be set or not so far, with no
- # particular consequence, but we force it to be set from now on (below)
+ ll_assert(localhdr.tid & GCFLAG_VISITED != 0,
+ "in a root: missing GCFLAG_VISITED")
globalhdr = self.gc.header(globalobj)
ll_assert(globalhdr.tid & GCFLAG_GLOBAL != 0,
"in a root: GLOBAL: missing GCFLAG_GLOBAL")
@@ -512,8 +514,7 @@
self.gc.get_type_id(globalobj))
ll_assert(TL == TG, "in a root: type(LOCAL) != type(GLOBAL)")
#
- localhdr.tid |= GCFLAG_VISITED
- self.pending.append(localobj)
+ self.trace_and_drag_out_of_nursery(localobj)
def collect_flush_pending(self):
# Follow the objects in the 'pending' stack and move the
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -53,11 +53,6 @@
struct FXCache recent_reads_cache;
};
-struct gcroot_s {
- gcptr R, L;
- revision_t v;
-};
-
static volatile revision_t global_cur_time = 2; /* always even */
static volatile revision_t next_locked_value = LOCKED + 3; /* always odd */
static __thread struct tx_descriptor *thread_descriptor = NULL;
@@ -238,9 +233,10 @@
not_found:
L = pypy_g__stm_duplicate(R);
- L->h_tid &= ~(GCFLAG_GLOBAL | GCFLAG_POSSIBLY_OUTDATED);
- assert(L->h_tid & GCFLAG_NOT_WRITTEN);
- L->h_tid |= GCFLAG_LOCAL_COPY;
+ assert(!(L->h_tid & GCFLAG_GLOBAL)); /* must be removed by stm_duplicate */
+ assert(!(L->h_tid & GCFLAG_POSSIBLY_OUTDATED)); /* must be removed by ^ */
+ assert(L->h_tid & GCFLAG_LOCAL_COPY); /* must be added by stm_duplicate */
+ assert(L->h_tid & GCFLAG_NOT_WRITTEN); /* must not be set in the 1st place */
L->h_revision = (revision_t)R; /* back-reference to the original */
g2l_insert(&d->global_to_local, R, L);
return L;
@@ -411,31 +407,15 @@
update_reads_size_limit(d);
}
-#if 0
-static int compare_by_R(const void *a, const void *b)
-{
- gcptr Ra = *(const gcptr *)a;
- gcptr Rb = *(const gcptr *)b;
- if (Ra < Rb)
- return -1;
- else if (Ra == Rb)
- return 0;
- else
- return 1;
-}
-#endif
-
static void AcquireLocks(struct tx_descriptor *d)
{
revision_t my_lock = d->my_lock;
- struct gcroot_s *item = (struct gcroot_s *)d->gcroots.items;
-#if 0
+ gcptr *item = d->gcroots.items;
// gcroots should be sorted in some deterministic order by construction
- qsort(item, d->gcroots.size / 3, sizeof(struct gcroot_s), &compare_by_R);
-#endif
- while (item->R != NULL)
+
+ while (item[0] != NULL)
{
- gcptr R = item->R;
+ gcptr R = (gcptr)item[0]->h_revision;
revision_t v;
retry:
v = R->h_revision;
@@ -452,49 +432,50 @@
if (!bool_cas((volatile revision_t *)&R->h_revision, v, my_lock))
goto retry;
- item->v = v;
- item++;
+ item[1] = (gcptr)v;
+ item += 2;
}
}
static void CancelLocks(struct tx_descriptor *d)
{
- long i, lastitem = d->gcroots.size - 3;
+ long i, lastitem = d->gcroots.size - 2;
gcptr *items = d->gcroots.items;
- for (i=0; i<=lastitem; i+=3)
+ for (i=0; i<=lastitem; i+=2)
{
gcptr R = items[i];
- gcptr v = items[i+2];
+ revision_t v = (revision_t)items[i+1];
if (v != 0)
{
- R->h_revision = (revision_t)v;
+ R->h_revision = v;
// if we're going to retry later, and abort,
// then we must not re-cancel the same entries
- items[i+2] = 0;
+ items[i+1] = 0;
}
}
}
static void UpdateChainHeads(struct tx_descriptor *d, revision_t cur_time)
{
- struct gcroot_s *item, *itemstart = (struct gcroot_s *)d->gcroots.items;
+ gcptr *item, *itemstart = d->gcroots.items;
revision_t new_revision = cur_time + 1; // make an odd number
assert(new_revision & 1);
- for (item = itemstart; item->R != NULL; item++)
+ for (item = itemstart; item[0] != NULL; item += 2)
{
- gcptr L = item->L;
+ gcptr L = item[0];
assert((L->h_tid & (GCFLAG_GLOBAL |
GCFLAG_NOT_WRITTEN |
GCFLAG_POSSIBLY_OUTDATED)) ==
(GCFLAG_GLOBAL | GCFLAG_NOT_WRITTEN));
+ item[1] = (gcptr)L->h_revision; /* old value: pointer to R */
L->h_revision = new_revision;
}
smp_wmb();
- for (item = itemstart; item->R != NULL; item++)
+ for (item = itemstart; item[0] != NULL; item += 2)
{
- gcptr L = item->L;
- gcptr R = item->R;
+ gcptr L = item[0];
+ gcptr R = item[1];
assert((R->h_tid & (GCFLAG_GLOBAL |
GCFLAG_NOT_WRITTEN |
GCFLAG_POSSIBLY_OUTDATED)) ==
@@ -503,7 +484,7 @@
}
}
-static struct gcroot_s *FindRootsForLocalCollect(void)
+static gcptr *FindRootsForLocalCollect(void)
{
struct tx_descriptor *d = thread_descriptor;
wlog_t *item;
@@ -517,10 +498,10 @@
L->h_tid |= GCFLAG_GLOBAL | GCFLAG_POSSIBLY_OUTDATED;
continue;
}
- gcptrlist_insert3(&d->gcroots, R, L, (gcptr)0);
+ gcptrlist_insert2(&d->gcroots, L, (gcptr)0);
} G2L_LOOP_END;
gcptrlist_insert(&d->gcroots, NULL);
- return (struct gcroot_s *)d->gcroots.items;
+ return d->gcroots.items;
}
int _FakeReach(gcptr P)
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -93,7 +93,7 @@
extern void *pypy_g__stm_duplicate(void *);
-extern void pypy_g__stm_enum_callback(void *, void *, void *);
+extern void pypy_g__stm_enum_callback(void *, void *);
void stm_set_tls(void *newtls);
void *stm_get_tls(void);
void stm_del_tls(void);
diff --git a/pypy/translator/stm/src_stm/lists.c b/pypy/translator/stm/src_stm/lists.c
--- a/pypy/translator/stm/src_stm/lists.c
+++ b/pypy/translator/stm/src_stm/lists.c
@@ -234,18 +234,17 @@
gcptrlist->items[gcptrlist->size++] = newitem;
}
-static void gcptrlist_insert3(struct GcPtrList *gcptrlist, gcptr newitem1,
- gcptr newitem2, gcptr newitem3)
+static void gcptrlist_insert2(struct GcPtrList *gcptrlist, gcptr newitem1,
+ gcptr newitem2)
{
gcptr *items;
long i = gcptrlist->size;
- if (__builtin_expect((gcptrlist->alloc - i) < 3, 0))
+ if (__builtin_expect((gcptrlist->alloc - i) < 2, 0))
_gcptrlist_grow(gcptrlist);
items = gcptrlist->items;
items[i+0] = newitem1;
items[i+1] = newitem2;
- items[i+2] = newitem3;
- gcptrlist->size = i + 3;
+ gcptrlist->size = i + 2;
}
/************************************************************/
diff --git a/pypy/translator/stm/src_stm/rpyintf.c b/pypy/translator/stm/src_stm/rpyintf.c
--- a/pypy/translator/stm/src_stm/rpyintf.c
+++ b/pypy/translator/stm/src_stm/rpyintf.c
@@ -39,12 +39,12 @@
struct tx_descriptor *d = thread_descriptor;
wlog_t *item;
void *tls = stm_get_tls();
- struct gcroot_s *gcroots = FindRootsForLocalCollect();
+ gcptr *gcroots = FindRootsForLocalCollect();
- while (gcroots->R != NULL)
+ while (gcroots[0] != NULL)
{
- pypy_g__stm_enum_callback(tls, gcroots->R, gcroots->L);
- gcroots++;
+ pypy_g__stm_enum_callback(tls, gcroots[0]);
+ gcroots += 2;
}
}
@@ -235,9 +235,11 @@
abort();
}
memcpy(result, src, size);
+ ((gcptr)result)->h_tid &= ~(GCFLAG_GLOBAL | GCFLAG_POSSIBLY_OUTDATED);
+ ((gcptr)result)->h_tid |= GCFLAG_LOCAL_COPY;
return result;
}
-void pypy_g__stm_enum_callback(void *tlsaddr, void *R, void *L)
+void pypy_g__stm_enum_callback(void *tlsaddr, void *L)
{
abort();
}
diff --git a/pypy/translator/stm/test/test_stmgcintf.c b/pypy/translator/stm/test/test_stmgcintf.c
--- a/pypy/translator/stm/test/test_stmgcintf.c
+++ b/pypy/translator/stm/test/test_stmgcintf.c
@@ -32,15 +32,15 @@
gcptr (*cb_duplicate)(gcptr);
-void (*cb_enum_callback)(void *, gcptr, gcptr);
+void (*cb_enum_callback)(void *, gcptr);
void *pypy_g__stm_duplicate(void *a) {
assert(cb_duplicate != NULL);
return cb_duplicate((gcptr)a);
}
-void pypy_g__stm_enum_callback(void *a, void *b, void *c) {
+void pypy_g__stm_enum_callback(void *a, void *b) {
assert(cb_enum_callback != NULL);
- cb_enum_callback(a, (gcptr)b, (gcptr)c);
+ cb_enum_callback(a, (gcptr)b);
}
@@ -159,14 +159,15 @@
/************************************************************/
struct pypy_header0 etldn1 = {GCFLAG_PREBUILT, REV_INITIAL};
-struct pypy_header0 etldn2 = {0, 0};
+struct pypy_header0 etldn2 = {GCFLAG_LOCAL_COPY, (revision_t)&etldn1};
struct pypy_header0 etldn3 = {GCFLAG_PREBUILT, REV_INITIAL};
-struct pypy_header0 etldn4 = {0, 0};
+struct pypy_header0 etldn4 = {GCFLAG_LOCAL_COPY, (revision_t)&etldn3};
int check_enum_1_found;
-void check_enum_1(void *tls, gcptr a, gcptr b)
+void check_enum_1(void *tls, gcptr b)
{
int n;
+ gcptr a = (gcptr)b->h_revision;
assert(tls == (void *)742);
if (a == &etldn1 && b == &etldn2)
n = 1;
@@ -277,9 +278,11 @@
}
gcptr duplicator_cb(gcptr x)
{
- assert(x == &sg_global);
+ assert(x == &sg_global.header);
sg_local = sg_global;
- return &sg_local;
+ sg_local.header.h_tid &= ~(GCFLAG_GLOBAL | GCFLAG_POSSIBLY_OUTDATED);
+ sg_local.header.h_tid |= GCFLAG_LOCAL_COPY;
+ return &sg_local.header;
}
void test_duplicator(void)
{
More information about the pypy-commit
mailing list