Example #1
0
 def test_forced_virtual_assigned_in_bridge(self):
     myjitdriver = JitDriver(greens = [], reds = ['n', 's', 'node', 'node2'])
     def externfn(node):
         node.value += 1
     def f(n, s):
         node = self._new()
         node.value = 1
         node2 = self._new()
         node2.value = 2
         while n > 0:
             myjitdriver.can_enter_jit(n=n, s=s, node=node, node2=node2)
             myjitdriver.jit_merge_point(n=n, s=s, node=node, node2=node2)
             next = self._new()
             next.value = node.value + 1
             node = next
             if (n>>s) & 1:
                 node2.value += node.value
                 node = node2
             externfn(node)
             n -= 1
         return node.value
     res = self.meta_interp(f, [48, 3], policy=StopAtXPolicy(externfn))
     assert res == f(48, 3)
     self.check_trace_count(4)
     res = self.meta_interp(f, [40, 3], policy=StopAtXPolicy(externfn))
     assert res == f(40, 3)
     self.check_trace_count(3)
Example #2
0
    def test_loop_with_two_paths(self):
        from pypy.rpython.lltypesystem import lltype
        from pypy.rpython.lltypesystem.lloperation import llop
        myjitdriver = JitDriver(greens=[], reds=['x', 'y', 'res'])

        def l(y, x, t):
            llop.debug_print(lltype.Void, y, x, t)

        def g(y, x, r):
            if y <= 12:
                res = x - 2
            else:
                res = x
            l(y, x, r)
            return res

        def f(x, y):
            res = 0
            while y > 0:
                myjitdriver.can_enter_jit(x=x, y=y, res=res)
                myjitdriver.jit_merge_point(x=x, y=y, res=res)
                res += g(y, x, res)
                y -= 1
            return res * 2

        res = self.meta_interp(f, [6, 33], policy=StopAtXPolicy(l))
        assert res == f(6, 33)
        if self.enable_opts:
            self.check_trace_count(2)
        else:
            self.check_trace_count(2)
Example #3
0
 def test_two_loops_with_escaping_virtual(self):
     myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
     def externfn(node):
         llop.debug_print(lltype.Void, compute_unique_id(node),
                          node.value, node.extra)
         return node.value * 2
     def f(n):
         node = self._new()
         node.value = 0
         node.extra = 0
         while n > 0:
             myjitdriver.can_enter_jit(n=n, node=node)
             myjitdriver.jit_merge_point(n=n, node=node)
             next = self._new()
             next.value = node.value + n
             next.extra = node.extra + 1
             if next.extra == 5:
                 next.value = externfn(next)
                 next.extra = 0
             node = next
             n -= 1
         return node.value
     res = self.meta_interp(f, [20], policy=StopAtXPolicy(externfn))
     assert res == f(20)
     self.check_trace_count(2)
     self.check_resops(**{self._new_op: 1})
     self.check_resops(int_mul=0, call=1)
Example #4
0
    def test_external_read_sometimes_dont_compile_guard(self):
        jitdriver = JitDriver(greens = [], reds = ['frame'],
                              virtualizables = ['frame'])
        
        class Frame(object):
            _virtualizable2_ = ['x', 'y']
        class SomewhereElse:
            pass
        somewhere_else = SomewhereElse()

        def g():
            somewhere_else.counter += 1
            if somewhere_else.counter == 70:
                result = somewhere_else.top_frame.y     # external read
                debug_print(lltype.Void, '-+-+-+-+- external read:', result)
                assert result == 79
            else:
                result = 1
            return result

        def f(n):
            frame = Frame()
            frame.x = n
            frame.y = 10
            somewhere_else.counter = 0
            somewhere_else.top_frame = frame
            while frame.x > 0:
                jitdriver.can_enter_jit(frame=frame)
                jitdriver.jit_merge_point(frame=frame)
                frame.x -= g()
                frame.y += 1
            return frame.x

        res = self.meta_interp(f, [123], policy=StopAtXPolicy(g), repeat=7)
        assert res == f(123)
Example #5
0
    def test_escapes(self):
        myjitdriver = JitDriver(greens = [], reds = ['n', 'parent'])

        class Parent(object):
            def __init__(self, node):
                self.node = node

        def g(x):
            pass

        def f(n):
            node = self._new()
            node.value = 3
            parent = Parent(node)
            while n > 0:
                myjitdriver.can_enter_jit(n=n, parent=parent)
                myjitdriver.jit_merge_point(n=n, parent=parent)
                node = parent.node
                g(node)
                newnode = self._new()
                newnode.value = 3
                parent = Parent(newnode)
                n -= 1
            return parent.node.value

        res = self.meta_interp(f, [10], policy=StopAtXPolicy(g))
        assert res == 3
        self.check_resops(**{self._new_op: 1}) 
Example #6
0
    def test_residual_oosend(self):
        myjitdriver = JitDriver(greens=[], reds=['i', 'obj'])

        class A:
            def foo(self):
                return 41

        class B(A):
            def foo(self):
                return 42

        def new(n):
            if n:
                return A()
            else:
                return B()

        def fn(n, i):
            res = 0
            obj = new(n)
            while i > 0:
                myjitdriver.can_enter_jit(i=i, obj=obj)
                myjitdriver.jit_merge_point(i=i, obj=obj)
                res = obj.foo()
                i -= 1
            return res

        policy = StopAtXPolicy(new, A.foo.im_func, B.foo.im_func)
        res = self.meta_interp(fn, [0, 20], policy=policy)
        assert res == 42
        self.check_resops(call=2)
Example #7
0
    def test_residual_oosend_with_void(self):
        myjitdriver = JitDriver(greens=[], reds=['i', 'obj'])

        class A:
            def foo(self, other):
                return 41

            def _freeze_(self):
                return True

        def new(n):
            if n:
                return A()
            else:
                return None

        pbc = A()

        def fn(n, i):
            res = 0
            obj = new(n)
            while i > 0:
                myjitdriver.can_enter_jit(i=i, obj=obj)
                myjitdriver.jit_merge_point(i=i, obj=obj)
                res = obj.foo(pbc)
                i -= 1
            return res

        policy = StopAtXPolicy(new, A.foo.im_func)
        res = self.meta_interp(fn, [1, 20], policy=policy)
        assert res == 41
        self.check_resops(call=2)
Example #8
0
    def test_external_write_sometimes(self):
        jitdriver = JitDriver(greens = [], reds = ['frame'],
                              virtualizables = ['frame'])
        
        class Frame(object):
            _virtualizable2_ = ['x', 'y']
        class SomewhereElse:
            pass
        somewhere_else = SomewhereElse()

        def g():
            somewhere_else.counter += 1
            if somewhere_else.counter == 70:
                debug_print(lltype.Void, '-+-+-+-+- external write: 7000')
                somewhere_else.top_frame.y = 7000
                result = 2
            else:
                result = 1
            return result

        def f(n):
            frame = Frame()
            frame.x = n
            frame.y = 10
            somewhere_else.counter = 0
            somewhere_else.top_frame = frame
            while frame.x > 0:
                jitdriver.can_enter_jit(frame=frame)
                jitdriver.jit_merge_point(frame=frame)
                frame.x -= g()
                frame.y += 1
            return frame.y

        res = self.meta_interp(f, [123], policy=StopAtXPolicy(g))
        assert res == f(123)
Example #9
0
    def test_bug1(self):
        myjitdriver = JitDriver(greens=[], reds=['n', 'node'])

        class Base:
            pass

        class A(Base):
            def decr(self, n):
                return n - 2

        class B(Base):
            def __init__(self, n):
                self.n = n

            def decr(self, n):
                assert n == self.n
                return self.n - 1

        def extern(n):
            if n <= 21:
                return B(n)
            else:
                return A()

        def f(n):
            node = A()
            while n >= 0:
                myjitdriver.can_enter_jit(node=node, n=n)
                myjitdriver.jit_merge_point(node=node, n=n)
                n = node.decr(n)
                node = extern(n)
            return n

        res = self.meta_interp(f, [60], policy=StopAtXPolicy(extern))
        assert res == f(60)
Example #10
0
    def test_assembler_call_red_args(self):
        driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'],
                           get_printable_location = lambda codeno : str(codeno))

        def residual(k):
            if k > 150:
                return 0
            return 1

        def portal(codeno, k):
            i = 0
            while i < 15:
                driver.can_enter_jit(codeno=codeno, i=i, k=k)
                driver.jit_merge_point(codeno=codeno, i=i, k=k)
                if codeno == 2:
                    k += portal(residual(k), k)
                if codeno == 0:
                    k += 2
                elif codeno == 1:
                    k += 1
                i += 1
            return k

        res = self.meta_interp(portal, [2, 0], inline=True,
                               policy=StopAtXPolicy(residual))
        assert res == portal(2, 0)
        self.check_resops(call_assembler=4)
Example #11
0
    def test_bridge_forces(self):
        jitdriver = JitDriver(greens = [], reds = ['frame'],
                              virtualizables = ['frame'])
        
        class Frame(object):
            _virtualizable2_ = ['x', 'y']
        class SomewhereElse:
            pass
        somewhere_else = SomewhereElse()

        def g():
            n = somewhere_else.top_frame.y + 700
            debug_print(lltype.Void, '-+-+-+-+- external write:', n)
            somewhere_else.top_frame.y = n

        def f(n):
            frame = Frame()
            frame.x = n
            frame.y = 10
            somewhere_else.counter = 0
            somewhere_else.top_frame = frame
            while frame.x > 0:
                jitdriver.can_enter_jit(frame=frame)
                jitdriver.jit_merge_point(frame=frame)
                if frame.y > 17:
                    g()
                frame.x -= 5
                frame.y += 1
            return frame.y

        res = self.meta_interp(f, [123], policy=StopAtXPolicy(g))
        assert res == f(123)
Example #12
0
    def test_indirect_call_unknown_object_1(self):
        myjitdriver = JitDriver(greens=[], reds=['x', 'y'])

        def getvalue2():
            return 2

        def getvalue25():
            return 25

        def getvalue1001():
            return -1001

        def externfn(n):
            if n % 5:
                return getvalue2
            elif n % 7:
                return getvalue25
            else:
                return getvalue1001

        def f(y):
            x = 0
            while y > 0:
                myjitdriver.can_enter_jit(x=x, y=y)
                myjitdriver.jit_merge_point(x=x, y=y)
                x += externfn(y)()
                y -= 1
            return x

        res = self.meta_interp(f, [198], policy=StopAtXPolicy(externfn))
        assert res == f(198)
        self.check_trace_count(4)
Example #13
0
    def test_invalidate_while_running(self):
        jitdriver = JitDriver(greens=['foo'], reds=['i', 'total'])

        class Foo(object):
            _immutable_fields_ = ['a?']

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

        def external(foo, v):
            if v:
                foo.a = 2

        def f(foo):
            i = 0
            total = 0
            while i < 10:
                jitdriver.jit_merge_point(i=i, foo=foo, total=total)
                external(foo, i > 7)
                i += 1
                total += foo.a
            return total

        def g():
            return f(Foo(1))

        assert self.meta_interp(g, [], policy=StopAtXPolicy(external)) == g()
Example #14
0
    def test_adapt_bridge_to_merge_point(self):
        myjitdriver = JitDriver(greens=[], reds=['x', 'z'])

        class Z(object):
            def __init__(self, elem):
                self.elem = elem

        def externfn(z):
            pass

        def f(x, y):
            z = Z(y)
            while x > 0:
                myjitdriver.can_enter_jit(x=x, z=z)
                myjitdriver.jit_merge_point(x=x, z=z)
                if x % 5 != 0:
                    externfn(z)
                z = Z(z.elem + 1)
                x -= 1
            return z.elem

        expected = f(100, 5)
        res = self.meta_interp(f, [100, 5], policy=StopAtXPolicy(externfn))
        assert res == expected

        if self.enable_opts:
            self.check_trace_count(2)
            self.check_jitcell_token_count(1)  # 1 loop with bridge from interp
        else:
            self.check_trace_count(2)
            self.check_jitcell_token_count(
                1)  # 1 loop, callable from the interp
Example #15
0
    def test_external_write(self):
        jitdriver = JitDriver(greens = [], reds = ['frame'],
                              virtualizables = ['frame'])

        class Frame(object):
            _virtualizable2_ = ['x', 'y']
        class SomewhereElse:
            pass
        somewhere_else = SomewhereElse()

        def g():
            result = somewhere_else.top_frame.y + 1
            debug_print(lltype.Void, '-+-+-+-+- external write:', result)
            somewhere_else.top_frame.y = result      # external read/write

        def f(n):
            frame = Frame()
            frame.x = n
            frame.y = 10
            somewhere_else.top_frame = frame
            while frame.x > 0:
                jitdriver.can_enter_jit(frame=frame)
                jitdriver.jit_merge_point(frame=frame)
                g()
                frame.x -= frame.y
            return frame.y

        res = self.meta_interp(f, [240], policy=StopAtXPolicy(g))
        assert res == f(240)
        self.check_aborted_count(3)
        self.check_jitcell_token_count(0)
Example #16
0
    def test_external_pass(self):
        jitdriver = JitDriver(greens = [], reds = ['n', 'z', 'frame'],
                              virtualizables = ['frame'])

        class BaseFrame(object):
            _virtualizable2_ = ['x[*]']

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

        class Frame(BaseFrame):
            pass

        def g(frame):
            return frame.x[1] == 1

        def f(n):
            BaseFrame([])     # hack to force 'x' to be in BaseFrame
            frame = Frame([1,2,3])
            z = 0
            while n > 0:
                jitdriver.can_enter_jit(frame=frame, n=n, z=z)
                jitdriver.jit_merge_point(frame=frame, n=n, z=z)
                z += g(frame)
                n -= 1
            return z

        res = self.meta_interp(f, [10], policy=StopAtXPolicy(g))
        assert res == f(10)
Example #17
0
 def test_single_virtual_forced_in_bridge(self):
     myjitdriver = JitDriver(greens = [], reds = ['n', 's', 'node'])
     def externfn(node):
         node.value *= 2
     def f(n, s):
         node = self._new()
         node.value = 1
         while n > 0:
             myjitdriver.can_enter_jit(n=n, s=s, node=node)
             myjitdriver.jit_merge_point(n=n, s=s, node=node)
             next = self._new()
             next.value = node.value + 1
             node = next
             if (n>>s) & 1:
                 externfn(node)
             n -= 1
         return node.value
     res = self.meta_interp(f, [48, 3], policy=StopAtXPolicy(externfn))
     assert res == f(48, 3)
     res = self.meta_interp(f, [40, 3], policy=StopAtXPolicy(externfn))
     assert res == f(40, 3)
Example #18
0
    def test_directly_call_assembler_virtualizable_force1(self):
        class Thing(object):
            def __init__(self, val):
                self.val = val
        
        class Frame(object):
            _virtualizable2_ = ['thing']
        
        driver = JitDriver(greens = ['codeno'], reds = ['i', 'frame'],
                           virtualizables = ['frame'],
                           get_printable_location = lambda codeno : str(codeno))
        class SomewhereElse(object):
            pass

        somewhere_else = SomewhereElse()

        def change(newthing):
            somewhere_else.frame.thing = newthing

        def main(codeno):
            frame = Frame()
            somewhere_else.frame = frame
            frame.thing = Thing(0)
            portal(codeno, frame)
            return frame.thing.val

        def portal(codeno, frame):
            print 'ENTER:', codeno, frame.thing.val
            i = 0
            while i < 10:
                driver.can_enter_jit(frame=frame, codeno=codeno, i=i)
                driver.jit_merge_point(frame=frame, codeno=codeno, i=i)
                nextval = frame.thing.val
                if codeno == 0:
                    subframe = Frame()
                    subframe.thing = Thing(nextval)
                    nextval = portal(1, subframe)
                elif codeno == 1:
                    if frame.thing.val > 40:
                        change(Thing(13))
                        nextval = 13
                else:
                    fatalerror("bad codeno = " + str(codeno))
                frame.thing = Thing(nextval + 1)
                i += 1
            print 'LEAVE:', codeno, frame.thing.val
            return frame.thing.val

        res = self.meta_interp(main, [0], inline=True,
                               policy=StopAtXPolicy(change))
        assert res == main(0)
Example #19
0
 def test_forced_virtual_assigned_different_class_in_bridge(self):
     myjitdriver = JitDriver(greens = [], reds = ['n', 's', 'node', 'node2'])
     def externfn(node):
         node.value += 1
     class A(object):
         def __init__(self, value):
             self.value = value
         def op(self, val):
             return self.value + val
     class B(A):
         def op(self, val):
             return self.value - val
     def f(n, s, node2):
         node = A(1)
         while n > 0:
             myjitdriver.can_enter_jit(n=n, s=s, node=node, node2=node2)
             myjitdriver.jit_merge_point(n=n, s=s, node=node, node2=node2)
             if (n>>s) & 1:
                 node2.value += node.value
                 node = node2
             else:
                 node.value = node.op(1)
                 node = A(node.value + 7)
                 externfn(node)
             n -= 1
         return node.value
     def g1(n, s):
         return f(n, s, A(2)) + f(n, s, B(2))
     def g2(n, s):
         return f(n, s, B(2)) + f(n, s, A(2))
     res = self.meta_interp(g1, [40, 3], policy=StopAtXPolicy(externfn))
     assert res == g1(40, 3)
     res = self.meta_interp(g1, [48, 3], policy=StopAtXPolicy(externfn))
     assert res == g1(48, 3)
     res = self.meta_interp(g2, [40, 3], policy=StopAtXPolicy(externfn))
     assert res == g2(40, 3)
     res = self.meta_interp(g2, [48, 3], policy=StopAtXPolicy(externfn))
     assert res == g2(48, 3)
Example #20
0
    def test_external_read_sometimes_recursive(self):
        jitdriver = JitDriver(greens = [], reds = ['rec', 'frame'],
                              virtualizables = ['frame'])
        
        class Frame(object):
            _virtualizable2_ = ['x', 'y']
        class SomewhereElse:
            pass
        somewhere_else = SomewhereElse()

        def g(rec):
            somewhere_else.counter += 1
            if somewhere_else.counter == 70:
                frame = somewhere_else.top_frame
                result1 = frame.y     # external read
                result2 = frame.back.y     # external read
                debug_print(lltype.Void, '-+-+-+-+- external read:',
                            result1, result2)
                assert result1 == 13
                assert result2 == 1023
                result = 2
            elif rec:
                res = f(4, False)
                assert res == 0 or res == -1
                result = 1
            else:
                result = 1
            return result

        def f(n, rec):
            frame = Frame()
            frame.x = n
            frame.y = 10 + 1000 * rec
            frame.back = somewhere_else.top_frame
            somewhere_else.top_frame = frame
            while frame.x > 0:
                jitdriver.can_enter_jit(frame=frame, rec=rec)
                jitdriver.jit_merge_point(frame=frame, rec=rec)
                frame.x -= g(rec)
                frame.y += 1
            somewhere_else.top_frame = frame.back
            return frame.x

        def main(n):
            somewhere_else.counter = 0
            somewhere_else.top_frame = None
            return f(n, True)

        res = self.meta_interp(main, [123], policy=StopAtXPolicy(g))
        assert res == main(123)
Example #21
0
    def test_external_read_sometimes_changing_virtuals(self):
        jitdriver = JitDriver(greens = [], reds = ['frame'],
                              virtualizables = ['frame'])
        
        class Frame(object):
            _virtualizable2_ = ['x', 'y']
        class Y:
            pass
        class SomewhereElse:
            pass
        somewhere_else = SomewhereElse()

        def g():
            somewhere_else.counter += 1
            if somewhere_else.counter == 70:
                y = somewhere_else.top_frame.y     # external read
                debug_print(lltype.Void, '-+-+-+-+- external virtual write')
                assert y.num == 123
                y.num += 2
            else:
                y = None
            return y

        def f(n):
            frame = Frame()
            frame.x = n
            somewhere_else.counter = 0
            somewhere_else.top_frame = frame
            while frame.x > 0:
                jitdriver.can_enter_jit(frame=frame)
                jitdriver.jit_merge_point(frame=frame)
                frame.y = y = Y()
                y.num = 123
                result = g()
                if frame.y is not y:
                    return -660
                if result:
                    if result is not y:
                        return -661
                    if y.num != 125:
                        return -662
                frame.y = None
                frame.x -= 1
            return frame.x

        res = self.meta_interp(f, [123], policy=StopAtXPolicy(g))
        assert res == f(123)
Example #22
0
    def test_indirect_call_unknown_object_3(self):
        myjitdriver = JitDriver(greens=[], reds=['x', 'y', 'z', 'state'])

        def getvalue2():
            return 2

        def getvalue25():
            return 25

        def getvalue1001():
            return -1001

        class State:
            count = 0

            def externfn(self, n):
                assert n == 198 - self.count
                self.count += 1
                if n % 5:
                    return getvalue2
                elif n % 7:
                    return getvalue25
                else:
                    return getvalue1001

        def f(y):
            state = State()
            x = z = 0
            while y > 0:
                myjitdriver.can_enter_jit(x=x, y=y, z=z, state=state)
                myjitdriver.jit_merge_point(x=x, y=y, z=z, state=state)
                x += z
                z = state.externfn(y)()
                y -= 1
            return x

        res = self.meta_interp(f, [198],
                               policy=StopAtXPolicy(State.externfn.im_func))
        assert res == f(198)
        # we get four TargetTokens: one for each of the 3 getvalue functions,
        # and one entering from the interpreter (the preamble)
        self.check_jitcell_token_count(1)
        self.check_target_token_count(4)
Example #23
0
 def test_bug_1(self):
     myjitdriver = JitDriver(greens=[], reds=['n', 'i', 'stack'])
     def opaque(n, i):
         if n == 1 and i == 19:
             for j in range(20):
                 res = f(0)      # recurse repeatedly, 20 times
                 assert res == 0
     def f(n):
         stack = [n]
         i = 0
         while i < 20:
             myjitdriver.can_enter_jit(n=n, i=i, stack=stack)
             myjitdriver.jit_merge_point(n=n, i=i, stack=stack)
             opaque(n, i)
             i += 1
         return stack.pop()
     res = self.meta_interp(f, [1], enable_opts='', repeat=2,
                            policy=StopAtXPolicy(opaque))
     assert res == 1
Example #24
0
    def test_three_receivers(self):
        myjitdriver = JitDriver(greens=[], reds=['y'])

        class Base:
            pass

        class W1(Base):
            def foo(self):
                return 1

        class W2(Base):
            def foo(self):
                return 2

        class W3(Base):
            def foo(self):
                return 3

        def externfn(y):
            lst = [W1, W1, W2, W2, W3, W3, W2, W1, W3]
            W = lst[y % len(lst)]
            return W()

        def f(y):
            while y > 0:
                myjitdriver.can_enter_jit(y=y)
                myjitdriver.jit_merge_point(y=y)
                w = externfn(y)
                w.foo()
                y -= 1
            return 42

        policy = StopAtXPolicy(externfn)

        for j in range(69, 75):
            res = self.meta_interp(f, [j], policy=policy)
            assert res == 42
            self.check_enter_count_at_most(5)
            self.check_trace_count_at_most(5)
Example #25
0
    def test_generalize_loop(self):
        myjitdriver = JitDriver(greens=[], reds=['i', 'obj'])

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

        def extern(obj):
            pass

        def fn(i):
            obj = A(1)
            while i > 0:
                myjitdriver.can_enter_jit(i=i, obj=obj)
                myjitdriver.jit_merge_point(i=i, obj=obj)
                obj = A(obj.n + 1)
                if i < 10:
                    extern(obj)
                i -= 1
            return obj.n

        res = self.meta_interp(fn, [20], policy=StopAtXPolicy(extern))
        assert res == 21
Example #26
0
    def test_red_builtin_send(self):
        myjitdriver = JitDriver(greens=[], reds=['i', 'counter'])
        lst = [{1: 1, 2: 2, 3: 3}, {4: 4, 5: 5}]

        def externfn(i):
            return lst[i]

        def f(i):
            counter = 20
            res = 0
            while counter > 0:
                myjitdriver.can_enter_jit(counter=counter, i=i)
                myjitdriver.jit_merge_point(counter=counter, i=i)
                dct = externfn(i)
                res = len(dct)
                counter -= 1
            return res

        res = self.meta_interp(f, [1], policy=StopAtXPolicy(externfn))
        assert res == 2
        # 'len' becomes a getfield('num_items') for now in lltype,
        # which is itself encoded as a 'getfield_gc'
        self.check_resops(call=2, getfield_gc=2)
Example #27
0
    def test_constfold_pure_oosend(self):
        myjitdriver = JitDriver(greens=[], reds=['i', 'obj'])

        class A:
            @elidable
            def foo(self):
                return 42

        def fn(n, i):
            res = 0
            obj = A()
            while i > 0:
                myjitdriver.can_enter_jit(i=i, obj=obj)
                myjitdriver.jit_merge_point(i=i, obj=obj)
                promote(obj)
                res = obj.foo()
                i -= 1
            return res

        policy = StopAtXPolicy(A.foo.im_func)
        res = self.meta_interp(fn, [1, 20], policy=policy)
        assert res == 42
        self.check_resops(call=0)
Example #28
0
    def test_send_to_single_target_method(self):
        myjitdriver = JitDriver(greens=[], reds=['i', 'counter'])

        class Foo:
            def meth(self, y):
                return self.x + y

        def externfn(i):
            foo = Foo()
            foo.x = i * 42
            return foo

        def f(i):
            counter = 20
            res = 0
            while counter > 0:
                myjitdriver.can_enter_jit(counter=counter, i=i)
                myjitdriver.jit_merge_point(counter=counter, i=i)
                foo = externfn(i)
                res = foo.meth(i)
                counter -= 1
            return res

        res = self.meta_interp(f, [1],
                               policy=StopAtXPolicy(externfn),
                               backendopt=True)
        assert res == 43
        self.check_resops({
            'int_gt': 2,
            'getfield_gc': 2,
            'guard_true': 2,
            'int_sub': 2,
            'jump': 1,
            'call': 2,
            'guard_no_exception': 2,
            'int_add': 2
        })
Example #29
0
    def test_three_classes(self):
        class Base:
            pass

        class A(Base):
            def f(self):
                return 1

        class B(Base):
            def f(self):
                return 2

        class C(Base):
            def f(self):
                return 3

        myjitdriver = JitDriver(greens=[], reds=['n'])

        def extern(n):
            if n > 40:
                return A()
            elif n > 20:
                return B()
            else:
                return C()

        def f(n):
            while n > 0:
                myjitdriver.can_enter_jit(n=n)
                myjitdriver.jit_merge_point(n=n)
                n -= extern(n).f()
            return n

        res = self.meta_interp(f, [55], policy=StopAtXPolicy(extern))
        assert res == f(55)
        self.check_jitcell_token_count(1)
Example #30
0
    def test_direct_assembler_call_translates(self):
        """Test CALL_ASSEMBLER and the recursion limit"""
        from pypy.rlib.rstackovf import StackOverflow

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

        class Frame(object):
            _virtualizable2_ = ['thing']

        driver = JitDriver(greens=['codeno'],
                           reds=['i', 'frame'],
                           virtualizables=['frame'],
                           get_printable_location=lambda codeno: str(codeno))

        class SomewhereElse(object):
            pass

        somewhere_else = SomewhereElse()

        def change(newthing):
            somewhere_else.frame.thing = newthing

        def main(codeno):
            frame = Frame()
            somewhere_else.frame = frame
            frame.thing = Thing(0)
            portal(codeno, frame)
            return frame.thing.val

        def portal(codeno, frame):
            i = 0
            while i < 10:
                driver.can_enter_jit(frame=frame, codeno=codeno, i=i)
                driver.jit_merge_point(frame=frame, codeno=codeno, i=i)
                nextval = frame.thing.val
                if codeno == 0:
                    subframe = Frame()
                    subframe.thing = Thing(nextval)
                    nextval = portal(1, subframe)
                elif frame.thing.val > 40:
                    change(Thing(13))
                    nextval = 13
                frame.thing = Thing(nextval + 1)
                i += 1
            return frame.thing.val

        driver2 = JitDriver(greens=[], reds=['n'])

        def main2(bound):
            try:
                while portal2(bound) == -bound + 1:
                    bound *= 2
            except StackOverflow:
                pass
            return bound

        def portal2(n):
            while True:
                driver2.jit_merge_point(n=n)
                n -= 1
                if n <= 0:
                    return n
                n = portal2(n)

        assert portal2(10) == -9

        def mainall(codeno, bound):
            return main(codeno) + main2(bound)

        res = self.meta_interp(mainall, [0, 1],
                               inline=True,
                               policy=StopAtXPolicy(change))
        print hex(res)
        assert res & 255 == main(0)
        bound = res & ~255
        assert 1024 <= bound <= 131072
        assert bound & (bound - 1) == 0  # a power of two