Author: Armin Rigo <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit