[pypy-commit] pypy r15-for-exception: Hopefully fix all remaining places that are involved in C callbacks

arigo noreply at buildbot.pypy.org
Sat Jul 9 16:03:26 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: r15-for-exception
Changeset: r45436:5c84150482d2
Date: 2011-07-09 16:12 +0200
http://bitbucket.org/pypy/pypy/changeset/5c84150482d2/

Log:	Hopefully fix all remaining places that are involved in C callbacks
	(including multi-threading). Simplify a bit the approach, with an
	explicit 'saved' value to carry around the callback's code.

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -498,12 +498,13 @@
 
     @specialize.ll()
     def wrapper(*args):
+        from pypy.rpython.lltypesystem import llmemory
         from pypy.module.cpyext.pyobject import make_ref, from_ref
         from pypy.module.cpyext.pyobject import Reference
         # we hope that malloc removal removes the newtuple() that is
         # inserted exactly here by the varargs specializer
-        llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
         rffi.stackcounter.stacks_counter += 1
+        saved = llop.gc_stack_bottom(llmemory.Address)   # for trackgcroot.py
         retval = fatal_value
         boxed_args = ()
         try:
@@ -572,6 +573,7 @@
             else:
                 print str(e)
                 pypy_debug_catch_fatal_exception()
+        llop.gc_stack_bottom_stop(lltype.Void, saved)
         rffi.stackcounter.stacks_counter -= 1
         return retval
     callable._always_inline_ = True
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -891,9 +891,6 @@
     def op_gc_asmgcroot_static(self, index):
         raise NotImplementedError("gc_asmgcroot_static")
 
-    def op_gc_stack_bottom(self):
-        pass       # marker for trackgcroot.py
-
     def op_gc_get_type_info_group(self):
         raise NotImplementedError("gc_get_type_info_group")
 
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -503,6 +503,7 @@
     # see translator/c/src/mem.h for the valid indices
     'gc_asmgcroot_static':  LLOp(sideeffects=False),
     'gc_stack_bottom':      LLOp(canrun=True),
+    'gc_stack_bottom_stop': LLOp(canrun=True),
 
     # NOTE NOTE NOTE! don't forget *** canunwindgc=True *** for anything that
     # can go through a stack unwind, in particular anything that mallocs!
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -527,7 +527,10 @@
     return debug.have_debug_prints()
 
 def op_gc_stack_bottom():
-    pass       # marker for trackgcroot.py
+    return llmemory.NULL       # marker for trackgcroot.py
+
+def op_gc_stack_bottom_stop(saved):
+    pass                       # for rlib/register.py
 
 def op_jit_force_virtualizable(*args):
     pass
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -248,7 +248,7 @@
     """ Function creating wrappers for callbacks. Note that this is
     cheating as we assume constant callbacks and we just memoize wrappers
     """
-    from pypy.rpython.lltypesystem import lltype
+    from pypy.rpython.lltypesystem import lltype, llmemory
     from pypy.rpython.lltypesystem.lloperation import llop
     if hasattr(callable, '_errorcode_'):
         errorcode = callable._errorcode_
@@ -260,13 +260,15 @@
     args = ', '.join(['a%d' % i for i in range(len(TP.TO.ARGS))])
     source = py.code.Source(r"""
         def wrapper(%s):    # no *args - no GIL for mallocing the tuple
-            llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
             if aroundstate is not None:
                 after = aroundstate.after
                 if after:
                     after()
             # from now on we hold the GIL
             stackcounter.stacks_counter += 1
+            # marker for trackgcroot.py and for rlib/register.py:
+            # initialize the value of the special register
+            saved = llop.gc_stack_bottom(llmemory.Address)
             try:
                 result = callable(%s)
             except Exception, e:
@@ -277,6 +279,7 @@
                     import traceback
                     traceback.print_exc()
                 result = errorcode
+            llop.gc_stack_bottom_stop(lltype.Void, saved)
             stackcounter.stacks_counter -= 1
             if aroundstate is not None:
                 before = aroundstate.before
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -104,9 +104,6 @@
     def OP_GC_ASSUME_YOUNG_POINTERS(self, funcgen, op):
         return ''
 
-    def OP_GC_STACK_BOTTOM(self, funcgen, op):
-        return ''
-
 
 class RefcountingInfo:
     static_deallocator = None
@@ -397,9 +394,6 @@
     def GC_KEEPALIVE(self, funcgen, v):
         return 'pypy_asm_keepalive(%s);' % funcgen.expr(v)
 
-    def OP_GC_STACK_BOTTOM(self, funcgen, op):
-        return 'pypy_asm_stack_bottom();'
-
 
 name_to_gcpolicy = {
     'boehm': BoehmGcPolicy,
diff --git a/pypy/translator/c/gcc/test/test_asmgcroot.py b/pypy/translator/c/gcc/test/test_asmgcroot.py
--- a/pypy/translator/c/gcc/test/test_asmgcroot.py
+++ b/pypy/translator/c/gcc/test/test_asmgcroot.py
@@ -6,7 +6,7 @@
 from pypy.annotation.listdef import s_list_of_strings
 from pypy import conftest
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rlib.entrypoint import entrypoint, secondary_entrypoints
 from pypy.rpython.lltypesystem.lloperation import llop
 
@@ -180,9 +180,10 @@
         
         @entrypoint("x42", [lltype.Signed, lltype.Signed], c_name='callback')
         def mycallback(a, b):
-            llop.gc_stack_bottom(lltype.Void)
             rffi.stackcounter.stacks_counter += 1
+            saved = llop.gc_stack_bottom(llmemory.Address)
             gc.collect()
+            llop.gc_stack_bottom_stop(lltype.Void, saved)
             rffi.stackcounter.stacks_counter -= 1
             return a + b
 
diff --git a/pypy/translator/c/src/main.h b/pypy/translator/c/src/main.h
--- a/pypy/translator/c/src/main.h
+++ b/pypy/translator/c/src/main.h
@@ -34,12 +34,9 @@
     char *errmsg;
     int i, exitcode;
     RPyListOfString *list;
-#ifdef PYPY_GET_SPECIAL_REG
-    void *pypy_reg_oldvalue = PYPY_GET_SPECIAL_REG();
-    PYPY_SET_SPECIAL_REG((void*)-1);
-#endif
+    void *saved;
 
-    pypy_asm_stack_bottom();
+    OP_GC_STACK_BOTTOM(saved);
     instrument_setup();
 
     if (sizeof(void*) != SIZEOF_LONG) {
@@ -74,10 +71,7 @@
         pypy_debug_catch_fatal_exception();
     }
 
-#ifdef PYPY_GET_SPECIAL_REG
-    PYPY_SET_SPECIAL_REG(pypy_reg_oldvalue);
-#endif
-
+    OP_GC_STACK_BOTTOM_STOP(saved, /*nothing*/);
     return exitcode;
 
  memory_out:
diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h
--- a/pypy/translator/c/src/mem.h
+++ b/pypy/translator/c/src/mem.h
@@ -84,6 +84,17 @@
 #endif
 
 
+#ifdef PYPY_GET_SPECIAL_REG      /* pypy/rlib/register.py */
+#  define OP_GC_STACK_BOTTOM(r)        pypy_asm_stack_bottom();        \
+                                       r = PYPY_GET_SPECIAL_REG();     \
+                                       PYPY_SET_SPECIAL_REG((void*)-1)
+#  define OP_GC_STACK_BOTTOM_STOP(v,r) PYPY_SET_SPECIAL_REG(v)
+#else
+#  define OP_GC_STACK_BOTTOM(r)         pypy_asm_stack_bottom()
+#  define OP_GC_STACK_BOTTOM_STOP(v,r)  /* nothing */
+#endif
+
+
 /* used by pypy.rlib.rstack, but also by asmgcc */
 #define OP_STACK_CURRENT(r)  r = (long)&r
 


More information about the pypy-commit mailing list