PageRenderTime 121ms CodeModel.GetById 21ms app.highlight 90ms RepoModel.GetById 1ms app.codeStats 1ms

/pypy/jit/backend/x86/test/test_runner.py

https://bitbucket.org/pypy/pypy/
Python | 584 lines | 503 code | 54 blank | 27 comment | 39 complexity | 861aea1023eae995aebbe20e72514fc6 MD5 | raw file
  1import py
  2from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr, rclass
  3from pypy.rpython.annlowlevel import llhelper
  4from pypy.jit.metainterp.history import ResOperation, TargetToken, JitCellToken
  5from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstFloat,
  6                                         ConstPtr, Box, BoxFloat,
  7                                         BasicFailDescr)
  8from pypy.jit.backend.detect_cpu import getcpuclass
  9from pypy.jit.backend.x86.arch import WORD
 10from pypy.jit.backend.x86.rx86 import fits_in_32bits
 11from pypy.jit.backend.llsupport import symbolic
 12from pypy.jit.metainterp.resoperation import rop
 13from pypy.jit.metainterp.executor import execute
 14from pypy.jit.backend.test.runner_test import LLtypeBackendTest
 15from pypy.jit.tool.oparser import parse
 16from pypy.tool.udir import udir
 17import ctypes
 18import sys
 19import os
 20
 21CPU = getcpuclass()
 22
 23class FakeStats(object):
 24    pass
 25
 26U = LLtypeBackendTest.U
 27S = LLtypeBackendTest.S
 28
 29# ____________________________________________________________
 30
 31class TestX86(LLtypeBackendTest):
 32
 33    # for the individual tests see
 34    # ====> ../../test/runner_test.py
 35
 36    add_loop_instructions = ['mov', 'add', 'test', 'je', 'jmp']
 37    if WORD == 4:
 38        bridge_loop_instructions = ['lea', 'jmp']
 39    else:
 40        # the 'mov' is part of the 'jmp' so far
 41        bridge_loop_instructions = ['lea', 'mov', 'jmp']
 42
 43    def setup_method(self, meth):
 44        self.cpu = CPU(rtyper=None, stats=FakeStats())
 45        self.cpu.setup_once()
 46
 47    def test_execute_ptr_operation(self):
 48        cpu = self.cpu
 49        u = lltype.malloc(U)
 50        u_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, u))
 51        ofs = cpu.fielddescrof(S, 'value')
 52        assert self.execute_operation(rop.SETFIELD_GC,
 53                                      [u_box, BoxInt(3)],
 54                                     'void', ofs) == None
 55        assert u.parent.parent.value == 3
 56        u.parent.parent.value += 100
 57        assert (self.execute_operation(rop.GETFIELD_GC, [u_box], 'int', ofs)
 58                .value == 103)
 59
 60    def test_unicode(self):
 61        ofs = symbolic.get_field_token(rstr.UNICODE, 'chars', False)[0]
 62        u = rstr.mallocunicode(13)
 63        for i in range(13):
 64            u.chars[i] = unichr(ord(u'a') + i)
 65        b = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, u))
 66        r = self.execute_operation(rop.UNICODEGETITEM, [b, ConstInt(2)], 'int')
 67        assert r.value == ord(u'a') + 2
 68        self.execute_operation(rop.UNICODESETITEM, [b, ConstInt(2),
 69                                                    ConstInt(ord(u'z'))],
 70                               'void')
 71        assert u.chars[2] == u'z'
 72        assert u.chars[3] == u'd'
 73
 74    @staticmethod
 75    def _resbuf(res, item_tp=ctypes.c_long):
 76        return ctypes.cast(res.value._obj.intval, ctypes.POINTER(item_tp))
 77
 78    def test_allocations(self):
 79        py.test.skip("rewrite or kill")
 80        from pypy.rpython.lltypesystem import rstr
 81
 82        allocs = [None]
 83        all = []
 84        orig_new = self.cpu.gc_ll_descr.funcptr_for_new
 85        def f(size):
 86            allocs.insert(0, size)
 87            return orig_new(size)
 88
 89        self.cpu.assembler.setup_once()
 90        self.cpu.gc_ll_descr.funcptr_for_new = f
 91        ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0]
 92
 93        res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref')
 94        assert allocs[0] == 7 + ofs + WORD
 95        resbuf = self._resbuf(res)
 96        assert resbuf[ofs/WORD] == 7
 97
 98        # ------------------------------------------------------------
 99
100        res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref')
101        assert allocs[0] == 7 + ofs + WORD
102        resbuf = self._resbuf(res)
103        assert resbuf[ofs/WORD] == 7
104
105        # ------------------------------------------------------------
106
107        TP = lltype.GcArray(lltype.Signed)
108        ofs = symbolic.get_field_token(TP, 'length', False)[0]
109        descr = self.cpu.arraydescrof(TP)
110
111        res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)],
112                                         'ref', descr)
113        assert allocs[0] == 10*WORD + ofs + WORD
114        resbuf = self._resbuf(res)
115        assert resbuf[ofs/WORD] == 10
116
117        # ------------------------------------------------------------
118
119        res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)],
120                                         'ref', descr)
121        assert allocs[0] == 10*WORD + ofs + WORD
122        resbuf = self._resbuf(res)
123        assert resbuf[ofs/WORD] == 10
124
125    def test_stringitems(self):
126        from pypy.rpython.lltypesystem.rstr import STR
127        ofs = symbolic.get_field_token(STR, 'chars', False)[0]
128        ofs_items = symbolic.get_field_token(STR.chars, 'items', False)[0]
129
130        res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ref')
131        self.execute_operation(rop.STRSETITEM, [res, ConstInt(2), ConstInt(ord('d'))], 'void')
132        resbuf = self._resbuf(res, ctypes.c_char)
133        assert resbuf[ofs + ofs_items + 2] == 'd'
134        self.execute_operation(rop.STRSETITEM, [res, BoxInt(2), ConstInt(ord('z'))], 'void')
135        assert resbuf[ofs + ofs_items + 2] == 'z'
136        r = self.execute_operation(rop.STRGETITEM, [res, BoxInt(2)], 'int')
137        assert r.value == ord('z')
138
139    def test_arrayitems(self):
140        TP = lltype.GcArray(lltype.Signed)
141        ofs = symbolic.get_field_token(TP, 'length', False)[0]
142        itemsofs = symbolic.get_field_token(TP, 'items', False)[0]
143        descr = self.cpu.arraydescrof(TP)
144        res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)],
145                                     'ref', descr)
146        resbuf = self._resbuf(res)
147        assert resbuf[ofs/WORD] == 10
148        self.execute_operation(rop.SETARRAYITEM_GC, [res,
149                                                     ConstInt(2), BoxInt(38)],
150                               'void', descr)
151        assert resbuf[itemsofs/WORD + 2] == 38
152
153        self.execute_operation(rop.SETARRAYITEM_GC, [res,
154                                                     BoxInt(3), BoxInt(42)],
155                               'void', descr)
156        assert resbuf[itemsofs/WORD + 3] == 42
157
158        r = self.execute_operation(rop.GETARRAYITEM_GC, [res, ConstInt(2)],
159                                   'int', descr)
160        assert r.value == 38
161        r = self.execute_operation(rop.GETARRAYITEM_GC, [res.constbox(),
162                                                         BoxInt(2)],
163                                   'int', descr)
164        assert r.value == 38
165        r = self.execute_operation(rop.GETARRAYITEM_GC, [res.constbox(),
166                                                         ConstInt(2)],
167                                   'int', descr)
168        assert r.value == 38
169        r = self.execute_operation(rop.GETARRAYITEM_GC, [res,
170                                                         BoxInt(2)],
171                                   'int', descr)
172        assert r.value == 38
173
174        r = self.execute_operation(rop.GETARRAYITEM_GC, [res, BoxInt(3)],
175                                   'int', descr)
176        assert r.value == 42
177
178    def test_arrayitems_not_int(self):
179        TP = lltype.GcArray(lltype.Char)
180        ofs = symbolic.get_field_token(TP, 'length', False)[0]
181        itemsofs = symbolic.get_field_token(TP, 'items', False)[0]
182        descr = self.cpu.arraydescrof(TP)
183        res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)],
184                                     'ref', descr)
185        resbuf = self._resbuf(res, ctypes.c_char)
186        assert resbuf[ofs] == chr(10)
187        for i in range(10):
188            self.execute_operation(rop.SETARRAYITEM_GC, [res,
189                                                   ConstInt(i), BoxInt(i)],
190                                   'void', descr)
191        for i in range(10):
192            assert resbuf[itemsofs + i] == chr(i)
193        for i in range(10):
194            r = self.execute_operation(rop.GETARRAYITEM_GC, [res,
195                                                             ConstInt(i)],
196                                         'int', descr)
197            assert r.value == i
198
199    def test_getfield_setfield(self):
200        TP = lltype.GcStruct('x', ('s', lltype.Signed),
201                             ('i', rffi.INT),
202                             ('f', lltype.Float),
203                             ('u', rffi.USHORT),
204                             ('c1', lltype.Char),
205                             ('c2', lltype.Char),
206                             ('c3', lltype.Char))
207        res = self.execute_operation(rop.NEW, [],
208                                     'ref', self.cpu.sizeof(TP))
209        ofs_s = self.cpu.fielddescrof(TP, 's')
210        ofs_i = self.cpu.fielddescrof(TP, 'i')
211        #ofs_f = self.cpu.fielddescrof(TP, 'f')
212        ofs_u = self.cpu.fielddescrof(TP, 'u')
213        ofsc1 = self.cpu.fielddescrof(TP, 'c1')
214        ofsc2 = self.cpu.fielddescrof(TP, 'c2')
215        ofsc3 = self.cpu.fielddescrof(TP, 'c3')
216        self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(3)], 'void',
217                               ofs_s)
218        # XXX ConstFloat
219        #self.execute_operation(rop.SETFIELD_GC, [res, ofs_f, 1e100], 'void')
220        # XXX we don't support shorts (at all)
221        #self.execute_operation(rop.SETFIELD_GC, [res, ofs_u, ConstInt(5)], 'void')
222        s = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_s)
223        assert s.value == 3
224        self.execute_operation(rop.SETFIELD_GC, [res, BoxInt(3)], 'void',
225                               ofs_s)
226        s = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_s)
227        assert s.value == 3
228
229        self.execute_operation(rop.SETFIELD_GC, [res, BoxInt(1234)], 'void', ofs_i)
230        i = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofs_i)
231        assert i.value == 1234
232
233        #u = self.execute_operation(rop.GETFIELD_GC, [res, ofs_u], 'int')
234        #assert u.value == 5
235        self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(1)], 'void',
236                               ofsc1)
237        self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(3)], 'void',
238                               ofsc3)
239        self.execute_operation(rop.SETFIELD_GC, [res, ConstInt(2)], 'void',
240                               ofsc2)
241        c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc1)
242        assert c.value == 1
243        c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc2)
244        assert c.value == 2
245        c = self.execute_operation(rop.GETFIELD_GC, [res], 'int', ofsc3)
246        assert c.value == 3
247
248    def test_bug_setfield_64bit(self):
249        if WORD == 4:
250            py.test.skip("only for 64 bits")
251        TP = lltype.GcStruct('S', ('i', lltype.Signed))
252        ofsi = self.cpu.fielddescrof(TP, 'i')
253        for i in range(500):
254            p = lltype.malloc(TP)
255            addr = rffi.cast(lltype.Signed, p)
256            if fits_in_32bits(addr):
257                break    # fitting in 32 bits, good
258        else:
259            py.test.skip("cannot get a 32-bit pointer")
260        res = ConstPtr(rffi.cast(llmemory.GCREF, addr))
261        self.execute_operation(rop.SETFIELD_RAW, [res, ConstInt(3**33)],
262                               'void', ofsi)
263        assert p.i == 3**33
264
265    def test_nullity_with_guard(self):
266        allops = [rop.INT_IS_TRUE]
267        guards = [rop.GUARD_TRUE, rop.GUARD_FALSE]
268        p = lltype.cast_opaque_ptr(llmemory.GCREF,
269                                   lltype.malloc(lltype.GcStruct('x')))
270        nullptr = lltype.nullptr(llmemory.GCREF.TO)
271        f = BoxInt()
272        for op in allops:
273            for guard in guards:
274                if op == rop.INT_IS_TRUE:
275                    bp = BoxInt(1)
276                    n = BoxInt(0)
277                else:
278                    bp = BoxPtr(p)
279                    n = BoxPtr(nullptr)
280                for b in (bp, n):
281                    i1 = BoxInt(1)
282                    ops = [
283                        ResOperation(rop.SAME_AS, [ConstInt(1)], i1),
284                        ResOperation(op, [b], f),
285                        ResOperation(guard, [f], None,
286                                     descr=BasicFailDescr()),
287                        ResOperation(rop.FINISH, [ConstInt(0)], None,
288                                     descr=BasicFailDescr()),
289                        ]
290                    ops[-2].setfailargs([i1])
291                    looptoken = JitCellToken()
292                    self.cpu.compile_loop([b], ops, looptoken)
293                    self.cpu.execute_token(looptoken, b.value)
294                    result = self.cpu.get_latest_value_int(0)
295                    if guard == rop.GUARD_FALSE:
296                        assert result == execute(self.cpu, None,
297                                                 op, None, b).value
298                    else:
299                        assert result != execute(self.cpu, None,
300                                                 op, None, b).value
301
302
303    def test_stuff_followed_by_guard(self):
304        boxes = [(BoxInt(1), BoxInt(0)),
305                 (BoxInt(0), BoxInt(1)),
306                 (BoxInt(1), BoxInt(1)),
307                 (BoxInt(-1), BoxInt(1)),
308                 (BoxInt(1), BoxInt(-1)),
309                 (ConstInt(1), BoxInt(0)),
310                 (ConstInt(0), BoxInt(1)),
311                 (ConstInt(1), BoxInt(1)),
312                 (ConstInt(-1), BoxInt(1)),
313                 (ConstInt(1), BoxInt(-1)),
314                 (BoxInt(1), ConstInt(0)),
315                 (BoxInt(0), ConstInt(1)),
316                 (BoxInt(1), ConstInt(1)),
317                 (BoxInt(-1), ConstInt(1)),
318                 (BoxInt(1), ConstInt(-1))]
319        guards = [rop.GUARD_FALSE, rop.GUARD_TRUE]
320        all = [rop.INT_EQ, rop.INT_NE, rop.INT_LE, rop.INT_LT, rop.INT_GT,
321               rop.INT_GE, rop.UINT_GT, rop.UINT_LT, rop.UINT_LE, rop.UINT_GE]
322        for a, b in boxes:
323            for guard in guards:
324                for op in all:
325                    res = BoxInt()
326                    i1 = BoxInt(1)
327                    ops = [
328                        ResOperation(rop.SAME_AS, [ConstInt(1)], i1),
329                        ResOperation(op, [a, b], res),
330                        ResOperation(guard, [res], None,
331                                     descr=BasicFailDescr()),
332                        ResOperation(rop.FINISH, [ConstInt(0)], None,
333                                     descr=BasicFailDescr()),
334                        ]
335                    ops[-2].setfailargs([i1])
336                    inputargs = [i for i in (a, b) if isinstance(i, Box)]
337                    looptoken = JitCellToken()
338                    self.cpu.compile_loop(inputargs, ops, looptoken)
339                    inputvalues = [box.value for box in inputargs]
340                    self.cpu.execute_token(looptoken, *inputvalues)
341                    result = self.cpu.get_latest_value_int(0)
342                    expected = execute(self.cpu, None, op, None, a, b).value
343                    if guard == rop.GUARD_FALSE:
344                        assert result == expected
345                    else:
346                        assert result != expected
347
348    def test_compile_bridge_check_profile_info(self):
349        py.test.skip("does not work, reinvestigate")
350        class FakeProfileAgent(object):
351            def __init__(self):
352                self.functions = []
353            def native_code_written(self, name, address, size):
354                self.functions.append((name, address, size))
355        self.cpu.profile_agent = agent = FakeProfileAgent()
356
357        i0 = BoxInt()
358        i1 = BoxInt()
359        i2 = BoxInt()
360        targettoken = TargetToken()
361        faildescr1 = BasicFailDescr(1)
362        faildescr2 = BasicFailDescr(2)
363        looptoken = JitCellToken()
364        looptoken.number = 17
365        class FakeString(object):
366            def __init__(self, val):
367                self.val = val
368
369            def _get_str(self):
370                return self.val
371
372        operations = [
373            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
374            ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("hello"), 0], None),
375            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
376            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
377            ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
378            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
379            ]
380        inputargs = [i0]
381        operations[-2].setfailargs([i1])
382        self.cpu.compile_loop(inputargs, operations, looptoken)
383        name, loopaddress, loopsize = agent.functions[0]
384        assert name == "Loop # 17: hello (loop counter 0)"
385        assert loopaddress <= looptoken._x86_loop_code
386        assert loopsize >= 40 # randomish number
387
388        i1b = BoxInt()
389        i3 = BoxInt()
390        bridge = [
391            ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3),
392            ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2),
393            ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("bye"), 0], None),
394            ResOperation(rop.JUMP, [i1b], None, descr=targettoken),
395        ]
396        bridge[1].setfailargs([i1b])
397
398        self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken)
399        name, address, size = agent.functions[1]
400        assert name == "Bridge # 0: bye (loop counter 1)"
401        # Would be exactly ==, but there are some guard failure recovery
402        # stubs in-between
403        assert address >= loopaddress + loopsize
404        assert size >= 10 # randomish number
405
406        fail = self.cpu.execute_token(looptoken, 2)
407        assert fail.identifier == 2
408        res = self.cpu.get_latest_value_int(0)
409        assert res == 20
410
411    def test_ops_offset(self):
412        from pypy.rlib import debug
413        i0 = BoxInt()
414        i1 = BoxInt()
415        i2 = BoxInt()
416        looptoken = JitCellToken()
417        targettoken = TargetToken()
418        operations = [
419            ResOperation(rop.LABEL, [i0], None, descr=targettoken),
420            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
421            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
422            ResOperation(rop.JUMP, [i1], None, descr=targettoken),
423            ]
424        inputargs = [i0]
425        debug._log = dlog = debug.DebugLog()
426        info = self.cpu.compile_loop(inputargs, operations, looptoken)
427        ops_offset = info.ops_offset
428        debug._log = None
429        #
430        assert ops_offset is looptoken._x86_ops_offset
431        # 2*(getfield_raw/int_add/setfield_raw) + ops + None
432        assert len(ops_offset) == 2*3 + len(operations) + 1
433        assert (ops_offset[operations[0]] <=
434                ops_offset[operations[1]] <=
435                ops_offset[operations[2]] <=
436                ops_offset[None])
437
438    def test_calling_convention(self, monkeypatch):
439        if WORD != 4:
440            py.test.skip("32-bit only test")
441        from pypy.jit.backend.x86.regloc import eax, edx
442        from pypy.jit.backend.x86 import codebuf
443        from pypy.jit.codewriter.effectinfo import EffectInfo
444        from pypy.rlib.libffi import types, clibffi
445        had_stdcall = hasattr(clibffi, 'FFI_STDCALL')
446        if not had_stdcall:    # not running on Windows, but we can still test
447            monkeypatch.setattr(clibffi, 'FFI_STDCALL', 12345, raising=False)
448        #
449        for ffi in [clibffi.FFI_DEFAULT_ABI, clibffi.FFI_STDCALL]:
450            cpu = self.cpu
451            mc = codebuf.MachineCodeBlockWrapper()
452            mc.MOV_rs(eax.value, 4)      # argument 1
453            mc.MOV_rs(edx.value, 40)     # argument 10
454            mc.SUB_rr(eax.value, edx.value)     # return arg1 - arg10
455            if ffi == clibffi.FFI_DEFAULT_ABI:
456                mc.RET()
457            else:
458                mc.RET16_i(40)
459            rawstart = mc.materialize(cpu.asmmemmgr, [])
460            #
461            calldescr = cpu.calldescrof_dynamic([types.slong] * 10,
462                                                types.slong,
463                                                EffectInfo.MOST_GENERAL,
464                                                ffi_flags=-1)
465            calldescr.get_call_conv = lambda: ffi      # <==== hack
466            # ^^^ we patch get_call_conv() so that the test also makes sense
467            #     on Linux, because clibffi.get_call_conv() would always
468            #     return FFI_DEFAULT_ABI on non-Windows platforms.
469            funcbox = ConstInt(rawstart)
470            i1 = BoxInt()
471            i2 = BoxInt()
472            i3 = BoxInt()
473            i4 = BoxInt()
474            i5 = BoxInt()
475            i6 = BoxInt()
476            c = ConstInt(-1)
477            faildescr = BasicFailDescr(1)
478            # we must call it repeatedly: if the stack pointer gets increased
479            # by 40 bytes by the STDCALL call, and if we don't expect it,
480            # then we are going to get our stack emptied unexpectedly by
481            # several repeated calls
482            ops = [
483            ResOperation(rop.CALL_RELEASE_GIL,
484                         [funcbox, i1, c, c, c, c, c, c, c, c, i2],
485                         i3, descr=calldescr),
486            ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
487
488            ResOperation(rop.CALL_RELEASE_GIL,
489                         [funcbox, i1, c, c, c, c, c, c, c, c, i2],
490                         i4, descr=calldescr),
491            ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
492
493            ResOperation(rop.CALL_RELEASE_GIL,
494                         [funcbox, i1, c, c, c, c, c, c, c, c, i2],
495                         i5, descr=calldescr),
496            ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
497
498            ResOperation(rop.CALL_RELEASE_GIL,
499                         [funcbox, i1, c, c, c, c, c, c, c, c, i2],
500                         i6, descr=calldescr),
501            ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
502
503            ResOperation(rop.FINISH, [i3, i4, i5, i6], None,
504                         descr=BasicFailDescr(0))
505            ]
506            ops[1].setfailargs([])
507            ops[3].setfailargs([])
508            ops[5].setfailargs([])
509            ops[7].setfailargs([])
510            looptoken = JitCellToken()
511            self.cpu.compile_loop([i1, i2], ops, looptoken)
512
513            fail = self.cpu.execute_token(looptoken, 123450, 123408)
514            assert fail.identifier == 0
515            assert self.cpu.get_latest_value_int(0) == 42
516            assert self.cpu.get_latest_value_int(1) == 42
517            assert self.cpu.get_latest_value_int(2) == 42
518            assert self.cpu.get_latest_value_int(3) == 42
519
520
521class TestDebuggingAssembler(object):
522    def setup_method(self, meth):
523        self.cpu = CPU(rtyper=None, stats=FakeStats())
524        self.cpu.setup_once()
525
526    def test_debugger_on(self):
527        from pypy.tool.logparser import parse_log_file, extract_category
528        from pypy.rlib import debug
529
530        targettoken, preambletoken = TargetToken(), TargetToken()
531        loop = """
532        [i0]
533        label(i0, descr=preambletoken)
534        debug_merge_point('xyz', 0)
535        i1 = int_add(i0, 1)
536        i2 = int_ge(i1, 10)
537        guard_false(i2) []
538        label(i1, descr=targettoken)
539        debug_merge_point('xyz', 0)
540        i11 = int_add(i1, 1)
541        i12 = int_ge(i11, 10)
542        guard_false(i12) []
543        jump(i11, descr=targettoken)
544        """
545        ops = parse(loop, namespace={'targettoken': targettoken,
546                                     'preambletoken': preambletoken})
547        debug._log = dlog = debug.DebugLog()
548        try:
549            self.cpu.assembler.set_debug(True)
550            looptoken = JitCellToken()
551            self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
552            self.cpu.execute_token(looptoken, 0)
553            # check debugging info
554            struct = self.cpu.assembler.loop_run_counters[0]
555            assert struct.i == 1
556            struct = self.cpu.assembler.loop_run_counters[1]
557            assert struct.i == 1
558            struct = self.cpu.assembler.loop_run_counters[2]
559            assert struct.i == 9
560            self.cpu.finish_once()
561        finally:
562            debug._log = None
563        l0 = ('debug_print', 'entry -1:1')
564        l1 = ('debug_print', preambletoken.repr_of_descr() + ':1')
565        l2 = ('debug_print', targettoken.repr_of_descr() + ':9')
566        assert ('jit-backend-counts', [l0, l1, l2]) in dlog
567
568    def test_debugger_checksum(self):
569        loop = """
570        [i0]
571        label(i0, descr=targettoken)
572        debug_merge_point('xyz', 0)
573        i1 = int_add(i0, 1)
574        i2 = int_ge(i1, 10)
575        guard_false(i2) []
576        jump(i1, descr=targettoken)
577        """
578        ops = parse(loop, namespace={'targettoken': TargetToken()})
579        self.cpu.assembler.set_debug(True)
580        looptoken = JitCellToken()
581        self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
582        self.cpu.execute_token(looptoken, 0)
583        assert looptoken._x86_debug_checksum == sum([op.getopnum()
584                                                     for op in ops.operations])