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