Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r1300:2866cee6ce00
Date: 2014-08-12 16:29 +0200
http://bitbucket.org/pypy/stmgc/changeset/2866cee6ce00/

Log:    in-progress

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -393,7 +393,7 @@
 #ifdef STM_NO_AUTOMATIC_SETJMP
     long repeat_count = 0;    /* test/support.py */
 #else
-    long repeat_count = rewind_jmp_setjmp(&tl->rjthread);
+    long repeat_count = stm_rewind_jmp_setjmp(tl);
 #endif
     _stm_start_transaction(tl, false);
     return repeat_count;
@@ -828,7 +828,7 @@
     dprintf(("commit_transaction\n"));
 
     assert(STM_SEGMENT->nursery_end == NURSERY_END);
-    rewind_jmp_forget(&STM_SEGMENT->running_thread->rjthread);
+    stm_rewind_jmp_forget(STM_SEGMENT->running_thread);
 
     /* if a major collection is required, do it here */
     if (is_major_collection_requested()) {
@@ -983,12 +983,12 @@
     reset_modified_from_other_segments(segment_num);
     _verify_cards_cleared_in_all_lists(pseg);
 
-    /* reset the tl->shadowstack and thread_local_obj to their original
-       value before the transaction start */
+    /* reset tl->shadowstack and thread_local_obj to their original
+       value before the transaction start.  Also restore the content
+       of the shadowstack here. */
     stm_thread_local_t *tl = pseg->pub.running_thread;
-    assert(tl->shadowstack >= pseg->shadowstack_at_start_of_transaction);
-    pseg->shadowstack_at_abort = tl->shadowstack;
-    tl->shadowstack = pseg->shadowstack_at_start_of_transaction;
+    stm_rewind_jmp_restore_shadowstack(tl);
+    assert(tl->shadowstack == pseg->shadowstack_at_start_of_transaction);
     tl->thread_local_obj = pseg->threadlocal_at_start_of_transaction;
     tl->last_abort__bytes_in_nursery = bytes_in_nursery;
 
@@ -1063,7 +1063,7 @@
 #ifdef STM_NO_AUTOMATIC_SETJMP
     _test_run_abort(tl);
 #else
-    rewind_jmp_longjmp(&tl->rjthread);
+    stm_rewind_jmp_longjmp(tl);
 #endif
 }
 
@@ -1078,7 +1078,7 @@
         marker_fetch_inev();
         wait_for_end_of_inevitable_transaction(NULL);
         STM_PSEGMENT->transaction_state = TS_INEVITABLE;
-        rewind_jmp_forget(&STM_SEGMENT->running_thread->rjthread);
+        stm_rewind_jmp_forget(STM_SEGMENT->running_thread);
         clear_callbacks_on_abort();
     }
     else {
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -186,7 +186,6 @@
        'thread_local_obj' field. */
     struct stm_shadowentry_s *shadowstack_at_start_of_transaction;
     object_t *threadlocal_at_start_of_transaction;
-    struct stm_shadowentry_s *shadowstack_at_abort;
 
     /* Already signalled to commit soon: */
     bool signalled_to_commit_soon;
diff --git a/c7/stm/forksupport.c b/c7/stm/forksupport.c
--- a/c7/stm/forksupport.c
+++ b/c7/stm/forksupport.c
@@ -184,7 +184,7 @@
 
     rewind_jmp_buf rjbuf;
     stm_rewind_jmp_enterframe(tl, &rjbuf);
-    if (rewind_jmp_setjmp(&tl->rjthread) == 0) {
+    if (stm_rewind_jmp_setjmp(tl) == 0) {
 #ifndef NDEBUG
         pr->running_pthread = pthread_self();
 #endif
@@ -193,7 +193,7 @@
         strcpy(pr->marker_self, "fork");
         stm_abort_transaction();
     }
-    rewind_jmp_forget(&tl->rjthread);
+    stm_rewind_jmp_forget(tl);
     stm_rewind_jmp_leaveframe(tl, &rjbuf);
 }
 
diff --git a/c7/stm/rewind_setjmp.c b/c7/stm/rewind_setjmp.c
--- a/c7/stm/rewind_setjmp.c
+++ b/c7/stm/rewind_setjmp.c
@@ -93,13 +93,7 @@
         }
         memcpy(target, ((char *)p) + RJM_HEADER, p->stack_size);
 
-        char *sstarget = rjthread->moved_off_ssbase;
-        char *ssend = sstarget + p->shadowstack_size;
-        memcpy(sstarget, ((char *)p) + RJM_HEADER + p->stack_size,
-               p->shadowstack_size);
-
         rjthread->moved_off_base = target;
-        rjthread->moved_off_ssbase = ssend;
         rjthread->moved_off = p->next;
         rj_free(p);
     }
@@ -113,6 +107,22 @@
     do_longjmp(rjthread, &_rewind_jmp_marker);
 }
 
+char *rewind_jmp_restore_shadowstack(rewind_jmp_thread *rjthread)
+{
+    struct _rewind_jmp_moved_s *p = rjthread->moved_off;
+    char *sstarget = rjthread->moved_off_ssbase;
+
+    while (p) {
+        char *ssend = sstarget + p->shadowstack_size;
+        memcpy(sstarget, ((char *)p) + RJM_HEADER + p->stack_size,
+               p->shadowstack_size);
+        sstarget = ssend;
+        p = p->next;
+    }
+    rjthread->moved_off_ssbase = sstarget;
+    return sstarget;
+}
+
 __attribute__((noinline))
 void _rewind_jmp_copy_stack_slice(rewind_jmp_thread *rjthread)
 {
diff --git a/c7/stm/rewind_setjmp.h b/c7/stm/rewind_setjmp.h
--- a/c7/stm/rewind_setjmp.h
+++ b/c7/stm/rewind_setjmp.h
@@ -74,6 +74,7 @@
 
 long rewind_jmp_setjmp(rewind_jmp_thread *rjthread, void *ss);
 void rewind_jmp_longjmp(rewind_jmp_thread *rjthread) __attribute__((noreturn));
+char *rewind_jmp_restore_shadowstack(rewind_jmp_thread *rjthread);
 
 #define rewind_jmp_forget(rjthread)  do {                               \
     if ((rjthread)->moved_off) _rewind_jmp_free_stack_slices(rjthread); \
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -331,9 +331,18 @@
    function with the interpreter's dispatch loop, you need to declare
    a local variable of type 'rewind_jmp_buf' and call these macros. */
 #define stm_rewind_jmp_enterframe(tl, rjbuf)       \
-    rewind_jmp_enterframe(&(tl)->rjthread, rjbuf)
+    rewind_jmp_enterframe(&(tl)->rjthread, rjbuf, (tl)->shadowstack)
 #define stm_rewind_jmp_leaveframe(tl, rjbuf)       \
-    rewind_jmp_leaveframe(&(tl)->rjthread, rjbuf)
+    rewind_jmp_leaveframe(&(tl)->rjthread, rjbuf, (tl)->shadowstack)
+#define stm_rewind_jmp_setjmp(tl)                  \
+    rewind_jmp_setjmp(&(tl)->rjthread, (tl)->shadowstack)
+#define stm_rewind_jmp_longjmp(tl)                 \
+    rewind_jmp_longjmp(&(tl)->rjthread)
+#define stm_rewind_jmp_forget(tl)                  \
+    rewind_jmp_forget(&(tl)->rjthread)
+#define stm_rewind_jmp_restore_shadowstack(tl)     \
+    ((tl)->shadowstack = (struct stm_shadowentry_s *) \
+        rewind_jmp_restore_shadowstack(&(tl)->rjthread))
 
 /* Starting and ending transactions.  stm_read(), stm_write() and
    stm_allocate() should only be called from within a transaction.
diff --git a/c7/test/test_rewind.c b/c7/test/test_rewind.c
--- a/c7/test/test_rewind.c
+++ b/c7/test/test_rewind.c
@@ -239,6 +239,7 @@
         assert(ssarray[5] == a5);
         ssarray[4] = NULL;
         ssarray[5] = NULL;
+        rewind_jmp_restore_shadowstack(&gthread);
         rewind_jmp_longjmp(&gthread);
     }
     /* second path */
@@ -274,8 +275,10 @@
     int result = gtl2();
     ssarray[4] = NULL;
 
-    if (result == 0)
+    if (result == 0) {
+        rewind_jmp_restore_shadowstack(&gthread);
         rewind_jmp_longjmp(&gthread);
+    }
 
     rewind_jmp_leaveframe(&gthread, &buf, ssarray+4);
 }
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to