[pypy-commit] pypy default: Fixes fixes fixes. Now test_zrpy_releasegil passes, and other

arigo noreply at buildbot.pypy.org
Thu Apr 4 23:09:45 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r63023:a31ea3dedb23
Date: 2013-04-04 23:09 +0200
http://bitbucket.org/pypy/pypy/changeset/a31ea3dedb23/

Log:	Fixes fixes fixes. Now test_zrpy_releasegil passes, and other
	previously-broken tests too.

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
@@ -554,8 +554,8 @@
         from pypy.module.cpyext.pyobject import Reference
         # we hope that malloc removal removes the newtuple() that is
         # inserted exactly here by the varargs specializer
+        rffi.stackcounter.stacks_counter += 1
         llop.gc_stack_bottom(lltype.Void)   # marker for trackgcroot.py
-        rffi.stackcounter.stacks_counter += 1
         retval = fatal_value
         boxed_args = ()
         try:
diff --git a/rpython/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py
--- a/rpython/memory/gctransform/asmgcroot.py
+++ b/rpython/memory/gctransform/asmgcroot.py
@@ -1,13 +1,15 @@
 from rpython.flowspace.model import (Constant, Variable, Block, Link,
-     copygraph, SpaceOperation)
+     copygraph, SpaceOperation, checkgraph)
 from rpython.rlib.debug import ll_assert
+from rpython.rlib.nonconst import NonConstant
 from rpython.rtyper.annlowlevel import llhelper
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.memory.gctransform.framework import (
      BaseFrameworkGCTransformer, BaseRootWalker)
 from rpython.rtyper.rbuiltin import gen_cast
-from rpython.translator.unsimplify import copyvar
+from rpython.translator.unsimplify import copyvar, varoftype
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
 import sys
 
 
@@ -22,6 +24,7 @@
 
 class AsmGcRootFrameworkGCTransformer(BaseFrameworkGCTransformer):
     _asmgcc_save_restore_arguments = None
+    _seen_gctransformer_hint_close_stack = None
 
     def push_roots(self, hop, keep_current_args=False):
         livevars = self.get_livevars_for_roots(hop, keep_current_args)
@@ -57,10 +60,22 @@
 
     def handle_call_with_close_stack(self, hop):
         fnptr = hop.spaceop.args[0].value
+        if self._seen_gctransformer_hint_close_stack is None:
+            self._seen_gctransformer_hint_close_stack = {}
+        if fnptr._obj.graph not in self._seen_gctransformer_hint_close_stack:
+            self._transform_hint_close_stack(fnptr)
+            self._seen_gctransformer_hint_close_stack[fnptr._obj.graph] = True
+        #
+        livevars = self.push_roots(hop)
+        self.default(hop)
+        self.pop_roots(hop, livevars)
+
+    def _transform_hint_close_stack(self, fnptr):
         # We cannot easily pass variable amount of arguments of the call
         # across the call to the pypy_asm_stackwalk helper.  So we store
-        # them away and restore them.  We need to make a new graph
-        # that starts with restoring the arguments.
+        # them away and restore them.  More precisely, we need to
+        # replace 'graph' with code that saves the arguments, and make
+        # a new graph that starts with restoring the arguments.
         if self._asmgcc_save_restore_arguments is None:
             self._asmgcc_save_restore_arguments = {}
         sradict = self._asmgcc_save_restore_arguments
@@ -80,25 +95,52 @@
                 sradict[key] = Constant(p, lltype.Ptr(CONTAINER))
             sra.append(sradict[key])
         #
-        # store the value of the arguments
-        livevars = self.push_roots(hop)
+        # make a copy of the graph that will reload the values
+        graph = fnptr._obj.graph
+        graph2 = copygraph(graph)
+        #
+        # edit the original graph to only store the value of the arguments
+        block = Block(graph.startblock.inputargs)
         c_item0 = Constant('item0', lltype.Void)
-        for v_arg, c_p in zip(hop.spaceop.args[1:], sra):
+        assert len(block.inputargs) == len(sra)
+        for v_arg, c_p in zip(block.inputargs, sra):
             if isinstance(v_arg.concretetype, lltype.Ptr):
-                v_arg = hop.genop("cast_ptr_to_adr", [v_arg],
-                                  resulttype=llmemory.Address)
-            hop.genop("bare_setfield", [c_p, c_item0, v_arg])
+                v_adr = varoftype(llmemory.Address)
+                block.operations.append(
+                    SpaceOperation("cast_ptr_to_adr", [v_arg], v_adr))
+                v_arg = v_adr
+            v_void = varoftype(lltype.Void)
+            block.operations.append(
+                SpaceOperation("bare_setfield", [c_p, c_item0, v_arg], v_void))
         #
-        # make a copy of the graph that will reload the values
-        graph2 = copygraph(fnptr._obj.graph)
+        # call asm_stackwalk(graph2)
+        FUNC2 = lltype.FuncType([], FUNC1.RESULT)
+        fnptr2 = lltype.functionptr(FUNC2,
+                                    fnptr._obj._name + '_reload',
+                                    graph=graph2)
+        c_fnptr2 = Constant(fnptr2, lltype.Ptr(FUNC2))
+        HELPERFUNC = lltype.FuncType([lltype.Ptr(FUNC2),
+                                      ASM_FRAMEDATA_HEAD_PTR], FUNC1.RESULT)
+        v_asm_stackwalk = varoftype(lltype.Ptr(HELPERFUNC), "asm_stackwalk")
+        block.operations.append(
+            SpaceOperation("cast_pointer", [c_asm_stackwalk], v_asm_stackwalk))
+        v_result = varoftype(FUNC1.RESULT)
+        block.operations.append(
+            SpaceOperation("indirect_call", [v_asm_stackwalk, c_fnptr2,
+                                             c_gcrootanchor,
+                                             Constant(None, lltype.Void)],
+                           v_result))
+        block.closeblock(Link([v_result], graph.returnblock))
+        graph.startblock = block
+        #
+        # edit the copy of the graph to reload the values
         block2 = graph2.startblock
         block1 = Block([])
         reloadedvars = []
         for v, c_p in zip(block2.inputargs, sra):
             v = copyvar(None, v)
             if isinstance(v.concretetype, lltype.Ptr):
-                w = Variable('tmp')
-                w.concretetype = llmemory.Address
+                w = varoftype(llmemory.Address)
             else:
                 w = v
             block1.operations.append(SpaceOperation('getfield',
@@ -109,21 +151,9 @@
             reloadedvars.append(v)
         block1.closeblock(Link(reloadedvars, block2))
         graph2.startblock = block1
-        FUNC2 = lltype.FuncType([], FUNC1.RESULT)
-        fnptr2 = lltype.functionptr(FUNC2,
-                                    fnptr._obj._name + '_reload',
-                                    graph=graph2)
-        c_fnptr2 = Constant(fnptr2, lltype.Ptr(FUNC2))
-        HELPERFUNC = lltype.FuncType([lltype.Ptr(FUNC2),
-                                      ASM_FRAMEDATA_HEAD_PTR], FUNC1.RESULT)
         #
-        v_asm_stackwalk = hop.genop("cast_pointer", [c_asm_stackwalk],
-                                    resulttype=lltype.Ptr(HELPERFUNC))
-        hop.genop("indirect_call",
-                  [v_asm_stackwalk, c_fnptr2, c_gcrootanchor,
-                   Constant(None, lltype.Void)],
-                  resultvar=hop.spaceop.result)
-        self.pop_roots(hop, livevars)
+        checkgraph(graph)
+        checkgraph(graph2)
 
 
 class AsmStackRootWalker(BaseRootWalker):
@@ -284,6 +314,8 @@
             stackscount += 1
         #
         expected = rffi.stackcounter.stacks_counter
+        if NonConstant(0):
+            rffi.stackcounter.stacks_counter += 42    # hack to force it
         ll_assert(not (stackscount < expected), "non-closed stacks around")
         ll_assert(not (stackscount > expected), "stacks counter corruption?")
         lltype.free(otherframe, flavor='raw')
@@ -681,13 +713,16 @@
 gcrootanchor.next = gcrootanchor
 c_gcrootanchor = Constant(gcrootanchor, ASM_FRAMEDATA_HEAD_PTR)
 
+eci = ExternalCompilationInfo(pre_include_bits=['#define PYPY_USE_ASMGCC'])
+
 pypy_asm_stackwalk = rffi.llexternal('pypy_asm_stackwalk',
                                      [ASM_CALLBACK_PTR,
                                       ASM_FRAMEDATA_HEAD_PTR],
                                      lltype.Signed,
                                      sandboxsafe=True,
                                      _nowrapper=True,
-                                     random_effects_on_gcobjs=True)
+                                     random_effects_on_gcobjs=True,
+                                     compilation_info=eci)
 c_asm_stackwalk = Constant(pypy_asm_stackwalk,
                            lltype.typeOf(pypy_asm_stackwalk))
 
diff --git a/rpython/translator/c/gcc/test/test_asmgcroot.py b/rpython/translator/c/gcc/test/test_asmgcroot.py
--- a/rpython/translator/c/gcc/test/test_asmgcroot.py
+++ b/rpython/translator/c/gcc/test/test_asmgcroot.py
@@ -195,8 +195,8 @@
         
         @entrypoint("x42", [lltype.Signed, lltype.Signed], c_name='callback')
         def mycallback(a, b):
+            rffi.stackcounter.stacks_counter += 1
             llop.gc_stack_bottom(lltype.Void)
-            rffi.stackcounter.stacks_counter += 1
             gc.collect()
             rffi.stackcounter.stacks_counter -= 1
             return a + b
diff --git a/rpython/translator/c/src/mem.c b/rpython/translator/c/src/mem.c
--- a/rpython/translator/c/src/mem.c
+++ b/rpython/translator/c/src/mem.c
@@ -96,3 +96,27 @@
     GC_set_warn_proc(mem_boehm_ignore);
 }
 #endif /* BOEHM GC */
+
+
+#ifdef RPY_ASSERT
+# ifdef PYPY_USE_ASMGCC
+#  include "structdef.h"
+#  include "forwarddecl.h"
+# endif
+void pypy_check_stack_count(void)
+{
+# ifdef PYPY_USE_ASMGCC
+    void *anchor = (void*)&pypy_g_ASM_FRAMEDATA_HEAD;
+    void *fd = ((void* *) (((char *)anchor) + sizeof(void*)))[0];
+    long got = 0;
+    long stacks_counter =
+       pypy_g_rpython_rtyper_lltypesystem_rffi_StackCounter.sc_inst_stacks_counter;
+    while (fd != anchor) {
+        got += 1;
+        fd = ((void* *) (((char *)fd) + sizeof(void*)))[0];
+    }
+    RPyAssert(got == stacks_counter - 1,
+              "bad stacks_counter or non-closed stacks around");
+# endif
+}
+#endif
diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h
--- a/rpython/translator/c/src/mem.h
+++ b/rpython/translator/c/src/mem.h
@@ -195,24 +195,14 @@
                                              "g" (v))
 
 /* marker for trackgcroot.py, and inhibits tail calls */
-#define pypy_asm_stack_bottom()  { asm volatile ("/* GC_STACK_BOTTOM */" : : : \
-                                   "memory"); pypy_check_stack_count(); }
+#define pypy_asm_stack_bottom() { asm volatile ("/* GC_STACK_BOTTOM */" : : : \
+                                  "memory"); pypy_check_stack_count(); }
+#ifdef RPY_ASSERT
+void pypy_check_stack_count(void);
+#else
+static void pypy_check_stack_count(void) { }
+#endif
 
-static void pypy_check_stack_count(void)
-{
-#ifdef RPY_ASSERT
-    void *anchor = (void*)&pypy_g_ASM_FRAMEDATA_HEAD;
-    void *fd = ((void* *) (((char *)anchor) + sizeof(void*)))[0];
-    long got = 0;
-    long stacks_counter =
-       (&pypy_g_rpython_rtyper_lltypesystem_rffi_StackCounter)->sc_inst_stacks_counter;
-    while (fd != anchor) {
-        got += 1;
-        fd = ((void* *) (((char *)fd) + sizeof(void*)))[0];
-    }
-    assert(got == stacks_counter - 1);
-#endif
-}
 
 #define OP_GC_ASMGCROOT_STATIC(i, r)   r =	       \
 	i == 0 ? (void*)&__gcmapstart :		       \


More information about the pypy-commit mailing list