Research GitLab has introduced a user quota limitation. The new rule limits each user to have 50 Gb. The quota doesn't restrict group projects. If you have any concern with this, please talk to CECS Gitlab Admin at N110 (b) CSIT building.

test_logger.py 7.69 KB
Newer Older
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
1 2

import re
Alexander Hesse's avatar
Alexander Hesse committed
3 4 5 6
from rpython.rlib import debug
from rpython.jit.tool.oparser import pure_parse
from rpython.jit.metainterp import logger
from rpython.jit.metainterp.typesystem import llhelper
7
from StringIO import StringIO
Alexander Hesse's avatar
Alexander Hesse committed
8
from rpython.jit.metainterp.optimizeopt.util import equaloplists
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
9
from rpython.jit.metainterp.history import AbstractDescr, JitCellToken, BasicFailDescr, BasicFinalDescr
Alexander Hesse's avatar
Alexander Hesse committed
10
from rpython.jit.backend.model import AbstractCPU
11

12 13

class Descr(AbstractDescr):
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
14
    final_descr = False
15

16 17
def capturing(func, *args, **kwds):
    log_stream = StringIO()
18 19 20 21 22 23 24 25 26
    class MyDebugLog:
        def debug_print(self, *args):
            for arg in args:
                print >> log_stream, arg,
            print >> log_stream
        def debug_start(self, *args):
            pass
        def debug_stop(self, *args):
            pass
27
    try:
28
        debug._log = MyDebugLog()
29 30
        func(*args, **kwds)
    finally:
31
        debug._log = None
32 33
    return log_stream.getvalue()

34
class Logger(logger.Logger):
35
    def log_loop(self, loop, namespace={}, ops_offset=None, name=''):
36
        self.namespace = namespace
37
        return capturing(logger.Logger.log_loop, self,
38 39
                         loop.inputargs, loop.operations, ops_offset=ops_offset,
                         name=name)
40

Armin Rigo's avatar
Armin Rigo committed
41 42 43 44 45 46 47 48 49 50
    def _make_log_operations(self1):
        class LogOperations(logger.LogOperations):
            def repr_of_descr(self, descr):
                for k, v in self1.namespace.items():
                    if v == descr:
                        return k
                return descr.repr_of_descr()
        logops = LogOperations(self1.metainterp_sd, self1.guard_number)
        self1.logops = logops
        return logops
51 52 53 54

class TestLogger(object):
    ts = llhelper

55
    def make_metainterp_sd(self):
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
56 57
        class FakeJitDriver(object):
            class warmstate(object):
58
                get_location_str = staticmethod(lambda args: "dupa")
Alex Gaynor's avatar
Alex Gaynor committed
59

60
        class FakeMetaInterpSd:
61 62
            cpu = AbstractCPU()
            cpu.ts = self.ts
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
63
            jitdrivers_sd = [FakeJitDriver()]
64 65 66 67
            def get_name_from_address(self, addr):
                return 'Name'
        return FakeMetaInterpSd()

68 69 70
    def reparse(self, inp, namespace=None, check_equal=True):
        """ parse loop once, then log it and parse again.
        Checks that we get the same thing.
71
        """
72 73 74
        if namespace is None:
            namespace = {}
        loop = pure_parse(inp, namespace=namespace)
75
        logger = Logger(self.make_metainterp_sd())
76
        output = logger.log_loop(loop, namespace)
77
        oloop = pure_parse(output, namespace=namespace)
78 79 80
        if check_equal:
            equaloplists(loop.operations, oloop.operations)
            assert oloop.inputargs == loop.inputargs
81
        return logger, loop, oloop
Alex Gaynor's avatar
Alex Gaynor committed
82

83 84 85 86 87 88 89
    def test_simple(self):
        inp = '''
        [i0, i1, i2, p3, p4, p5]
        i6 = int_add(i1, i2)
        i8 = int_add(i6, 3)
        jump(i0, i8, i6, p3, p4, p5)
        '''
90
        self.reparse(inp)
91 92 93 94 95 96

    def test_descr(self):
        inp = '''
        [p0]
        setfield_gc(p0, 3, descr=somedescr)
        '''
97
        somedescr = Descr()
98
        self.reparse(inp, namespace=locals())
99 100 101 102

    def test_guard(self):
        inp = '''
        [i0]
103 104 105
        i1 = int_add(i0, 1)
        guard_true(i0) [i0, i1]
        finish(i1)
106
        '''
107
        self.reparse(inp)
108

109 110 111 112
    def test_guard_not_invalidated(self):
        inp = '''
        []
        guard_not_invalidated(descr=descr) []
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
113
        finish(descr=finaldescr)
114
        '''
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
115 116
        loop = pure_parse(inp, namespace={'descr': Descr(),
                                          'finaldescr': BasicFinalDescr()})
117 118 119 120
        logger = Logger(self.make_metainterp_sd())
        output = logger.log_loop(loop, {'descr': Descr()})
        assert 'guard_not_invalidated(descr=' in output

121 122 123 124 125 126 127 128 129
    def test_guard_w_hole(self):
        inp = '''
        [i0]
        i1 = int_add(i0, 1)
        guard_true(i0) [i0, None, i1]
        finish(i1)
        '''
        self.reparse(inp)

130 131 132
    def test_debug_merge_point(self):
        inp = '''
        []
Alex Gaynor's avatar
Alex Gaynor committed
133
        debug_merge_point(0, 0, 0)
134
        '''
135
        _, loop, oloop = self.reparse(inp, check_equal=False)
136
        assert loop.operations[0].getarg(1).getint() == 0
Alex Gaynor's avatar
Alex Gaynor committed
137 138 139
        assert loop.operations[0].getarg(2).getint() == 0
        assert oloop.operations[0].getarg(2)._get_str() == "dupa"

Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
140 141 142 143 144
    def test_floats(self):
        inp = '''
        [f0]
        f1 = float_add(3.5, f0)
        '''
145
        _, loop, oloop = self.reparse(inp)
146
        equaloplists(loop.operations, oloop.operations)
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
147

148
    def test_jump(self):
Hakan Ardo's avatar
Hakan Ardo committed
149
        namespace = {'target': JitCellToken()}
150
        namespace['target'].number = 3
151 152 153 154 155
        inp = '''
        [i0]
        jump(i0, descr=target)
        '''
        loop = pure_parse(inp, namespace=namespace)
156
        logger = Logger(self.make_metainterp_sd())
157 158 159
        output = logger.log_loop(loop)
        assert output.splitlines()[-1] == "jump(i0, descr=<Loop3>)"
        pure_parse(output)
Alex Gaynor's avatar
Alex Gaynor committed
160

161
    def test_guard_descr(self):
162
        namespace = {'fdescr': BasicFailDescr()}
163 164 165 166 167
        inp = '''
        [i0]
        guard_true(i0, descr=fdescr) [i0]
        '''
        loop = pure_parse(inp, namespace=namespace)
168
        logger = Logger(self.make_metainterp_sd(), guard_number=True)
169
        output = logger.log_loop(loop)
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
170
        assert re.match("guard_true\(i0, descr=<Guard0x[\da-f]+>\) \[i0\]", output.splitlines()[-1])
171
        pure_parse(output)
Alex Gaynor's avatar
Alex Gaynor committed
172

173
        logger = Logger(self.make_metainterp_sd(), guard_number=False)
174
        output = logger.log_loop(loop)
175 176 177
        lastline = output.splitlines()[-1]
        assert lastline.startswith("guard_true(i0, descr=<")
        assert not lastline.startswith("guard_true(i0, descr=<Guard")
178

179
    def test_class_name(self):
Alexander Hesse's avatar
Alexander Hesse committed
180
        from rpython.rtyper.lltypesystem import lltype
181 182 183 184 185 186 187 188 189 190 191 192 193 194
        AbcVTable = lltype.Struct('AbcVTable')
        abcvtable = lltype.malloc(AbcVTable, immortal=True)
        namespace = {'Name': abcvtable}
        inp = '''
        [i0]
        p = new_with_vtable(ConstClass(Name))
        '''
        loop = pure_parse(inp, namespace=namespace)
        logger = Logger(self.make_metainterp_sd())
        output = logger.log_loop(loop)
        assert output.splitlines()[-1].endswith(
            " = new_with_vtable(ConstClass(Name))")
        pure_parse(output, namespace=namespace)

195
    def test_intro_loop(self):
196
        bare_logger = logger.Logger(self.make_metainterp_sd())
197
        output = capturing(bare_logger.log_loop, [], [], 1, "foo")
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
198
        assert output.splitlines()[0] == "# Loop 1 () : foo with 0 ops"
199 200 201
        pure_parse(output)

    def test_intro_bridge(self):
202
        bare_logger = logger.Logger(self.make_metainterp_sd())
203
        output = capturing(bare_logger.log_bridge, [], [], 3)
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
204
        assert re.match("# bridge out of Guard 0x[\da-f]+ with 0 ops",
Maciej Fijalkowski's avatar
Maciej Fijalkowski committed
205
                        output.splitlines()[0])
206
        pure_parse(output)
207 208 209 210 211 212 213 214 215 216

    def test_repr_single_op(self):
        inp = '''
        [i0, i1, i2, p3, p4, p5]
        i6 = int_add(i1, i2)
        i8 = int_add(i6, 3)
        jump(i0, i8, i6, p3, p4, p5)
        '''
        logger, loop, _ = self.reparse(inp)
        op = loop.operations[1]
217
        assert logger.logops.repr_of_resop(op) == "i8 = int_add(i6, 3)"
Armin Rigo's avatar
Armin Rigo committed
218

219
    def test_ops_offset(self):
220 221 222 223 224 225 226 227
        inp = '''
        [i0]
        i1 = int_add(i0, 1)
        i2 = int_mul(i1, 2)
        jump(i2)
        '''
        loop = pure_parse(inp)
        ops = loop.operations
228
        ops_offset = {
229 230 231 232 233
            ops[0]: 10,
            ops[2]: 30,
            None: 40
            }
        logger = Logger(self.make_metainterp_sd())
234
        output = logger.log_loop(loop, ops_offset=ops_offset, name="foo")
235
        assert output.strip() == """
236
# Loop 0 (foo) : noopt with 3 ops
237 238 239 240
[i0]
+10: i2 = int_add(i0, 1)
i4 = int_mul(i2, 2)
+30: jump(i4)
Antonio Cuni's avatar
Antonio Cuni committed
241
+40: --end of the loop--
242
""".strip()