[pypy-commit] pypy shadowstack-perf-2: Improve the final checking logic and add a failing test (from looking at pypy)
arigo
pypy.commits at gmail.com
Tue May 17 05:54:02 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-perf-2
Changeset: r84506:73b76c96f2ae
Date: 2016-05-17 11:54 +0200
http://bitbucket.org/pypy/pypy/changeset/73b76c96f2ae/
Log: Improve the final checking logic and add a failing test (from
looking at pypy)
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
@@ -566,6 +566,10 @@
if left:
raise PostProcessCheckError(graph, block, op, 'left!')
num = op.args[0].value
+ # first, cancel any other variable that would be saved in 'num'
+ for v in locsaved:
+ locsaved[v] = locsaved[v].difference([num])
+ #
v = op.args[1]
if isinstance(v, Variable):
locsaved[v] = locsaved[v].union([num])
@@ -574,15 +578,16 @@
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)
+ if bitmask != 0:
+ # cancel any variable that would be saved in any
+ # position shown by the bitmask, not just 'num'
+ 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 op.opname == 'gc_leave_roots_frame':
if left:
raise PostProcessCheckError(graph, block, op, 'left!')
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
@@ -594,3 +594,80 @@
'gc_leave_roots_frame',
'direct_call']
postprocess_double_check(graph, force_frame=True)
+
+def test_bug_1():
+ class W:
+ pass
+ def foo(a):
+ if a < 10:
+ return W()
+ else:
+ return None
+ def compare(w_a, w_b):
+ return W()
+ def fetch_compare(w_a, w_b):
+ return W()
+ def is_true(a, w_b):
+ return not a
+ def call_next(w_a):
+ return W()
+
+ def f(a, w_tup):
+ llop.gc_push_roots(lltype.Void, w_tup)
+ w_key = foo(a)
+ llop.gc_pop_roots(lltype.Void, w_tup)
+
+ llop.gc_push_roots(lltype.Void, w_tup, w_key)
+ w_iter = foo(a)
+ llop.gc_pop_roots(lltype.Void, w_tup, w_key)
+
+ has_key = w_key is not None
+ has_item = False
+ w_max_item = None
+ w_max_val = None
+
+ while True:
+ llop.gc_push_roots(lltype.Void, w_tup, w_key, w_max_item, w_max_val)
+ w_item = call_next(w_iter)
+ llop.gc_pop_roots(lltype.Void, w_tup, w_key, w_max_item, w_max_val)
+
+ if has_key:
+ llop.gc_push_roots(lltype.Void, w_tup, w_key,
+ w_max_item, w_max_val, w_item)
+ w_compare_with = fetch_compare(w_key, w_item)
+ llop.gc_pop_roots(lltype.Void, w_tup, w_key,
+ w_max_item, w_max_val, w_item)
+ else:
+ w_compare_with = w_item
+
+ if has_item:
+ llop.gc_push_roots(lltype.Void, w_tup, w_key,
+ w_max_item, w_max_val, w_item, w_compare_with)
+ w_bool = compare(w_compare_with, w_max_val)
+ llop.gc_pop_roots(lltype.Void, w_tup, w_key,
+ w_max_item, w_max_val, w_item, w_compare_with)
+
+ llop.gc_push_roots(lltype.Void, w_tup, w_key,
+ w_max_item, w_max_val, w_item, w_compare_with)
+ condition = is_true(a, w_bool)
+ llop.gc_pop_roots(lltype.Void, w_tup, w_key,
+ w_max_item, w_max_val, w_item, w_compare_with)
+ else:
+ condition = True
+
+ if condition:
+ has_item = True
+ w_max_item = w_item
+ w_max_val = w_compare_with
+
+ return w_max_item
+
+ graph = make_graph(f, [int, llmemory.GCREF])
+ regalloc = allocate_registers(graph)
+ expand_push_roots(graph, regalloc)
+ move_pushes_earlier(graph, regalloc)
+ expand_pop_roots(graph, regalloc)
+ add_leave_roots_frame(graph, regalloc)
+ join_blocks(graph)
+ postprocess_double_check(graph, force_frame=True)
+ graph.show()
More information about the pypy-commit
mailing list