[pypy-commit] pypy stm-gc: Save and restore the root_stack_top explicitly with the help of C code.

arigo noreply at buildbot.pypy.org
Tue Apr 17 14:03:24 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54460:7a642543dd09
Date: 2012-04-17 13:28 +0200
http://bitbucket.org/pypy/pypy/changeset/7a642543dd09/

Log:	Save and restore the root_stack_top explicitly with the help of C
	code.

diff --git a/pypy/rlib/rstm.py b/pypy/rlib/rstm.py
--- a/pypy/rlib/rstm.py
+++ b/pypy/rlib/rstm.py
@@ -2,7 +2,7 @@
 from pypy.rlib.objectmodel import specialize, we_are_translated
 from pypy.rlib.objectmodel import keepalive_until_here
 from pypy.rlib.debug import ll_assert
-from pypy.rpython.lltypesystem import rffi, lltype, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass
 from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.annlowlevel import (cast_base_ptr_to_instance,
                                       cast_instance_to_base_ptr,
@@ -35,6 +35,7 @@
     if we_are_translated():
         llarg = cast_instance_to_base_ptr(arg)
         llarg = rffi.cast(rffi.VOIDP, llarg)
+        adr_of_top = llop.gc_adr_of_root_stack_top(llmemory.Address)
     else:
         # only for tests: we want (1) to test the calls to the C library,
         # but also (2) to work with multiple Python threads, so we acquire
@@ -43,9 +44,11 @@
         _global_lock.acquire()
         lltype.TLS.stm_callback_arg = arg
         llarg = lltype.nullptr(rffi.VOIDP.TO)
+        adr_of_top = llmemory.NULL
+    #
     callback = _get_stm_callback(func, argcls)
     llcallback = llhelper(StmOperations.CALLBACK_TX, callback)
-    StmOperations.perform_transaction(llcallback, llarg)
+    StmOperations.perform_transaction(llcallback, llarg, adr_of_top)
     keepalive_until_here(arg)
     if not we_are_translated():
         _global_lock.release()
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
@@ -128,8 +128,6 @@
         # transaction is aborted, the latter might never be called.
         # Be ready here to clean up any state.
         self._cleanup_state()
-        if self is not self.gc.main_thread_tls:
-            self.gc.root_walker.clear_current_stack_roots()
         if self.nursery_free:
             clear_size = self.nursery_free - self.nursery_start
         else:
diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -135,8 +135,6 @@
 class FakeRootWalker:
     def walk_current_stack_roots(self, *args):
         pass     # no stack roots in this test file
-    def clear_current_stack_roots(self):
-        pass
 
 
 class StmGCTests:
diff --git a/pypy/rpython/memory/gctransform/stmframework.py b/pypy/rpython/memory/gctransform/stmframework.py
--- a/pypy/rpython/memory/gctransform/stmframework.py
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -2,6 +2,7 @@
 from pypy.rpython.memory.gctransform.framework import BaseRootWalker
 from pypy.rpython.memory.gctransform.framework import sizeofaddr
 from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython import rmodel
 from pypy.annotation import model as annmodel
 from pypy.rlib.debug import fatalerror_notb
 from pypy.rlib.nonconst import NonConstant
@@ -50,6 +51,17 @@
     def build_root_walker(self):
         return StmShadowStackRootWalker(self)
 
+    def _gc_adr_of_gcdata_attr(self, hop, attrname):
+        x = self.root_walker.stackgcdata
+        c_const_stackgcdata = rmodel.inputconst(lltype.typeOf(x), x)
+        op = hop.spaceop
+        ofs = llmemory.offsetof(c_const_stackgcdata.concretetype.TO,
+                                attrname)
+        c_ofs = rmodel.inputconst(lltype.Signed, ofs)
+        v_gcdata_adr = hop.genop('cast_ptr_to_adr', [c_const_stackgcdata],
+                                 resulttype=llmemory.Address)
+        hop.genop('adr_add', [v_gcdata_adr, c_ofs], resultvar=op.result)
+
     def gct_stm_descriptor_init(self, hop):
         hop.genop("direct_call", [self.setup_secondary_thread_ptr,
                                   self.c_const_gc])
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
@@ -658,14 +658,20 @@
   return d->end_time;
 }
 
-void* stm_perform_transaction(void*(*callback)(void*, long), void *arg)
+void* stm_perform_transaction(void*(*callback)(void*, long), void *arg,
+                              void *save_and_restore)
 {
   void *result;
   jmp_buf _jmpbuf;
   volatile long v_counter = 0;
   long counter;
+  volatile void *saved_value;
   assert(active_thread_descriptor == NULL);
+  if (save_and_restore)
+    saved_value = *(void**)save_and_restore;
   setjmp(_jmpbuf);
+  if (save_and_restore)
+    *(void**)save_and_restore = saved_value;
   begin_transaction(&_jmpbuf);
   counter = v_counter;
   v_counter = counter + 1;
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
@@ -39,7 +39,7 @@
 #endif
 
 
-void* stm_perform_transaction(void*(*)(void*, long), void*);
+void* stm_perform_transaction(void*(*)(void*, long), void*, void*);
 void stm_enter_transactional_mode(void);
 void stm_leave_transactional_mode(void);
 void stm_try_inevitable(STM_CCHARP1(why));
diff --git a/pypy/translator/stm/stmgcintf.py b/pypy/translator/stm/stmgcintf.py
--- a/pypy/translator/stm/stmgcintf.py
+++ b/pypy/translator/stm/stmgcintf.py
@@ -80,7 +80,8 @@
 
     try_inevitable = smexternal('stm_try_inevitable', [], lltype.Void)
     perform_transaction = smexternal('stm_perform_transaction',
-                                     [CALLBACK_TX, rffi.VOIDP], rffi.VOIDP)
+                                     [CALLBACK_TX, rffi.VOIDP,
+                                      llmemory.Address], rffi.VOIDP)
     thread_id        = smexternal('stm_thread_id',       [], lltype.Signed)
     abort_and_retry  = smexternal('stm_abort_and_retry', [], lltype.Void)
 


More information about the pypy-commit mailing list