Exemplo n.º 1
0
 def check_resops(self, expected=None, **check):
     """Check the instructions in all loops and bridges, ignoring
     the ones that end in FINISH.  Either pass a dictionary (then
     the check must match exactly), or some keyword arguments (then
     the check is only about the instructions named)."""
     if self.enable_opts == ENABLE_ALL_OPTS:
         get_stats().check_resops(expected=expected, **check)
Exemplo n.º 2
0
 def check_simple_loop(self, expected=None, **check):
     """Useful in the simplest case when we have only one loop
     ending with a jump back to itself and possibly a few bridges.
     Only the operations within the loop formed by that single jump
     will be counted; the bridges are all ignored.  If several loops
     were compiled, complains."""
     get_stats().check_simple_loop(expected=expected, **check)
Exemplo n.º 3
0
 def check_resops(self, expected=None, **check):
     """Check the instructions in all loops and bridges, ignoring
     the ones that end in FINISH.  Either pass a dictionary (then
     the check must match exactly), or some keyword arguments (then
     the check is only about the instructions named)."""
     if self.enable_opts == ENABLE_ALL_OPTS:
         get_stats().check_resops(expected=expected, **check)
Exemplo n.º 4
0
 def check_simple_loop(self, expected=None, **check):
     """Useful in the simplest case when we have only one loop
     ending with a jump back to itself and possibly a few bridges.
     Only the operations within the loop formed by that single jump
     will be counted; the bridges are all ignored.  If several loops
     were compiled, complains."""
     get_stats().check_simple_loop(expected=expected, **check)
Exemplo n.º 5
0
    def test_location(self):
        def get_printable_location(n):
            return 'GREEN IS %d.' % n
        myjitdriver = JitDriver(greens=['n'], reds=['m'],
                                get_printable_location=get_printable_location)
        def f(n, m):
            while m > 0:
                myjitdriver.can_enter_jit(n=n, m=m)
                myjitdriver.jit_merge_point(n=n, m=m)
                m -= 1

        self.meta_interp(f, [123, 10])
        assert len(get_stats().locations) >= 4
        for loc in get_stats().locations:
            assert loc == (0, 0, 123)
Exemplo n.º 6
0
    def test_location(self):
        def get_printable_location(n):
            return 'GREEN IS %d.' % n
        myjitdriver = JitDriver(greens=['n'], reds=['m'],
                                get_printable_location=get_printable_location)
        def f(n, m):
            while m > 0:
                myjitdriver.can_enter_jit(n=n, m=m)
                myjitdriver.jit_merge_point(n=n, m=m)
                m -= 1

        self.meta_interp(f, [123, 10])
        assert len(get_stats().locations) >= 4
        for loc in get_stats().locations:
            assert loc == (0, 0, 123)
Exemplo n.º 7
0
    def test_simple_1(self):
        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])

        class Foo:
            _immutable_fields_ = ['a?']

            def __init__(self, a):
                self.a = a

        def f(a, x):
            foo = Foo(a)
            total = 0
            while x > 0:
                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
                # read a quasi-immutable field out of a Constant
                total += foo.a
                x -= 1
            return total

        #
        res = self.meta_interp(f, [100, 7])
        assert res == 700
        self.check_resops(guard_not_invalidated=2)
        #
        from rpython.jit.metainterp.warmspot import get_stats
        loops = get_stats().loops
        for loop in loops:
            assert len(loop.quasi_immutable_deps) == 1
            assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
Exemplo n.º 8
0
 def test_nonopt_1(self):
     myjitdriver = JitDriver(greens=[], reds=['x', 'total', 'lst'])
     class Foo:
         _immutable_fields_ = ['a?']
         def __init__(self, a):
             self.a = a
     def setup(x):
         return [Foo(100 + i) for i in range(x)]
     def f(a, x):
         lst = setup(x)
         total = 0
         while x > 0:
             myjitdriver.jit_merge_point(lst=lst, x=x, total=total)
             # read a quasi-immutable field out of a variable
             x -= 1
             total += lst[x].a
         return total
     #
     assert f(100, 7) == 721
     res = self.meta_interp(f, [100, 7])
     assert res == 721
     self.check_resops(guard_not_invalidated=0, getfield_gc=1, getfield_gc_pure=2)
     #
     from rpython.jit.metainterp.warmspot import get_stats
     loops = get_stats().loops
     for loop in loops:
         assert loop.quasi_immutable_deps is None
Exemplo n.º 9
0
 def test_list_pass_around(self):
     py.test.skip("think about a way to fix it")
     myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
     class Foo:
         _immutable_fields_ = ['lst?[*]']
         def __init__(self, lst):
             self.lst = lst
     def g(lst):
         # here, 'lst' is statically annotated as a "modified" list,
         # so the following doesn't generate a getarrayitem_gc_pure...
         return lst[1]
     def f(a, x):
         lst1 = [0, 0]
         g(lst1)
         lst1[1] = a
         foo = Foo(lst1)
         total = 0
         while x > 0:
             myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
             # read a quasi-immutable field out of a Constant
             total += g(foo.lst)
             x -= 1
         return total
     #
     res = self.meta_interp(f, [100, 7])
     assert res == 700
     self.check_resops(guard_not_invalidated=2, getfield_gc=0,
                       getarrayitem_gc=0, getarrayitem_gc_pure=0)
     #
     from rpython.jit.metainterp.warmspot import get_stats
     loops = get_stats().loops
     for loop in loops:
         assert len(loop.quasi_immutable_deps) == 1
         assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
Exemplo n.º 10
0
 def check_enter_count(self, count):
     """Check the number of times pyjitpl ran.  (Every time, it
     should have produced either one loop or one bridge, or aborted;
     but it is not 100% clear that this is still correct in the
     presence of unrolling.)"""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert get_stats().enter_count == count
Exemplo n.º 11
0
 def check_enter_count(self, count):
     """Check the number of times pyjitpl ran.  (Every time, it
     should have produced either one loop or one bridge, or aborted;
     but it is not 100% clear that this is still correct in the
     presence of unrolling.)"""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert get_stats().enter_count == count
Exemplo n.º 12
0
    def test_get_unique_id(self):
        def get_unique_id(pc):
            return pc + 1

        driver = JitDriver(greens=["pc"],
                           reds='auto',
                           get_unique_id=get_unique_id)

        def f(arg):
            i = 0
            pc = 0
            while i < 30 and pc < 3:
                driver.jit_merge_point(pc=pc)
                pc += 1
                if arg == 0 and pc == 3:
                    pc = 0
                if arg == 0:
                    f(1)
                i += 1

        self.meta_interp(f, [0], inline=True)
        loop = get_stats().loops[1]
        for op in loop.operations:
            if op.getopname() == 'enter_portal_frame':
                assert op.getarg(0).getint() == 0
                assert op.getarg(1).getint() == 1
Exemplo n.º 13
0
    def test_virtualizable(self):
        # basically the same test as test_segmented_trace, but the value of n
        # is stored in a virtualizable
        myjitdriver = JitDriver(greens=[],
                                reds=['frame'],
                                virtualizables=['frame'])

        class Frame(object):
            _virtualizable_ = ['n']

            def __init__(self, n):
                self.n = n

        def p(pc, code):
            return "%s %d %s" % (code, pc, code[pc])

        myjitdriver = JitDriver(greens=['pc', 'code'],
                                reds=['frame'],
                                virtualizables=['frame'],
                                get_printable_location=p,
                                is_recursive=True)

        def f(code, n):
            frame = Frame(n)
            pc = 0
            while pc < len(code):
                myjitdriver.jit_merge_point(frame=frame, code=code, pc=pc)

                op = code[pc]
                if op == "-":
                    frame.n -= 1
                elif op == "c":
                    f('--------------------', frame.n)
                elif op == "l":
                    if frame.n > 0:
                        myjitdriver.can_enter_jit(frame=frame, code=code, pc=0)
                        pc = 0
                        continue
                else:
                    assert 0
                pc += 1
            return frame.n

        def g(m):
            set_param(None, 'inlining', True)
            set_param(None, 'trace_limit', 40)
            if m > 1000000:
                f('', 0)
            result = 0
            s = '-' * 50 + '-c-l-'
            for i in range(m):
                result += f(s, i + 100)

        self.meta_interp(g, [10], backendopt=True, ProfilerClass=Profiler)
        stats = get_stats()
        self.check_resops(label=1, jump=1, omit_finish=False)
        assert stats.metainterp_sd.profiler.counters[
            Counters.ABORT_SEGMENTED_TRACE] == 5
        self.check_trace_count(8)
        self.check_jitcell_token_count(1)
Exemplo n.º 14
0
    def test_nonopt_1(self):
        myjitdriver = JitDriver(greens=[], reds=['x', 'total', 'lst'])

        class Foo:
            _immutable_fields_ = ['a?']

            def __init__(self, a):
                self.a = a

        def setup(x):
            return [Foo(100 + i) for i in range(x)]

        def f(a, x):
            lst = setup(x)
            total = 0
            while x > 0:
                myjitdriver.jit_merge_point(lst=lst, x=x, total=total)
                # read a quasi-immutable field out of a variable
                x -= 1
                total += lst[x].a
            return total

        #
        assert f(100, 7) == 721
        res = self.meta_interp(f, [100, 7])
        assert res == 721
        self.check_resops(guard_not_invalidated=0,
                          getfield_gc_r=1,
                          getfield_gc_i=2)
        #
        from rpython.jit.metainterp.warmspot import get_stats
        loops = get_stats().loops
        for loop in loops:
            assert loop.quasi_immutable_deps is None
Exemplo n.º 15
0
    def test_get_unique_id(self):
        def get_unique_id(pc):
            return pc + 1
        
        driver = JitDriver(greens=["pc"], reds='auto',
                           get_unique_id=get_unique_id)

        def f(arg):
            i = 0
            pc = 0
            while i < 30 and pc < 3:
                driver.jit_merge_point(pc=pc)
                pc += 1
                if arg == 0 and pc == 3:
                    pc = 0
                if arg == 0:
                    f(1)
                i += 1

        self.meta_interp(f, [0], inline=True)
        loop = get_stats().loops[1]
        for op in loop.operations:
            if op.getopname() == 'enter_portal_frame':
                assert op.getarg(0).getint() == 0
                assert op.getarg(1).getint() == 1
Exemplo n.º 16
0
 def test_simple_1(self):
     myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
     class Foo:
         _immutable_fields_ = ['a?']
         def __init__(self, a):
             self.a = a
     def f(a, x):
         foo = Foo(a)
         total = 0
         while x > 0:
             myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
             # read a quasi-immutable field out of a Constant
             total += foo.a
             x -= 1
         return total
     #
     res = self.meta_interp(f, [100, 7])
     assert res == 700
     self.check_resops(guard_not_invalidated=2, getfield_gc=0)
     #
     from rpython.jit.metainterp.warmspot import get_stats
     loops = get_stats().loops
     for loop in loops:
         assert len(loop.quasi_immutable_deps) == 1
         assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
Exemplo n.º 17
0
 def test_list_simple_1(self):
     myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
     class Foo:
         _immutable_fields_ = ['lst?[*]']
         def __init__(self, lst):
             self.lst = lst
     def f(a, x):
         lst1 = [0, 0]
         lst1[1] = a
         foo = Foo(lst1)
         total = 0
         while x > 0:
             myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
             # read a quasi-immutable field out of a Constant
             total += foo.lst[1]
             x -= 1
         return total
     #
     res = self.meta_interp(f, [100, 7])
     assert res == 700
     self.check_resops(getarrayitem_gc_pure_i=0, guard_not_invalidated=2,
                       getarrayitem_gc_pure_r=0,
                       getarrayitem_gc_i=0,
                       getarrayitem_gc_r=0,
                       getfield_gc_i=0, getfield_gc_r=0)
     #
     from rpython.jit.metainterp.warmspot import get_stats
     loops = get_stats().loops
     for loop in loops:
         assert len(loop.quasi_immutable_deps) == 1
         assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
Exemplo n.º 18
0
 def test_inline(self):
     # this is not an example of reasonable code: loop1() is unrolled
     # 'n/m' times, where n and m are given as red arguments.
     myjitdriver1 = JitDriver(greens=[], reds=['n', 'm'],
                              get_printable_location = getloc1)
     myjitdriver2 = JitDriver(greens=['g'], reds=['r'],
                              get_printable_location = getloc2)
     #
     def loop1(n, m):
         while n > 0:
             if n > 1000:
                 myjitdriver1.can_enter_jit(n=n, m=m)
             myjitdriver1.jit_merge_point(n=n, m=m)
             n -= m
         return n
     #
     def loop2(g, r):
         set_param(None, 'function_threshold', 0)
         while r > 0:
             myjitdriver2.can_enter_jit(g=g, r=r)
             myjitdriver2.jit_merge_point(g=g, r=r)
             r += loop1(r, g) - 1
         return r
     #
     res = self.meta_interp(loop2, [4, 40], repeat=7, inline=True)
     assert res == loop2(4, 40)
     # we expect no loop at all for 'loop1': it should always be inlined
     # we do however get several version of 'loop2', all of which contains
     # at least one int_add, while there are no int_add's in 'loop1'
     self.check_jitcell_token_count(1)
     for loop in get_stats().loops:
         assert loop.summary()['int_add'] >= 1
Exemplo n.º 19
0
    def test_huge_bridge(self):
        def p(pc, code):
            return "%s %d %s" % (code, pc, code[pc])

        myjitdriver = JitDriver(greens=['pc', 'code'],
                                reds=['n'],
                                get_printable_location=p,
                                is_recursive=True)

        @unroll_safe
        def longtrace(x, n):
            for i in range(x):
                n -= 1
            return n

        def f(code, n):
            pc = 0
            while pc < len(code):

                myjitdriver.jit_merge_point(n=n, code=code, pc=pc)
                op = code[pc]
                if op == "-":
                    n -= longtrace(3, n)
                elif op == "~":
                    if n > 10:
                        n -= 1
                    else:
                        code = "-" * 50
                        pc = 0
                        continue
                elif op == "l":
                    if n > 0:
                        myjitdriver.can_enter_jit(n=n, code=code, pc=0)
                        pc = 0
                        continue
                else:
                    assert 0
                pc += 1
            return n

        def g(m):
            set_param(None, 'inlining', True)
            set_param(None, 'trace_limit', 40)
            if m > 1000000:
                f('', 0)
            result = 0
            s = '~l-'
            for i in range(m):
                result += f(s, i + 100)

        # idea of this test: we have a tiny loop that's just compiled
        # immediately. then at some point n <= 10 and we switch to "-" * 50.
        # That's a huge bridge. The first time we trace that, it doesn't work,
        # but then we set the flag on the loop "expect huge bridges", next time
        # we make a segmented trace
        self.meta_interp(g, [10], backendopt=True, ProfilerClass=Profiler)
        stats = get_stats()
        assert stats.metainterp_sd.profiler.counters[
            Counters.ABORT_SEGMENTED_TRACE] == 4
Exemplo n.º 20
0
 def execute_debug_merge_point(self, descr, *args):
     from rpython.jit.metainterp.warmspot import get_stats
     try:
         stats = get_stats()
     except AttributeError:
         pass
     else:
         stats.add_merge_point_location(args[1:])
Exemplo n.º 21
0
 def execute_debug_merge_point(self, descr, *args):
     from rpython.jit.metainterp.warmspot import get_stats
     try:
         stats = get_stats()
     except AttributeError:
         pass
     else:
         stats.add_merge_point_location(args[1:])
Exemplo n.º 22
0
 def test_reduce_axis_compile_only_once(self):
     self.compile_graph()
     reset_jit()
     i = self.code_mapping['axissum']
     # run it twice
     retval = self.interp.eval_graph(self.graph, [i])
     retval = self.interp.eval_graph(self.graph, [i])
     # check that we got only one loop
     assert len(get_stats().loops) == 1
Exemplo n.º 23
0
 def check_max_trace_length(self, length):
     for loop in get_stats().loops:
         assert len(
             loop.operations
         ) <= length + 5  # because we only check once per metainterp bytecode
         for op in loop.operations:
             if op.is_guard() and hasattr(op.getdescr(),
                                          '_debug_suboperations'):
                 assert len(
                     op.getdescr()._debug_suboperations) <= length + 5
Exemplo n.º 24
0
 def test_reduce_compile_only_once(self):
     self.compile_graph()
     reset_jit()
     i = self.code_mapping['reduce']
     # run it twice
     retval = self.interp.eval_graph(self.graph, [i])
     assert retval == sum(range(1, 11))
     retval = self.interp.eval_graph(self.graph, [i])
     assert retval == sum(range(1, 11))
     # check that we got only one loop
     assert len(get_stats().loops) == 1
     self.check_vectorized(2, 0)
Exemplo n.º 25
0
 def test_reduce_compile_only_once(self):
     self.compile_graph()
     reset_jit()
     i = self.code_mapping['reduce']
     # run it twice
     retval = self.interp.eval_graph(self.graph, [i])
     assert retval == sum(range(1,11))
     retval = self.interp.eval_graph(self.graph, [i])
     assert retval == sum(range(1,11))
     # check that we got only one loop
     assert len(get_stats().loops) == 1
     self.check_vectorized(2, 0)
Exemplo n.º 26
0
 def test_pow_int(self):
     result = self.run("pow_int")
     assert result == 3 ** 2
     self.check_trace_count(2)  # extra one for the astype
     del get_stats().loops[0]   # we don't care about it
     self.check_simple_loop({
         'call': 1,
         'guard_false': 1,
         'guard_not_invalidated': 1,
         'int_add': 3,
         'int_ge': 1,
         'jump': 1,
         'raw_load': 1,
         'raw_store': 1,
     })
Exemplo n.º 27
0
 def test_loop_automatic_reds_not_too_many_redvars(self):
     myjitdriver = JitDriver(greens = ['m'], reds = 'auto')
     def one():
         return 1
     def f(n, m):
         res = 0
         while n > 0:
             n -= one()
             myjitdriver.jit_merge_point(m=m)
             res += m*2
         return res
     expected = f(21, 5)
     res = self.meta_interp(f, [21, 5])
     assert res == expected
     oplabel = get_stats().loops[0].operations[0]
     assert len(oplabel.getarglist()) == 2     # 'n', 'res' in some order
Exemplo n.º 28
0
 def test_loop_automatic_reds_not_too_many_redvars(self):
     myjitdriver = JitDriver(greens = ['m'], reds = 'auto')
     def one():
         return 1
     def f(n, m):
         res = 0
         while n > 0:
             n -= one()
             myjitdriver.jit_merge_point(m=m)
             res += m*2
         return res
     expected = f(21, 5)
     res = self.meta_interp(f, [21, 5])
     assert res == expected
     oplabel = get_stats().loops[0].operations[0]
     assert len(oplabel.getarglist()) == 2     # 'n', 'res' in some order
Exemplo n.º 29
0
    def test_segmented_trace(self):
        def p(pc, code):
            return "%s %d %s" % (code, pc, code[pc])

        myjitdriver = JitDriver(greens=['pc', 'code'],
                                reds=['n'],
                                get_printable_location=p,
                                is_recursive=True)

        def f(code, n):
            pc = 0
            while pc < len(code):

                myjitdriver.jit_merge_point(n=n, code=code, pc=pc)
                op = code[pc]
                if op == "-":
                    n -= 1
                elif op == "c":
                    f('--------------------', n)
                elif op == "l":
                    if n > 0:
                        myjitdriver.can_enter_jit(n=n, code=code, pc=0)
                        pc = 0
                        continue
                else:
                    assert 0
                pc += 1
            return n

        def g(m):
            set_param(None, 'inlining', True)
            set_param(None, 'trace_limit', 40)
            if m > 1000000:
                f('', 0)
            result = 0
            s = '-' * 50 + '-c-l-'
            for i in range(m):
                result += f(s, i + 100)

        self.meta_interp(g, [10], backendopt=True, ProfilerClass=Profiler)
        stats = get_stats()
        self.check_resops(label=1, jump=1, omit_finish=False)
        assert stats.metainterp_sd.profiler.counters[
            Counters.ABORT_SEGMENTED_TRACE] == 4
        self.check_trace_count(7)
        self.check_jitcell_token_count(1)
Exemplo n.º 30
0
    def test_call_assembler_keep_alive(self):
        myjitdriver1 = JitDriver(greens=['m'], reds=['n'])
        myjitdriver2 = JitDriver(greens=['m'], reds=['n', 'rec'])

        def h(m, n):
            while True:
                myjitdriver1.can_enter_jit(n=n, m=m)
                myjitdriver1.jit_merge_point(n=n, m=m)
                n = n >> 1
                if n == 0:
                    return 21

        def g(m, rec):
            n = 5
            while n > 0:
                myjitdriver2.can_enter_jit(n=n, m=m, rec=rec)
                myjitdriver2.jit_merge_point(n=n, m=m, rec=rec)
                if rec:
                    h(m, rec)
                n = n - 1
            return 21

        def f(u):
            for i in range(8):
                h(u, 32)  # make a loop and an exit bridge for h(u)
            g(u, 8)  # make a loop for g(u) with a call_assembler
            g(u, 0)
            g(u + 1, 0)  # \
            g(u, 0)
            g(u + 2, 0)  #  \  make more loops for g(u+1) to g(u+4),
            g(u, 0)
            g(u + 3, 0)  #  /  but keeps g(u) alive
            g(u, 0)
            g(u + 4, 0)  # /
            g(u, 8)  # call g(u) again, with its call_assembler to h(u)
            return 42

        res = self.meta_interp(f, [1], loop_longevity=4, inline=True)
        assert res == 42
        self.check_jitcell_token_count(6)
        tokens = [t() for t in get_stats().jitcell_token_wrefs]
        # Some loops have been freed
        assert None in tokens
        # Loop with number 0, h(), has not been freed
        assert 0 in [t.number for t in tokens if t]
Exemplo n.º 31
0
    def test_interp_single_loop(self):
        myjitdriver = JitDriver(greens=['i'], reds=['x', 'y'])
        bytecode = "abcd"

        def f(x, y):
            i = 0
            while i < len(bytecode):
                myjitdriver.jit_merge_point(i=i, x=x, y=y)
                op = bytecode[i]
                if op == 'a':
                    x += y
                elif op == 'b':
                    y -= 1
                elif op == 'c':
                    if y:
                        i = 0
                        myjitdriver.can_enter_jit(i=i, x=x, y=y)
                        continue
                else:
                    x += 1
                i += 1
            return x

        res = self.meta_interp(f, [5, 8])
        assert res == 42
        self.check_trace_count(1)
        # the 'int_eq' and following 'guard' should be constant-folded
        if 'unroll' in self.enable_opts:
            self.check_resops(int_eq=0, guard_true=2, guard_false=0)
        else:
            self.check_resops(int_eq=0, guard_true=1, guard_false=0)
        if self.basic:
            found = 0
            for op in get_stats().loops[0]._all_operations():
                if op.getopname() == 'guard_true':
                    liveboxes = op.getfailargs()
                    assert len(liveboxes) == 2  # x, y (in some order)
                    assert isinstance(liveboxes[0], history.BoxInt)
                    assert isinstance(liveboxes[1], history.BoxInt)
                    found += 1
            if 'unroll' in self.enable_opts:
                assert found == 2
            else:
                assert found == 1
Exemplo n.º 32
0
    def test_list_length_1(self):
        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])

        class Foo:
            _immutable_fields_ = ['lst?[*]']

            def __init__(self, lst):
                self.lst = lst

        class A:
            pass

        def f(a, x):
            lst1 = [0, 0]
            lst1[1] = a
            foo = Foo(lst1)
            total = 0
            while x > 0:
                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
                # make it a Constant after optimization only
                a = A()
                a.foo = foo
                foo = a.foo
                # read a quasi-immutable field out of it
                total += foo.lst[1]
                # also read the length
                total += len(foo.lst)
                x -= 1
            return total

        #
        res = self.meta_interp(f, [100, 7])
        assert res == 714
        self.check_resops(getarrayitem_gc_pure=0,
                          guard_not_invalidated=2,
                          arraylen_gc=0,
                          getarrayitem_gc=0,
                          getfield_gc=0)
        #
        from rpython.jit.metainterp.warmspot import get_stats
        loops = get_stats().loops
        for loop in loops:
            assert len(loop.quasi_immutable_deps) == 1
            assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
Exemplo n.º 33
0
 def test_interp_single_loop(self):
     myjitdriver = JitDriver(greens = ['i'], reds = ['x', 'y'])
     bytecode = "abcd"
     def f(x, y):
         i = 0
         while i < len(bytecode):
             myjitdriver.jit_merge_point(i=i, x=x, y=y)
             op = bytecode[i]
             if op == 'a':
                 x += y
             elif op == 'b':
                 y -= 1
             elif op == 'c':
                 if y:
                     i = 0
                     myjitdriver.can_enter_jit(i=i, x=x, y=y)
                     continue
             else:
                 x += 1
             i += 1
         return x
     res = self.meta_interp(f, [5, 8])
     assert res == 42
     self.check_trace_count(1)
     # the 'int_eq' and following 'guard' should be constant-folded
     if 'unroll' in self.enable_opts:
         self.check_resops(int_eq=0, guard_true=2, guard_false=0)
     else:
         self.check_resops(int_eq=0, guard_true=1, guard_false=0)
     if self.basic:
         found = 0
         for op in get_stats().loops[0]._all_operations():
             if op.getopname() == 'guard_true':
                 liveboxes = op.getfailargs()
                 assert len(liveboxes) == 2     # x, y (in some order)
                 assert isinstance(liveboxes[0], history.BoxInt)
                 assert isinstance(liveboxes[1], history.BoxInt)
                 found += 1
         if 'unroll' in self.enable_opts:
             assert found == 2
         else:
             assert found == 1
Exemplo n.º 34
0
    def test_list_pass_around(self):
        py.test.skip("think about a way to fix it")
        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])

        class Foo:
            _immutable_fields_ = ['lst?[*]']

            def __init__(self, lst):
                self.lst = lst

        def g(lst):
            # here, 'lst' is statically annotated as a "modified" list,
            # so the following doesn't generate a getarrayitem_gc_pure...
            return lst[1]

        def f(a, x):
            lst1 = [0, 0]
            g(lst1)
            lst1[1] = a
            foo = Foo(lst1)
            total = 0
            while x > 0:
                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
                # read a quasi-immutable field out of a Constant
                total += g(foo.lst)
                x -= 1
            return total

        #
        res = self.meta_interp(f, [100, 7])
        assert res == 700
        self.check_resops(guard_not_invalidated=2,
                          getfield_gc=0,
                          getarrayitem_gc=0,
                          getarrayitem_gc_pure=0)
        #
        from rpython.jit.metainterp.warmspot import get_stats
        loops = get_stats().loops
        for loop in loops:
            assert len(loop.quasi_immutable_deps) == 1
            assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
Exemplo n.º 35
0
    def test_call_assembler_keep_alive(self):
        myjitdriver1 = JitDriver(greens=['m'], reds=['n'])
        myjitdriver2 = JitDriver(greens=['m'], reds=['n', 'rec'])
        def h(m, n):
            while True:
                myjitdriver1.can_enter_jit(n=n, m=m)
                myjitdriver1.jit_merge_point(n=n, m=m)
                n = n >> 1
                if n == 0:
                    return 21
        def g(m, rec):
            n = 5
            while n > 0:
                myjitdriver2.can_enter_jit(n=n, m=m, rec=rec)
                myjitdriver2.jit_merge_point(n=n, m=m, rec=rec)
                if rec:
                    h(m, rec)
                n = n - 1
            return 21
        def f(u):
            for i in range(8):
                h(u, 32)  # make a loop and an exit bridge for h(u)
            g(u, 8)       # make a loop for g(u) with a call_assembler
            g(u, 0); g(u+1, 0)     # \
            g(u, 0); g(u+2, 0)     #  \  make more loops for g(u+1) to g(u+4),
            g(u, 0); g(u+3, 0)     #  /  but keeps g(u) alive
            g(u, 0); g(u+4, 0)     # /
            g(u, 8)       # call g(u) again, with its call_assembler to h(u)
            return 42

        res = self.meta_interp(f, [1], loop_longevity=4, inline=True)
        assert res == 42
        self.check_jitcell_token_count(6)
        tokens = [t() for t in get_stats().jitcell_token_wrefs]
        # Some loops have been freed
        assert None in tokens
        # Loop with number 0, h(), has not been freed
        assert 0 in [t.number for t in tokens if t]
Exemplo n.º 36
0
    def test_list_simple_1(self):
        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])

        class Foo:
            _immutable_fields_ = ['lst?[*]']

            def __init__(self, lst):
                self.lst = lst

        def f(a, x):
            lst1 = [0, 0]
            lst1[1] = a
            foo = Foo(lst1)
            total = 0
            while x > 0:
                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
                # read a quasi-immutable field out of a Constant
                total += foo.lst[1]
                x -= 1
            return total

        #
        res = self.meta_interp(f, [100, 7])
        assert res == 700
        self.check_resops(getarrayitem_gc_pure_i=0,
                          guard_not_invalidated=2,
                          getarrayitem_gc_pure_r=0,
                          getarrayitem_gc_i=0,
                          getarrayitem_gc_r=0,
                          getfield_gc_i=0,
                          getfield_gc_r=0)
        #
        from rpython.jit.metainterp.warmspot import get_stats
        loops = get_stats().loops
        for loop in loops:
            assert len(loop.quasi_immutable_deps) == 1
            assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
Exemplo n.º 37
0
    def test_inline(self):
        # this is not an example of reasonable code: loop1() is unrolled
        # 'n/m' times, where n and m are given as red arguments.
        myjitdriver1 = JitDriver(greens=[],
                                 reds=['n', 'm'],
                                 get_printable_location=getloc1)
        myjitdriver2 = JitDriver(greens=['g'],
                                 reds=['r'],
                                 get_printable_location=getloc2)

        #
        def loop1(n, m):
            while n > 0:
                if n > 1000:
                    myjitdriver1.can_enter_jit(n=n, m=m)
                myjitdriver1.jit_merge_point(n=n, m=m)
                n -= m
            return n

        #
        def loop2(g, r):
            set_param(None, 'function_threshold', 0)
            while r > 0:
                myjitdriver2.can_enter_jit(g=g, r=r)
                myjitdriver2.jit_merge_point(g=g, r=r)
                r += loop1(r, g) - 1
            return r

        #
        res = self.meta_interp(loop2, [4, 40], repeat=7, inline=True)
        assert res == loop2(4, 40)
        # we expect no loop at all for 'loop1': it should always be inlined
        # we do however get several version of 'loop2', all of which contains
        # at least one int_add, while there are no int_add's in 'loop1'
        self.check_jitcell_token_count(1)
        for loop in get_stats().loops:
            assert loop.summary()['int_add'] >= 1
Exemplo n.º 38
0
    def test_multiple_jits_trace_too_long(self):
        myjitdriver1 = JitDriver(greens=["n"], reds=["i", "box"])
        myjitdriver2 = JitDriver(greens=["n"], reds=["i"])

        class IntBox(object):
            def __init__(self, val):
                self.val = val

        def loop1(n):
            i = 0
            box = IntBox(10)
            while i < n:
                myjitdriver1.can_enter_jit(n=n, i=i, box=box)
                myjitdriver1.jit_merge_point(n=n, i=i, box=box)
                i += 1
                loop2(box)
            return i

        def loop2(n):
            i = 0
            f(10)
            while i < n.val:
                myjitdriver2.can_enter_jit(n=n, i=i)
                myjitdriver2.jit_merge_point(n=n, i=i)
                i += 1

        @unroll_safe
        def f(n):
            i = 0
            while i < n:
                i += 1

        res = self.meta_interp(loop1, [10], inline=True, trace_limit=6)
        assert res == 10
        stats = get_stats()
        assert stats.aborted_keys == [None, None]
Exemplo n.º 39
0
    def test_multiple_jits_trace_too_long(self):
        myjitdriver1 = JitDriver(greens=["n"], reds=["i", "box"])
        myjitdriver2 = JitDriver(greens=["n"], reds=["i"])

        class IntBox(object):
            def __init__(self, val):
                self.val = val

        def loop1(n):
            i = 0
            box = IntBox(10)
            while i < n:
                myjitdriver1.can_enter_jit(n=n, i=i, box=box)
                myjitdriver1.jit_merge_point(n=n, i=i, box=box)
                i += 1
                loop2(box)
            return i

        def loop2(n):
            i = 0
            f(10)
            while i < n.val:
                myjitdriver2.can_enter_jit(n=n, i=i)
                myjitdriver2.jit_merge_point(n=n, i=i)
                i += 1

        @unroll_safe
        def f(n):
            i = 0
            while i < n:
                i += 1

        res = self.meta_interp(loop1, [10], inline=True, trace_limit=6)
        assert res == 10
        stats = get_stats()
        assert stats.aborted_keys == [None, None]
Exemplo n.º 40
0
 def test_list_length_1(self):
     myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
     class Foo:
         _immutable_fields_ = ['lst?[*]']
         def __init__(self, lst):
             self.lst = lst
     class A:
         pass
     def f(a, x):
         lst1 = [0, 0]
         lst1[1] = a
         foo = Foo(lst1)
         total = 0
         while x > 0:
             myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
             # make it a Constant after optimization only
             a = A()
             a.foo = foo
             foo = a.foo
             # read a quasi-immutable field out of it
             total += foo.lst[1]
             # also read the length
             total += len(foo.lst)
             x -= 1
         return total
     #
     res = self.meta_interp(f, [100, 7])
     assert res == 714
     self.check_resops(getarrayitem_gc_pure=0, guard_not_invalidated=2,
                       arraylen_gc=0, getarrayitem_gc=0, getfield_gc=0)
     #
     from rpython.jit.metainterp.warmspot import get_stats
     loops = get_stats().loops
     for loop in loops:
         assert len(loop.quasi_immutable_deps) == 1
         assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
Exemplo n.º 41
0
 def check_history(self, expected=None, **isns):
     # this can be used after calling meta_interp
     get_stats().check_history(expected, **isns)
Exemplo n.º 42
0
 def check_aborted_count_at_least(self, count):
     """Check the number of times pyjitpl was aborted."""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert get_stats().aborted_count >= count
Exemplo n.º 43
0
 def check_enter_count_at_most(self, count):
     """Check the number of times pyjitpl ran."""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert get_stats().enter_count <= count
Exemplo n.º 44
0
 def check_aborted_count_at_least(self, count):
     """Check the number of times pyjitpl was aborted."""
     assert get_stats().aborted_count >= count
Exemplo n.º 45
0
 def check_target_token_count(self, count):
     """(xxx unknown)"""
     if self.enable_opts == ENABLE_ALL_OPTS:
         tokens = get_stats().get_all_jitcell_tokens()
         n = sum([len(t.target_tokens) for t in tokens])
         assert n == count
Exemplo n.º 46
0
 def check_jitcell_token_count(self, count):  # was check_tree_loop_count
     """This should check the number of independent trees of code.
     (xxx it is not 100% clear that the count is correct)"""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert len(get_stats().jitcell_token_wrefs) == count
Exemplo n.º 47
0
 def check_aborted_count_at_least(self, count):
     assert get_stats().aborted_count >= count
Exemplo n.º 48
0
 def check_target_token_count(self, count):
     """(xxx unknown)"""
     if self.enable_opts == ENABLE_ALL_OPTS:
         tokens = get_stats().get_all_jitcell_tokens()
         n = sum([len(t.target_tokens) for t in tokens])
         assert n == count
Exemplo n.º 49
0
 def check_aborted_count_at_least(self, count):
     """Check the number of times pyjitpl was aborted."""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert get_stats().aborted_count >= count
Exemplo n.º 50
0
 def check_jitcell_token_count(self, count): # was check_tree_loop_count
     """This should check the number of independent trees of code.
     (xxx it is not 100% clear that the count is correct)"""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert len(get_stats().jitcell_token_wrefs) == count
Exemplo n.º 51
0
 def check_history(self, expected=None, **isns):
     # this can be used after calling meta_interp
     get_stats().check_history(expected, **isns)
Exemplo n.º 52
0
 def check_trace_count_at_most(self, count):
     """Check the number of loops and bridges compiled."""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert get_stats().compiled_count <= count
Exemplo n.º 53
0
 def check_aborted_count(self, count):
     assert get_stats().aborted_count == count
Exemplo n.º 54
0
 def check_trace_count_at_most(self, count):
     """Check the number of loops and bridges compiled."""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert get_stats().compiled_count <= count
Exemplo n.º 55
0
 def check_jumps(self, maxcount):
     return  # FIXME
     assert get_stats().exec_jumps <= maxcount
Exemplo n.º 56
0
 def check_enter_count_at_most(self, count):
     assert get_stats().enter_count <= count
Exemplo n.º 57
0
 def check_max_trace_length(self, length):
     for loop in get_stats().loops:
         assert len(loop.operations) <= length + 5 # because we only check once per metainterp bytecode
         for op in loop.operations:
             if op.is_guard() and hasattr(op.getdescr(), '_debug_suboperations'):
                 assert len(op.getdescr()._debug_suboperations) <= length + 5
Exemplo n.º 58
0
 def check_enter_count_at_most(self, count):
     """Check the number of times pyjitpl ran."""
     if self.enable_opts == ENABLE_ALL_OPTS:
         assert get_stats().enter_count <= count