def insert_stackcheck(ann): from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles edges = [] graphs_to_patch = {} for callposition, (caller, callee) in ann.translator.callgraph.items(): if getattr(getattr(callee, "func", None), "insert_stack_check_here", False): graphs_to_patch[callee] = True continue edge = Edge(caller, callee) edge.callposition = callposition edges.append(edge) for graph in graphs_to_patch: v = Variable() ann.setbinding(v, annmodel.SomeImpossibleValue()) unwind_op = SpaceOperation("simple_call", [Constant(stack_check)], v) graph.startblock.operations.insert(0, unwind_op) edgedict = make_edge_dict(edges) for edge in break_cycles(edgedict, edgedict): caller = edge.source _, _, call_tag = edge.callposition if call_tag: caller_block, _ = call_tag else: ann.warning("cycle detected but no information on where to insert " "stack_check()") continue # caller block found, insert stack_check() v = Variable() # push annotation on v ann.setbinding(v, annmodel.SomeImpossibleValue()) unwind_op = SpaceOperation("simple_call", [Constant(stack_check)], v) caller_block.operations.insert(0, unwind_op)
def insert_ll_stackcheck(translator): from pypy.translator.backendopt.support import find_calls_from from pypy.rpython.module.ll_stack import ll_stack_check from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles rtyper = translator.rtyper graph = rtyper.annotate_helper(ll_stack_check, []) rtyper.specialize_more_blocks() stack_check_ptr = rtyper.getcallable(graph) stack_check_ptr_const = Constant(stack_check_ptr, lltype.typeOf(stack_check_ptr)) edges = [] graphs_to_patch = {} insert_in = {} for caller in translator.graphs: for block, callee in find_calls_from(translator, caller): if getattr(getattr(callee, 'func', None), 'insert_stack_check_here', False): insert_in[callee.startblock] = True continue edge = Edge(caller, callee) edge.block = block edges.append(edge) edgedict = make_edge_dict(edges) for edge in break_cycles(edgedict, edgedict): block = edge.block insert_in[block] = True for block in insert_in: v = Variable() v.concretetype = lltype.Void unwind_op = SpaceOperation('direct_call', [stack_check_ptr_const], v) block.operations.insert(0, unwind_op)
def insert_stackcheck(ann): from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles edges = [] graphs_to_patch = {} for callposition, (caller, callee) in ann.translator.callgraph.items(): if getattr(getattr(callee, 'func', None), 'insert_stack_check_here', False): graphs_to_patch[callee] = True continue edge = Edge(caller, callee) edge.callposition = callposition edges.append(edge) for graph in graphs_to_patch: v = Variable() ann.setbinding(v, annmodel.SomeImpossibleValue()) unwind_op = SpaceOperation('simple_call', [Constant(stack_check)], v) graph.startblock.operations.insert(0, unwind_op) edgedict = make_edge_dict(edges) for edge in break_cycles(edgedict, edgedict): caller = edge.source _, _, call_tag = edge.callposition if call_tag: caller_block, _ = call_tag else: ann.warning("cycle detected but no information on where to insert " "stack_check()") continue # caller block found, insert stack_check() v = Variable() # push annotation on v ann.setbinding(v, annmodel.SomeImpossibleValue()) unwind_op = SpaceOperation('simple_call', [Constant(stack_check)], v) caller_block.operations.insert(0, unwind_op)
def insert_ll_stackcheck(translator): from pypy.translator.backendopt.support import find_calls_from from pypy.rlib.rstack import stack_check from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles rtyper = translator.rtyper graph = rtyper.annotate_helper(stack_check, []) rtyper.specialize_more_blocks() stack_check_ptr = rtyper.getcallable(graph) stack_check_ptr_const = Constant(stack_check_ptr, lltype.typeOf(stack_check_ptr)) edges = [] graphs_to_patch = {} insert_in = {} for caller in translator.graphs: for block, callee in find_calls_from(translator, caller): if getattr(getattr(callee, 'func', None), 'insert_stack_check_here', False): insert_in[callee.startblock] = True continue edge = Edge(caller, callee) edge.block = block edges.append(edge) edgedict = make_edge_dict(edges) for edge in break_cycles(edgedict, edgedict): block = edge.block insert_in[block] = True for block in insert_in: v = Variable() v.concretetype = lltype.Void unwind_op = SpaceOperation('direct_call', [stack_check_ptr_const], v) block.operations.insert(0, unwind_op) return len(insert_in)