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