[pypy-commit] pypy stmgc-c4: import stmgc
Raemi
noreply at buildbot.pypy.org
Mon Aug 26 18:14:01 CEST 2013
Author: Remi Meier <remi.meier at gmail.com>
Branch: stmgc-c4
Changeset: r66321:a9cc9ad24fae
Date: 2013-08-26 18:09 +0200
http://bitbucket.org/pypy/pypy/changeset/a9cc9ad24fae/
Log: import stmgc
diff --git a/rpython/translator/stm/src_stm/et.c b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -958,6 +958,7 @@
SpinLoop(SPLP_ABORT);
// jump back to the setjmp_buf (this call does not return)
d->active = 0;
+ d->atomic = 0;
stm_stop_sharedlock();
longjmp(*d->setjmp_buf, 1);
}
@@ -1006,6 +1007,7 @@
static void init_transaction(struct tx_descriptor *d)
{
+ assert(d->atomic == 0);
assert(d->active == 0);
stm_start_sharedlock();
assert(d->active == 0);
@@ -1361,6 +1363,7 @@
revision_t cur_time;
struct tx_descriptor *d = thread_descriptor;
assert(d->active >= 1);
+ assert(d->atomic == 0);
dprintf(("CommitTransaction(%p)\n", d));
spinlock_acquire(d->public_descriptor->collection_lock, 'C'); /*committing*/
if (d->public_descriptor->stolen_objects.size != 0)
diff --git a/rpython/translator/stm/src_stm/extra.c b/rpython/translator/stm/src_stm/extra.c
--- a/rpython/translator/stm/src_stm/extra.c
+++ b/rpython/translator/stm/src_stm/extra.c
@@ -301,15 +301,16 @@
case 3: /* a string of bytes from the target object */
rps = *(char **)(object + offset);
offset = *fieldoffsets++;
- if (rps) {
+ /* XXX think of a different hack: this one doesn't really
+ work if we see stubs! */
+ if (rps && !(((gcptr)rps)->h_tid & GCFLAG_STUB)) {
/* xxx a bit ad-hoc: it's a string whose length is a
* long at 'offset', following immediately the offset */
rps_size = *(long *)(rps + offset);
- offset += sizeof(long);
assert(rps_size >= 0);
res_size = sprintf(buffer, "%zu:", rps_size);
WRITE_BUF(buffer, res_size);
- WRITE_BUF(rps + offset, rps_size);
+ WRITE_BUF(rps + offset + sizeof(long), rps_size);
}
else {
WRITE_BUF("0:", 2);
diff --git a/rpython/translator/stm/src_stm/fprintcolor.c b/rpython/translator/stm/src_stm/fprintcolor.c
--- a/rpython/translator/stm/src_stm/fprintcolor.c
+++ b/rpython/translator/stm/src_stm/fprintcolor.c
@@ -58,3 +58,25 @@
}
#endif
+
+
+#ifdef STM_BARRIER_COUNT
+long stm_barriercount[STM_BARRIER_NUMBERS];
+
+void stm_print_barrier_count(void)
+{
+ static char names[] = STM_BARRIER_NAMES;
+ char *p = names;
+ char *q;
+ int i;
+ fprintf(stderr, "** Summary of the barrier calls **\n");
+ for (i = 0; i < STM_BARRIER_NUMBERS; i += 2) {
+ q = strchr(p, '\n');
+ *q = '\0';
+ fprintf(stderr, "%12ld %s\n", stm_barriercount[i], p);
+ *q = '\n';
+ fprintf(stderr, "%12ld \\ fast path\n", stm_barriercount[i + 1]);
+ p = q + 1;
+ }
+}
+#endif
diff --git a/rpython/translator/stm/src_stm/fprintcolor.h b/rpython/translator/stm/src_stm/fprintcolor.h
--- a/rpython/translator/stm/src_stm/fprintcolor.h
+++ b/rpython/translator/stm/src_stm/fprintcolor.h
@@ -21,3 +21,8 @@
#define dprintfcolor() 0
#endif
+
+
+#ifdef STM_BARRIER_COUNT
+void stm_print_barrier_count(void);
+#endif
diff --git a/rpython/translator/stm/src_stm/revision b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-b19dfb209a10
+cb61cf4e30a9
diff --git a/rpython/translator/stm/src_stm/steal.c b/rpython/translator/stm/src_stm/steal.c
--- a/rpython/translator/stm/src_stm/steal.c
+++ b/rpython/translator/stm/src_stm/steal.c
@@ -218,11 +218,12 @@
dprintf(("already stolen: %p -> %p\n", P, L));
/* note that we should follow h_revision at least one more
- step: it is necessary if L is public but young (and then
- has GCFLAG_MOVED), but it is fine to do it more
- generally. */
- v = ACCESS_ONCE(L->h_revision);
- if (IS_POINTER(v)) {
+ step: in the case where L is public but young (and then
+ has GCFLAG_MOVED). Don't do it generally! L might be
+ a stub again. */
+ if (L->h_tid & GCFLAG_MOVED) {
+ v = ACCESS_ONCE(L->h_revision);
+ assert(IS_POINTER(v));
L = (gcptr)v;
dprintf(("\t---> %p\n", L));
}
diff --git a/rpython/translator/stm/src_stm/stmgc.h b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -94,6 +94,10 @@
- stm_repeat_write_barrier() can be used on an object on which
we already did stm_write_barrier(), but a potential collection
can have occurred.
+
+ - stm_write_barrier_noptr() is a slightly cheaper version of
+ stm_write_barrier(), for when we are going to write
+ non-gc-pointers into the object.
*/
#if 0 // (optimized version below)
gcptr stm_read_barrier(gcptr);
@@ -101,6 +105,7 @@
gcptr stm_repeat_read_barrier(gcptr);
gcptr stm_immut_read_barrier(gcptr);
gcptr stm_repeat_write_barrier(gcptr); /* <= always returns its argument */
+gcptr stm_write_barrier_noptr(gcptr);
#endif
/* start a new transaction, calls callback(), and when it returns
@@ -203,33 +208,52 @@
#define UNLIKELY(test) __builtin_expect(test, 0)
+#ifdef STM_BARRIER_COUNT
+# define STM_BARRIER_NUMBERS 12
+# define STM_BARRIER_NAMES "stm_read_barrier\n" \
+ "stm_write_barrier\n" \
+ "stm_repeat_read_barrier\n" \
+ "stm_immut_read_barrier\n" \
+ "stm_repeat_write_barrier\n" \
+ "stm_write_barrier_noptr\n"
+# define STM_COUNT(id, x) (stm_barriercount[id]++, x)
+extern long stm_barriercount[STM_BARRIER_NUMBERS];
+#else
+# define STM_COUNT(id, x) (x)
+#endif
+
#define stm_read_barrier(obj) \
(UNLIKELY(((obj)->h_revision != stm_private_rev_num) && \
(FXCACHE_AT(obj) != (obj))) ? \
- stm_DirectReadBarrier(obj) \
- : (obj))
+ STM_COUNT(0, stm_DirectReadBarrier(obj)) \
+ : STM_COUNT(1, obj))
#define stm_write_barrier(obj) \
(UNLIKELY(((obj)->h_revision != stm_private_rev_num) || \
(((obj)->h_tid & GCFLAG_WRITE_BARRIER) != 0)) ? \
- stm_WriteBarrier(obj) \
- : (obj))
+ STM_COUNT(2, stm_WriteBarrier(obj)) \
+ : STM_COUNT(3, obj))
#define stm_repeat_read_barrier(obj) \
(UNLIKELY(((obj)->h_tid & (GCFLAG_PUBLIC_TO_PRIVATE | \
GCFLAG_MOVED)) != 0) ? \
- stm_RepeatReadBarrier(obj) \
- : (obj))
+ STM_COUNT(4, stm_RepeatReadBarrier(obj)) \
+ : STM_COUNT(5, obj))
#define stm_immut_read_barrier(obj) \
(UNLIKELY(((obj)->h_tid & GCFLAG_STUB) != 0) ? \
- stm_ImmutReadBarrier(obj) \
- : (obj))
+ STM_COUNT(6, stm_ImmutReadBarrier(obj)) \
+ : STM_COUNT(7, obj))
#define stm_repeat_write_barrier(obj) \
(UNLIKELY(((obj)->h_tid & GCFLAG_WRITE_BARRIER) != 0) ? \
- stm_RepeatWriteBarrier(obj) \
- : (obj))
+ STM_COUNT(8, stm_RepeatWriteBarrier(obj)) \
+ : STM_COUNT(9, obj))
+
+#define stm_write_barrier_noptr(obj) \
+ (UNLIKELY((obj)->h_revision != stm_private_rev_num) ? \
+ STM_COUNT(10, stm_WriteBarrier(obj)) \
+ : STM_COUNT(11, obj))
#endif
diff --git a/rpython/translator/stm/src_stm/stmsync.c b/rpython/translator/stm/src_stm/stmsync.c
--- a/rpython/translator/stm/src_stm/stmsync.c
+++ b/rpython/translator/stm/src_stm/stmsync.c
@@ -84,6 +84,13 @@
dprintf(("enter_callback_call(tok=%d)\n", token));
if (token == 1) {
stmgcpage_acquire_global_lock();
+#ifdef STM_BARRIER_COUNT
+ static int seen = 0;
+ if (!seen) {
+ seen = 1;
+ atexit(&stm_print_barrier_count);
+ }
+#endif
DescriptorInit();
stmgc_init_nursery();
init_shadowstack();
@@ -129,12 +136,11 @@
jmp_buf _jmpbuf;
long volatile v_counter = 0;
gcptr *volatile v_saved_value = stm_shadowstack;
- long volatile v_atomic;
stm_push_root(arg);
stm_push_root(END_MARKER_OFF);
- if (!(v_atomic = thread_descriptor->atomic))
+ if (!thread_descriptor->atomic)
CommitTransaction();
#ifdef _GC_ON_CPYTHON
@@ -153,7 +159,6 @@
struct tx_descriptor *d = thread_descriptor;
long counter, result;
counter = v_counter;
- d->atomic = v_atomic;
stm_shadowstack = v_saved_value + 2; /*skip the two values pushed above*/
do {
@@ -178,6 +183,7 @@
/* atomic transaction: a common case is that callback() returned
even though we are atomic because we need a major GC. For
that case, release and reaquire the rw lock here. */
+ assert(d->active >= 1);
stm_possible_safe_point();
}
@@ -186,7 +192,6 @@
result = callback(arg, counter);
assert(stm_shadowstack == v_saved_value + 2);
- v_atomic = d->atomic;
if (!d->atomic)
CommitTransaction();
More information about the pypy-commit
mailing list