[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