[pypy-commit] pypy shadowstack-perf-2: Double-check using a very different algorithm
arigo
pypy.commits at gmail.com
Mon May 16 09:27:08 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-perf-2
Changeset: r84480:6d8934908ce2
Date: 2016-05-15 19:05 +0200
http://bitbucket.org/pypy/pypy/changeset/6d8934908ce2/
Log: Double-check using a very different algorithm
diff --git a/rpython/memory/gctransform/shadowcolor.py b/rpython/memory/gctransform/shadowcolor.py
--- a/rpython/memory/gctransform/shadowcolor.py
+++ b/rpython/memory/gctransform/shadowcolor.py
@@ -438,6 +438,81 @@
# new blocks made by insert_empty_block() earlier
+class PostProcessCheckError(Exception):
+ pass
+
+def postprocess_double_check(graph):
+ # Debugging only: double-check that the placement is correct.
+ # Assumes that every gc_restore_root() indicates that the variable
+ # must be saved at the given position in the shadowstack frame (in
+ # practice it may have moved because of the GC, but in theory it
+ # is still the "same" object). So we build the set of all known
+ # valid-in-all-paths saved locations, and check that.
+
+ saved = {} # {var-from-inputargs: location} where location is:
+ # <unset>: we haven't seen this variable so far
+ # set-of-indexes: says where the variable is always
+ # saved at the start of this block
+ # empty-set: same as above, so: "saved nowhere"
+
+ for v in graph.startblock.inputargs:
+ saved[v] = frozenset() # function arguments are not saved anywhere
+
+ pending = set([graph.startblock])
+ while pending:
+ block = pending.pop()
+ locsaved = {}
+ for v in block.inputargs:
+ locsaved[v] = saved[v]
+ for op in block.operations:
+ if op.opname == 'gc_restore_root':
+ if isinstance(op.args[1], Constant):
+ continue
+ num = op.args[0].value
+ if num not in locsaved[op.args[1]]:
+ raise PostProcessCheckError(graph, block, op, num, locsaved)
+ elif op.opname == 'gc_save_root':
+ num = op.args[0].value
+ v = op.args[1]
+ if isinstance(v, Variable):
+ locsaved[v] = locsaved[v].union([num])
+ else:
+ if v.concretetype != lltype.Signed:
+ locsaved[v] = locsaved.get(v, frozenset()).union([num])
+ continue
+ bitmask = v.value
+ if bitmask == 0:
+ bitmask = 1
+ assert bitmask & 1
+ assert bitmask < (2<<num)
+ nummask = [i for i in range(num+1)
+ if bitmask & (1<<(num-i))]
+ assert nummask[-1] == num
+ for v in locsaved:
+ locsaved[v] = locsaved[v].difference(nummask)
+ elif is_trivial_rewrite(op):
+ locsaved[op.result] = locsaved[op.args[0]]
+ else:
+ locsaved[op.result] = frozenset()
+ for link in block.exits:
+ changed = False
+ for i, v in enumerate(link.args):
+ try:
+ loc = locsaved[v]
+ except KeyError:
+ assert isinstance(v, Constant)
+ loc = frozenset()
+ w = link.target.inputargs[i]
+ if w in saved:
+ if loc == saved[w]:
+ continue # already up-to-date
+ loc = loc.intersection(saved[w])
+ saved[w] = loc
+ changed = True
+ if changed:
+ pending.add(link.target)
+
+
def postprocess_graph(graph, c_gcdata):
"""Collect information about the gc_push_roots and gc_pop_roots
added in this complete graph, and replace them with real operations.
@@ -448,3 +523,4 @@
expand_pop_roots(graph, regalloc)
add_enter_roots_frame(graph, regalloc, c_gcdata)
checkgraph(graph)
+ postprocess_double_check(graph)
diff --git a/rpython/memory/gctransform/test/test_shadowcolor.py b/rpython/memory/gctransform/test/test_shadowcolor.py
--- a/rpython/memory/gctransform/test/test_shadowcolor.py
+++ b/rpython/memory/gctransform/test/test_shadowcolor.py
@@ -336,6 +336,7 @@
assert len(graph.startblock.operations) == 1
assert graph.startblock.operations[0].opname == 'gc_save_root'
assert graph.startblock.operations[0].args[0].value == 0
+ postprocess_double_check(graph)
def test_move_pushes_earlier_2():
def g(a):
@@ -363,6 +364,7 @@
'int_sub': 1,
'direct_call': 2,
}
+ postprocess_double_check(graph)
def test_remove_intrablock_push_roots():
def g(a):
@@ -416,6 +418,7 @@
'int_sub': 1,
'direct_call': 2,
}
+ postprocess_double_check(graph)
def test_move_pushes_earlier_rename_2():
def g(a):
@@ -445,6 +448,7 @@
'int_sub': 1,
'direct_call': 2,
}
+ postprocess_double_check(graph)
def test_move_pushes_earlier_rename_3():
def g(a):
@@ -476,6 +480,7 @@
'int_sub': 2,
'direct_call': 2,
}
+ postprocess_double_check(graph)
def test_move_pushes_earlier_rename_4():
def g(a):
@@ -515,3 +520,4 @@
'int_sub': 3,
'direct_call': 2,
}
+ postprocess_double_check(graph)
More information about the pypy-commit
mailing list