PageRenderTime 46ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

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

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