[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