Author: Armin Rigo <ar...@tunes.org>
Branch: shadowstack-perf-2
Changeset: r84387:5b47be0086d7
Date: 2016-05-11 20:49 +0200
http://bitbucket.org/pypy/pypy/changeset/5b47be0086d7/

Log:    expand_pop_roots

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
@@ -113,6 +113,11 @@
     return SpaceOperation('gc_save_root', [c_index, var],
                           varoftype(lltype.Void))
 
+def _gc_restore_root(index, var):
+    c_index = Constant(index, lltype.Signed)
+    return SpaceOperation('gc_restore_root', [c_index, var],
+                          varoftype(lltype.Void))
+
 c_NULL = Constant(lltype.nullptr(llmemory.GCREF.TO), llmemory.GCREF)
 
 def make_bitmask(filled):
@@ -128,6 +133,7 @@
             bitmask <<= (i - last_index)
             last_index = i
             bitmask |= 1
+    assert bitmask & 1
     return (last_index, Constant(bitmask, lltype.Signed))
 
 
@@ -141,14 +147,23 @@
             assert not filled[index]
             filled[index] = True
             yield _gc_save_root(index, v)
-        bitmask_index, bitmask_v = make_bitmask(filled)
+        bitmask_index, bitmask_c = make_bitmask(filled)
         if bitmask_index is not None:
-            yield _gc_save_root(bitmask_index, bitmask_v)
+            yield _gc_save_root(bitmask_index, bitmask_c)
+
+def expand_one_pop_roots(regalloc, args):
+    if regalloc is None:
+        assert len(args) == 0
+    else:
+        for v in args:
+            index = regalloc.getcolor(v)
+            yield _gc_restore_root(index, v)
 
 
 def expand_push_roots(graph, regalloc):
     """Expand gc_push_roots into a series of gc_save_root, including
-    writing a bitmask tag to mark some entries as not-in-use
+    writing a bitmask tag to mark some entries as not-in-use.
+    (If regalloc is None, it will still remove empty gc_push_roots.)
     """
     for block in graph.iterblocks():
         any_change = False
@@ -200,18 +215,22 @@
     x.x.x.x
 
 
-def expand_push_pop_roots(graph):
-    xxxxxxxxx
+def expand_pop_roots(graph):
+    """gc_pop_roots => series of gc_restore_root; this is done after
+    move_pushes_earlier() because that one doesn't work correctly if
+    a completely-empty gc_pop_roots is removed.
+    """
     for block in graph.iterblocks():
+        any_change = False
+        newops = []
         for op in block.operations:
-            if op.opname == 'gc_push_roots':
-                for v in op.args:
-                    interesting_vars.add(v)
-                    pending_pred.append((block, v))
-            elif op.opname == 'gc_pop_roots':
-                for v in op.args:
-                    assert v in interesting_vars   # must be pushed just above
-                    pending_succ.append((block, v))
+            if op.opname == 'gc_pop_roots':
+                newops += expand_one_pop_roots(regalloc, op)
+                any_change = True
+            else:
+                newops.append(op)
+        if any_change:
+            block.operations = newops
 
 
 def postprocess_graph(gct, graph):
@@ -219,4 +238,7 @@
     added in this complete graph, and replace them with real operations.
     """
     regalloc = allocate_registers(graph)
+    expand_push_roots(graph, regalloc)
+    move_pushes_earlier(graph, regalloc)
+    expand_pop_roots(graph, regalloc)
     xxxx
diff --git a/rpython/memory/gctransform/shadowstack.py 
b/rpython/memory/gctransform/shadowstack.py
--- a/rpython/memory/gctransform/shadowstack.py
+++ b/rpython/memory/gctransform/shadowstack.py
@@ -29,8 +29,7 @@
     def push_roots(self, hop, keep_current_args=False):
         livevars = self.get_livevars_for_roots(hop, keep_current_args)
         self.num_pushs += len(livevars)
-        if livevars:
-            hop.genop("gc_push_roots", livevars)
+        hop.genop("gc_push_roots", livevars)
         return livevars
 
     def pop_roots(self, hop, livevars):
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
@@ -268,27 +268,44 @@
 
 
 class FakeRegAlloc:
-    def __init__(self, **colors):
+    def __init__(self, expected_op, **colors):
+        self.expected_op = expected_op
         self.numcolors = len(colors)
         self.getcolor = colors.__getitem__
 
-def check_expand_one_push_roots(regalloc, args):
-    got = list(expand_one_push_roots(regalloc, args))
-    result = []
-    for spaceop in got:
-        assert spaceop.opname == 'gc_save_root'
-        result.append((spaceop.args[0].value, spaceop.args[1]))
-    return result
+    def check(self, got):
+        got = list(got)
+        result = []
+        for spaceop in got:
+            assert spaceop.opname == self.expected_op
+            result.append((spaceop.args[0].value, spaceop.args[1]))
+        return result
 
 def test_expand_one_push_roots():
-    regalloc = FakeRegAlloc(a=0, b=1, c=2)
-    assert check_expand_one_push_roots(regalloc, ['a', 'b', 'c']) == [
+    regalloc = FakeRegAlloc('gc_save_root', a=0, b=1, c=2)
+    assert regalloc.check(expand_one_push_roots(regalloc, ['a', 'b', 'c'])) == 
[
         (0, 'a'), (1, 'b'), (2, 'c')]
-    assert check_expand_one_push_roots(regalloc, ['a', 'c']) == [
+    assert regalloc.check(expand_one_push_roots(regalloc, ['a', 'c'])) == [
         (0, 'a'), (2, 'c'), (1, c_NULL)]
-    assert check_expand_one_push_roots(regalloc, ['b']) == [
+    assert regalloc.check(expand_one_push_roots(regalloc, ['b'])) == [
         (1, 'b'), (2, Constant(0x5, lltype.Signed))]
-    assert check_expand_one_push_roots(regalloc, ['a']) == [
+    assert regalloc.check(expand_one_push_roots(regalloc, ['a'])) == [
         (0, 'a'), (2, Constant(0x3, lltype.Signed))]
-    assert check_expand_one_push_roots(regalloc, []) == [
+    assert regalloc.check(expand_one_push_roots(regalloc, [])) == [
         (2, Constant(0x7, lltype.Signed))]
+
+    assert list(expand_one_push_roots(None, [])) == []
+
+def test_expand_one_pop_roots():
+    regalloc = FakeRegAlloc('gc_restore_root', a=0, b=1, c=2)
+    assert regalloc.check(expand_one_pop_roots(regalloc, ['a', 'b', 'c'])) == [
+        (0, 'a'), (1, 'b'), (2, 'c')]
+    assert regalloc.check(expand_one_pop_roots(regalloc, ['a', 'c'])) == [
+        (0, 'a'), (2, 'c')]
+    assert regalloc.check(expand_one_pop_roots(regalloc, ['b'])) == [
+        (1, 'b')]
+    assert regalloc.check(expand_one_pop_roots(regalloc, ['a'])) == [
+        (0, 'a')]
+    assert regalloc.check(expand_one_pop_roots(regalloc, [])) == []
+
+    assert list(expand_one_pop_roots(None, [])) == []
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to