Author: Brian Kearns <bdkea...@gmail.com> Branch: Changeset: r63026:75eddd236125 Date: 2013-04-04 17:11 -0400 http://bitbucket.org/pypy/pypy/changeset/75eddd236125/
Log: merge heads 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/jit/backend/x86/test/test_zrpy_releasegil.py b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py --- a/rpython/jit/backend/x86/test/test_zrpy_releasegil.py +++ b/rpython/jit/backend/x86/test/test_zrpy_releasegil.py @@ -68,10 +68,12 @@ c_qsort = rffi.llexternal('qsort', [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, CALLBACK], lltype.Void) # - def f42(): + def f42(n): length = len(glob.lst) raw = alloc1() fn = llhelper(CALLBACK, rffi._make_wrapper_for(CALLBACK, callback)) + if n & 1: # to create a loop and a bridge, and also + pass # to run the qsort() call in the blackhole interp c_qsort(rffi.cast(rffi.VOIDP, raw), rffi.cast(rffi.SIZE_T, 2), rffi.cast(rffi.SIZE_T, 8), fn) free1(raw) @@ -85,7 +87,7 @@ None, None, None, None, None, None) # def f(n, x, *args): - f42() + f42(n) n -= 1 return (n, x) + args return before, f, None 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 : \ _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit