Author: Armin Rigo <ar...@tunes.org> Branch: shadowstack-perf Changeset: r46028:175ad120b085 Date: 2011-07-27 20:01 +0200 http://bitbucket.org/pypy/pypy/changeset/175ad120b085/
Log: Improve the generated code somewhat. 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 @@ -483,9 +483,6 @@ 'gc_dump_rpy_heap' : LLOp(), 'gc_typeids_z' : LLOp(), - '_d_incr': LLOp(sideeffects=False), - '_d_decr': LLOp(sideeffects=False), - # ------- JIT & GC interaction, only for some GCs ---------- 'gc_adr_of_nursery_free' : LLOp(), diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py --- a/pypy/rpython/memory/gctransform/framework.py +++ b/pypy/rpython/memory/gctransform/framework.py @@ -243,21 +243,16 @@ annmodel.s_None) if root_walker.need_root_stack: - self.incr_stack_ptr = getfn(root_walker.incr_stack, - [annmodel.SomeInteger()], - annmodel.SomeAddress(), - inline = True) - self.decr_stack_ptr = getfn(root_walker.decr_stack, - [annmodel.SomeInteger()], - annmodel.SomeAddress(), - inline = True) self.get_stack_top_ptr = getfn(root_walker.get_stack_top, [], annmodel.SomeAddress(), inline = True) + self.set_stack_top_ptr = getfn(root_walker.set_stack_top, + [annmodel.SomeAddress()], + annmodel.s_None, + inline = True) else: - self.incr_stack_ptr = None - self.decr_stack_ptr = None self.get_stack_top_ptr = None + self.set_stack_top_ptr = None self.weakref_deref_ptr = self.inittime_helper( ll_weakref_deref, [llmemory.WeakRefPtr], llmemory.Address) @@ -1191,7 +1186,7 @@ return livevars def push_roots(self, hop, keep_current_args=False): - if self.incr_stack_ptr is None: + if self.get_stack_top_ptr is None: return livevars = self.get_livevars_for_roots(hop, keep_current_args) if livevars: @@ -1200,7 +1195,7 @@ return livevars def pop_roots(self, hop, livevars): - if self.decr_stack_ptr is None: + if self.get_stack_top_ptr is None: return if livevars: hop.genop("gc_pop_roots", livevars) diff --git a/pypy/rpython/memory/gctransform/shadowstack.py b/pypy/rpython/memory/gctransform/shadowstack.py --- a/pypy/rpython/memory/gctransform/shadowstack.py +++ b/pypy/rpython/memory/gctransform/shadowstack.py @@ -6,7 +6,7 @@ from pypy.rpython.lltypesystem import lltype, llmemory from pypy.tool.algo.regalloc import perform_register_allocation from pypy.translator.backendopt.ssa import DataFlowFamilyBuilder -from pypy.translator.unsimplify import copyvar, insert_empty_block +from pypy.translator.unsimplify import insert_empty_block, varoftype from pypy.objspace.flow.model import Block, Link, Constant from pypy.objspace.flow.model import checkgraph, mkentrymap from pypy.annotation import model as annmodel @@ -22,22 +22,14 @@ # NB. 'self' is frozen, but we can use self.gcdata to store state gcdata = self.gcdata - def incr_stack(n): - top = gcdata.root_stack_top - gcdata.root_stack_top = top + n*sizeofaddr - return top - self.incr_stack = incr_stack - - def decr_stack(n): - top = gcdata.root_stack_top - n*sizeofaddr - gcdata.root_stack_top = top - return top - self.decr_stack = decr_stack - def get_stack_top(): return gcdata.root_stack_top self.get_stack_top = get_stack_top + def set_stack_top(addr): + gcdata.root_stack_top = addr + self.set_stack_top = set_stack_top + self.rootstackhook = gctransformer.root_stack_jit_hook if self.rootstackhook is None: def collect_stack_root(callback, gc, addr): @@ -47,11 +39,13 @@ self.rootstackhook = collect_stack_root def push_stack(self, addr): - top = self.incr_stack(1) + top = self.get_stack_top() top.address[0] = addr + self.set_stack_top(top + sizeofaddr) def pop_stack(self): - top = self.decr_stack(1) + top = self.get_stack_top() - sizeofaddr + self.set_stack_top(top) return top.address[0] def allocate_stack(self): @@ -265,6 +259,15 @@ # operations raw_store/raw_load blocks_push_roots = {} # {block: index-of-the-first} blocks_pop_roots = {} # {block: index-just-after-the-last} + topaddrs_v = {} # {block: (index-of-first-use, v_topaddr)} + # + def get_v_topaddr(block, firstuse=0): + if block in topaddrs_v: + return topaddrs_v[block][1] + v_topaddr = varoftype(llmemory.Address, 'top') + topaddrs_v[block] = (firstuse, v_topaddr) + return v_topaddr + # negnumcolors = 0 c_type = rmodel.inputconst(lltype.Void, llmemory.Address) for block in graph.iterblocks(): @@ -275,32 +278,27 @@ if op.opname not in ("gc_push_roots", "gc_pop_roots"): llops.append(op) continue - top_addr = None for v in op.args: if isinstance(v, Constant): continue - if op.opname == "gc_push_roots": - blocks_push_roots.setdefault(block, len(llops)) - if top_addr is None: - top_addr = llops.genop("direct_call", - [gct.get_stack_top_ptr], - resulttype=llmemory.Address) + v_topaddr = get_v_topaddr(block, firstuse=len(llops)) k = ~regalloc.getcolor(v) negnumcolors = min(negnumcolors, k) c_k = rmodel.inputconst(lltype.Signed, k) if op.opname == "gc_push_roots": + blocks_push_roots.setdefault(block, len(llops)) if (block, op, v) not in useless_stores: - llops.genop("raw_store", [top_addr, c_type, + llops.genop("raw_store", [v_topaddr, c_type, c_k, v]) else: v_newaddr = llops.genop("raw_load", - [top_addr, c_type, c_k], + [v_topaddr, c_type, c_k], resulttype=llmemory.Address) llops.genop("gc_reload_possibly_moved", [v_newaddr, v]) blocks_pop_roots[block] = len(llops) block.operations[:] = llops numcolors = -negnumcolors - c_numcolors = rmodel.inputconst(lltype.Signed, numcolors) + c_framesize = rmodel.inputconst(lltype.Signed, numcolors * sizeofaddr) # # For each block, determine in which category it is: # @@ -391,28 +389,37 @@ for block in blockstate: if "stop" in blockstate[block]: # "stop" or "startstop" llops = LowLevelOpList() - llops.genop("direct_call", [gct.decr_stack_ptr, c_numcolors], - resulttype=llmemory.Address) i = blocks_pop_roots[block] - llops.genop("_d_decr", []) + v_topaddr = get_v_topaddr(block, firstuse=i) + v_baseaddr = llops.genop("adr_sub", [v_topaddr, c_framesize], + resulttype=llmemory.Address) + llops.genop("direct_call", [gct.set_stack_top_ptr, v_baseaddr]) block.operations[i:i] = llops # ^^^ important: done first, in case it's a startstop block, # otherwise the index in 'blocks_push_roots[block]' is # off by one if "start" in blockstate[block]: # "start" or "startstop" llops = LowLevelOpList() - llops.genop("_d_incr", []) - llops.genop("direct_call", [gct.incr_stack_ptr, c_numcolors], - resulttype=llmemory.Address) - top_addr = llops.genop("direct_call", - [gct.get_stack_top_ptr], - resulttype=llmemory.Address) + v_topaddr = get_v_topaddr(block) + v_baseaddr = llops.genop("direct_call",[gct.get_stack_top_ptr], + resulttype=llmemory.Address) + llops.genop("adr_add", [v_baseaddr, c_framesize]) + llops[-1].result = v_topaddr + llops.genop("direct_call", [gct.set_stack_top_ptr, v_topaddr]) c_null = rmodel.inputconst(llmemory.Address, llmemory.NULL) for k in range(numcolors): c_k = rmodel.inputconst(lltype.Signed, ~k) - llops.genop("raw_store", [top_addr, c_type, c_k, c_null]) + llops.genop("raw_store", [v_topaddr, c_type, c_k, c_null]) i = blocks_push_roots[block] block.operations[i:i] = llops + else: + if block in topaddrs_v: + # we need to get the current stack top for this block + i, topaddr_v = topaddrs_v[block] + llops = LowLevelOpList() + llops.genop("direct_call", [gct.get_stack_top_ptr]) + llops[-1].result = topaddr_v + block.operations[i:i] = llops # checkgraph(graph) diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py --- a/pypy/translator/c/funcgen.py +++ b/pypy/translator/c/funcgen.py @@ -210,7 +210,6 @@ def cfunction_body(self): graph = self.graph - yield 'void *dbg=0;' yield 'goto block0;' # to avoid a warning "this label is not used" # generate the body of each block 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 @@ -246,9 +246,3 @@ #define OP_GC_GET_RPY_TYPE_INDEX(x, r) r = -1 #define OP_GC_IS_RPY_INSTANCE(x, r) r = 0 #define OP_GC_DUMP_RPY_HEAP(fd, r) r = 0 - - - - -#define OP__D_INCR(r) assert(!dbg); dbg = (&pypy_g_pypy_rpython_memory_gctypelayout_GCData)->gcd_inst_root_stack_top -#define OP__D_DECR(r) assert(dbg==(&pypy_g_pypy_rpython_memory_gctypelayout_GCData)->gcd_inst_root_stack_top); dbg = 0 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit