PageRenderTime 84ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/rpython/jit/metainterp/test/test_ajit.py

https://bitbucket.org/pjenvey/pypy-mq
Python | 4560 lines | 4420 code | 94 blank | 46 comment | 126 complexity | 1f30b04b5733a42c4019afd57a910876 MD5 | raw file
Possible License(s): Apache-2.0, AGPL-3.0, BSD-3-Clause
  1. import sys
  2. import py
  3. import weakref
  4. from rpython.rlib import rgc
  5. from rpython.jit.codewriter.policy import StopAtXPolicy
  6. from rpython.jit.metainterp import history
  7. from rpython.jit.metainterp.test.support import LLJitMixin, noConst
  8. from rpython.jit.metainterp.warmspot import get_stats
  9. from rpython.rlib import rerased
  10. from rpython.rlib.jit import (JitDriver, we_are_jitted, hint, dont_look_inside,
  11. loop_invariant, elidable, promote, jit_debug, assert_green,
  12. AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
  13. isconstant, isvirtual, set_param, record_exact_class)
  14. from rpython.rlib.longlong2float import float2longlong, longlong2float
  15. from rpython.rlib.rarithmetic import ovfcheck, is_valid_int, int_force_ge_zero
  16. from rpython.rtyper.lltypesystem import lltype, rffi
  17. class BasicTests:
  18. def test_basic(self):
  19. def f(x, y):
  20. return x + y
  21. res = self.interp_operations(f, [40, 2])
  22. assert res == 42
  23. def test_basic_inst(self):
  24. class A:
  25. pass
  26. def f(n):
  27. a = A()
  28. a.x = n
  29. return a.x
  30. res = self.interp_operations(f, [42])
  31. assert res == 42
  32. def test_uint_floordiv(self):
  33. from rpython.rlib.rarithmetic import r_uint
  34. def f(a, b):
  35. a = r_uint(a)
  36. b = r_uint(b)
  37. return a/b
  38. res = self.interp_operations(f, [-4, 3])
  39. assert res == long(r_uint(-4)) // 3
  40. def test_direct_call(self):
  41. def g(n):
  42. return n + 2
  43. def f(a, b):
  44. return g(a) + g(b)
  45. res = self.interp_operations(f, [8, 98])
  46. assert res == 110
  47. def test_direct_call_with_guard(self):
  48. def g(n):
  49. if n < 0:
  50. return 0
  51. return n + 2
  52. def f(a, b):
  53. return g(a) + g(b)
  54. res = self.interp_operations(f, [8, 98])
  55. assert res == 110
  56. def test_loop_1(self):
  57. myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
  58. def f(x, y):
  59. res = 0
  60. while y > 0:
  61. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  62. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  63. res += x
  64. y -= 1
  65. return res
  66. res = self.meta_interp(f, [6, 7])
  67. assert res == 42
  68. self.check_trace_count(1)
  69. self.check_resops({'jump': 1, 'int_gt': 2, 'int_add': 2,
  70. 'guard_true': 2, 'int_sub': 2})
  71. if self.basic:
  72. found = 0
  73. for op in get_stats().get_all_loops()[0]._all_operations():
  74. if op.getopname() == 'guard_true':
  75. liveboxes = op.getfailargs()
  76. assert len(liveboxes) == 3
  77. for box in liveboxes:
  78. assert box.type == 'i'
  79. found += 1
  80. assert found == 2
  81. def test_loop_variant_mul1(self):
  82. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
  83. def f(x, y):
  84. res = 0
  85. while y > 0:
  86. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  87. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  88. res += x * x
  89. x += 1
  90. res += x * x
  91. y -= 1
  92. return res
  93. res = self.meta_interp(f, [6, 7])
  94. assert res == 1323
  95. self.check_trace_count(1)
  96. self.check_simple_loop(int_mul=1)
  97. def test_loop_variant_mul_ovf(self):
  98. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
  99. def f(x, y):
  100. res = 0
  101. while y > 0:
  102. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  103. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  104. try:
  105. res += ovfcheck(x * x)
  106. x += 1
  107. res += ovfcheck(x * x)
  108. y -= 1
  109. except OverflowError:
  110. assert 0
  111. return res
  112. res = self.meta_interp(f, [6, 7])
  113. assert res == 1323
  114. self.check_trace_count(1)
  115. self.check_simple_loop(int_mul_ovf=1)
  116. def test_loop_invariant_mul1(self):
  117. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
  118. def f(x, y):
  119. res = 0
  120. while y > 0:
  121. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  122. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  123. res += x * x
  124. y -= 1
  125. return res
  126. res = self.meta_interp(f, [6, 7])
  127. assert res == 252
  128. self.check_trace_count(1)
  129. self.check_simple_loop(int_mul=0)
  130. self.check_resops({'jump': 1, 'int_gt': 2, 'int_add': 2,
  131. 'int_mul': 1, 'guard_true': 2, 'int_sub': 2})
  132. def test_loop_invariant_mul_ovf1(self):
  133. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
  134. def f(x, y):
  135. res = 0
  136. while y > 0:
  137. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  138. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  139. b = y * 2
  140. try:
  141. res += ovfcheck(x * x) + b
  142. except OverflowError:
  143. assert 0
  144. y -= 1
  145. return res
  146. res = self.meta_interp(f, [6, 7])
  147. assert res == 308
  148. self.check_trace_count(1)
  149. self.check_simple_loop(int_mul_ovf=0)
  150. self.check_resops({'jump': 1, 'int_lshift': 2, 'int_gt': 2,
  151. 'int_mul_ovf': 1, 'int_add': 4,
  152. 'guard_true': 2, 'guard_no_overflow': 1,
  153. 'int_sub': 2})
  154. def test_loop_invariant_mul_bridge1(self):
  155. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x', 'n'])
  156. def f(x, y, n):
  157. res = 0
  158. while y > 0:
  159. myjitdriver.can_enter_jit(x=x, y=y, n=n, res=res)
  160. myjitdriver.jit_merge_point(x=x, y=y, n=n, res=res)
  161. res += x * x
  162. if y<n:
  163. x += 1
  164. y -= 1
  165. return res
  166. res = self.meta_interp(f, [6, 32, 16])
  167. assert res == 3427
  168. self.check_trace_count(3)
  169. def test_loop_invariant_mul_bridge_maintaining1(self):
  170. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x', 'n'])
  171. def f(x, y, n):
  172. res = 0
  173. while y > 0:
  174. myjitdriver.can_enter_jit(x=x, y=y, res=res, n=n)
  175. myjitdriver.jit_merge_point(x=x, y=y, res=res, n=n)
  176. res += x * x
  177. if y<n:
  178. res += 1
  179. y -= 1
  180. return res
  181. res = self.meta_interp(f, [6, 32, 16])
  182. assert res == 1167
  183. self.check_trace_count(3)
  184. self.check_resops(int_mul=3)
  185. def test_loop_invariant_mul_bridge_maintaining2(self):
  186. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x', 'n'])
  187. def f(x, y, n):
  188. res = 0
  189. while y > 0:
  190. myjitdriver.can_enter_jit(x=x, y=y, res=res, n=n)
  191. myjitdriver.jit_merge_point(x=x, y=y, res=res, n=n)
  192. z = x * x
  193. res += z
  194. if y<n:
  195. res += z
  196. y -= 1
  197. return res
  198. res = self.meta_interp(f, [6, 32, 16])
  199. assert res == 1692
  200. self.check_trace_count(3)
  201. self.check_resops(int_mul=3)
  202. def test_loop_invariant_mul_bridge_maintaining3(self):
  203. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x', 'm'])
  204. def f(x, y, m):
  205. res = 0
  206. while y > 0:
  207. myjitdriver.can_enter_jit(x=x, y=y, res=res, m=m)
  208. myjitdriver.jit_merge_point(x=x, y=y, res=res, m=m)
  209. z = x * x
  210. res += z
  211. if y<m:
  212. res += z
  213. y -= 1
  214. return res
  215. res = self.meta_interp(f, [6, 32, 16])
  216. assert res == 1692
  217. self.check_trace_count(3)
  218. self.check_resops({'int_lt': 4, 'int_gt': 4, 'guard_false': 2,
  219. 'guard_true': 6, 'int_sub': 4, 'jump': 3,
  220. 'int_mul': 3, 'int_add': 4})
  221. def test_loop_invariant_mul_ovf2(self):
  222. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
  223. def f(x, y):
  224. res = 0
  225. while y > 0:
  226. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  227. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  228. b = y * 2
  229. try:
  230. res += ovfcheck(x * x) + b
  231. except OverflowError:
  232. res += 1
  233. y -= 1
  234. return res
  235. res = self.meta_interp(f, [sys.maxint, 7])
  236. assert res == f(sys.maxint, 7)
  237. self.check_trace_count(1)
  238. res = self.meta_interp(f, [6, 7])
  239. assert res == 308
  240. def test_loop_invariant_mul_bridge_ovf1(self):
  241. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x1', 'x2'])
  242. def f(x1, x2, y):
  243. res = 0
  244. while y > 0:
  245. myjitdriver.can_enter_jit(x1=x1, x2=x2, y=y, res=res)
  246. myjitdriver.jit_merge_point(x1=x1, x2=x2, y=y, res=res)
  247. try:
  248. res += ovfcheck(x1 * x1)
  249. except OverflowError:
  250. res += 1
  251. if y<32 and (y>>2)&1==0:
  252. x1, x2 = x2, x1
  253. y -= 1
  254. return res
  255. res = self.meta_interp(f, [6, sys.maxint, 48])
  256. self.check_trace_count(6)
  257. assert res == f(6, sys.maxint, 48)
  258. def test_loop_invariant_mul_bridge_ovf2(self):
  259. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x1', 'x2', 'n'])
  260. def f(x1, x2, n, y):
  261. res = 0
  262. while y > 0:
  263. myjitdriver.can_enter_jit(x1=x1, x2=x2, y=y, res=res, n=n)
  264. myjitdriver.jit_merge_point(x1=x1, x2=x2, y=y, res=res, n=n)
  265. try:
  266. res += ovfcheck(x1 * x1)
  267. except OverflowError:
  268. res += 1
  269. y -= 1
  270. if y&4 == 0:
  271. x1, x2 = x2, x1
  272. return res
  273. res = self.meta_interp(f, [6, sys.maxint, 32, 48])
  274. assert res == f(6, sys.maxint, 32, 48)
  275. res = self.meta_interp(f, [sys.maxint, 6, 32, 48])
  276. assert res == f(sys.maxint, 6, 32, 48)
  277. def test_loop_invariant_intbox(self):
  278. myjitdriver = JitDriver(greens = [], reds = ['y', 'res', 'x'])
  279. class I:
  280. __slots__ = 'intval'
  281. _immutable_ = True
  282. def __init__(self, intval):
  283. self.intval = intval
  284. def f(i, y):
  285. res = 0
  286. x = I(i)
  287. while y > 0:
  288. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  289. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  290. res += x.intval * x.intval
  291. y -= 1
  292. return res
  293. res = self.meta_interp(f, [6, 7])
  294. assert res == 252
  295. self.check_trace_count(1)
  296. self.check_resops({'jump': 1, 'int_gt': 2, 'int_add': 2,
  297. 'getfield_gc_i': 1, 'int_mul': 1,
  298. 'guard_true': 2, 'int_sub': 2})
  299. def test_loops_are_transient(self):
  300. import gc, weakref
  301. myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
  302. def f(x, y):
  303. res = 0
  304. while y > 0:
  305. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  306. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  307. res += x
  308. if y%2:
  309. res *= 2
  310. y -= 1
  311. return res
  312. wr_loops = []
  313. old_init = history.TreeLoop.__init__.im_func
  314. try:
  315. def track_init(self, name):
  316. old_init(self, name)
  317. wr_loops.append(weakref.ref(self))
  318. history.TreeLoop.__init__ = track_init
  319. res = self.meta_interp(f, [6, 15], no_stats=True)
  320. finally:
  321. history.TreeLoop.__init__ = old_init
  322. assert res == f(6, 15)
  323. gc.collect()
  324. assert not [wr for wr in wr_loops if wr()]
  325. def test_string(self):
  326. def f(n):
  327. bytecode = 'adlfkj' + chr(n)
  328. if n < len(bytecode):
  329. return bytecode[n]
  330. else:
  331. return "?"
  332. res = self.interp_operations(f, [1])
  333. assert res == ord("d") # XXX should be "d"
  334. res = self.interp_operations(f, [6])
  335. assert res == 6
  336. res = self.interp_operations(f, [42])
  337. assert res == ord("?")
  338. def test_chr2str(self):
  339. def f(n):
  340. s = chr(n)
  341. return s[0]
  342. res = self.interp_operations(f, [3])
  343. assert res == 3
  344. def test_unicode(self):
  345. def f(n):
  346. bytecode = u'adlfkj' + unichr(n)
  347. if n < len(bytecode):
  348. return bytecode[n]
  349. else:
  350. return u"?"
  351. res = self.interp_operations(f, [1])
  352. assert res == ord(u"d") # XXX should be "d"
  353. res = self.interp_operations(f, [6])
  354. assert res == 6
  355. res = self.interp_operations(f, [42])
  356. assert res == ord(u"?")
  357. def test_char_in_constant_string(self):
  358. def g(string):
  359. return '\x00' in string
  360. def f():
  361. if g('abcdef'): return -60
  362. if not g('abc\x00ef'): return -61
  363. return 42
  364. res = self.interp_operations(f, [])
  365. assert res == 42
  366. self.check_operations_history({'finish': 1}) # nothing else
  367. def test_residual_call(self):
  368. @dont_look_inside
  369. def externfn(x, y):
  370. return x * y
  371. def f(n):
  372. return externfn(n, n+1)
  373. res = self.interp_operations(f, [6])
  374. assert res == 42
  375. self.check_operations_history(int_add=1, int_mul=0, call_i=1, guard_no_exception=0)
  376. def test_residual_call_elidable(self):
  377. def externfn(x, y):
  378. return x * y
  379. externfn._elidable_function_ = True
  380. def f(n):
  381. promote(n)
  382. return externfn(n, n+1)
  383. res = self.interp_operations(f, [6])
  384. assert res == 42
  385. # CALL_PURE is not recorded in the history if all-constant args
  386. self.check_operations_history(int_add=0, int_mul=0,
  387. call_i=0, call_pure_i=0)
  388. def test_residual_call_elidable_1(self):
  389. @elidable
  390. def externfn(x, y):
  391. return x * y
  392. def f(n):
  393. return externfn(n, n+1)
  394. res = self.interp_operations(f, [6])
  395. assert res == 42
  396. # CALL_PURE is recorded in the history if not-all-constant args
  397. self.check_operations_history(int_add=1, int_mul=0,
  398. call_i=0, call_pure_i=1)
  399. def test_residual_call_elidable_2(self):
  400. myjitdriver = JitDriver(greens = [], reds = ['n'])
  401. @elidable
  402. def externfn(x):
  403. return x - 1
  404. def f(n):
  405. while n > 0:
  406. myjitdriver.can_enter_jit(n=n)
  407. myjitdriver.jit_merge_point(n=n)
  408. n = externfn(n)
  409. return n
  410. res = self.meta_interp(f, [7])
  411. assert res == 0
  412. # CALL_PURE is recorded in the history, but turned into a CALL
  413. # by optimizeopt.py
  414. self.check_resops(call_pure_i=0, call_i=2, int_sub=0)
  415. def test_constfold_call_elidable(self):
  416. myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
  417. @elidable
  418. def externfn(x):
  419. return x - 3
  420. def f(n, m):
  421. while n > 0:
  422. myjitdriver.can_enter_jit(n=n, m=m)
  423. myjitdriver.jit_merge_point(n=n, m=m)
  424. n -= externfn(m)
  425. return n
  426. res = self.meta_interp(f, [21, 5])
  427. assert res == -1
  428. # the CALL_PURE is constant-folded away by optimizeopt.py
  429. self.check_resops(call_pure_i=0, call_i=0, int_sub=2)
  430. def test_constfold_call_elidable_2(self):
  431. myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
  432. @elidable
  433. def externfn(x):
  434. return x - 3
  435. class V:
  436. def __init__(self, value):
  437. self.value = value
  438. def f(n, m):
  439. while n > 0:
  440. myjitdriver.can_enter_jit(n=n, m=m)
  441. myjitdriver.jit_merge_point(n=n, m=m)
  442. v = V(m)
  443. n -= externfn(v.value)
  444. return n
  445. res = self.meta_interp(f, [21, 5])
  446. assert res == -1
  447. # the CALL_PURE is constant-folded away by optimizeopt.py
  448. self.check_resops(call_pure_i=0, call_i=0, int_sub=2)
  449. def test_elidable_function_returning_object(self):
  450. myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
  451. class V:
  452. def __init__(self, x):
  453. self.x = x
  454. v1 = V(1)
  455. v2 = V(2)
  456. @elidable
  457. def externfn(x):
  458. if x:
  459. return v1
  460. else:
  461. return v2
  462. def f(n, m):
  463. while n > 0:
  464. myjitdriver.can_enter_jit(n=n, m=m)
  465. myjitdriver.jit_merge_point(n=n, m=m)
  466. m = V(m).x
  467. n -= externfn(m).x + externfn(m + m - m).x
  468. return n
  469. res = self.meta_interp(f, [21, 5])
  470. assert res == -1
  471. # the CALL_PURE is constant-folded away by optimizeopt.py
  472. self.check_resops(call_pure_r=0, call_r=0, getfield_gc_i=1, int_sub=2,
  473. call_pure_i=0, call_i=0)
  474. def test_elidable_raising(self):
  475. myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
  476. @elidable
  477. def externfn(x):
  478. if x <= 0:
  479. raise ValueError
  480. return x - 1
  481. def f(n, m):
  482. while n > 0:
  483. myjitdriver.can_enter_jit(n=n, m=m)
  484. myjitdriver.jit_merge_point(n=n, m=m)
  485. try:
  486. n -= externfn(m)
  487. except ValueError:
  488. n -= 1
  489. return n
  490. res = self.meta_interp(f, [22, 6])
  491. assert res == -3
  492. # the CALL_PURE is constant-folded away during tracing
  493. self.check_resops(call_pure_i=0, call_i=0, int_sub=2)
  494. #
  495. res = self.meta_interp(f, [22, -5])
  496. assert res == 0
  497. # raises: becomes CALL and is not constant-folded away
  498. self.check_resops(call_pure_i=0, call_i=2, int_sub=2)
  499. def test_elidable_raising_2(self):
  500. myjitdriver = JitDriver(greens = ['m'], reds = ['n'])
  501. @elidable
  502. def externfn(x):
  503. if x <= 0:
  504. raise ValueError
  505. return x - 1
  506. def f(n, m):
  507. while n > 0:
  508. myjitdriver.can_enter_jit(n=n, m=m)
  509. myjitdriver.jit_merge_point(n=n, m=m)
  510. try:
  511. n -= externfn(noConst(m))
  512. except ValueError:
  513. n -= 1
  514. return n
  515. res = self.meta_interp(f, [22, 6])
  516. assert res == -3
  517. # the CALL_PURE is constant-folded away by optimizeopt.py
  518. self.check_resops(call_pure_i=0, call_i=0, int_sub=2)
  519. #
  520. res = self.meta_interp(f, [22, -5])
  521. assert res == 0
  522. # raises: becomes CALL and is not constant-folded away
  523. self.check_resops(call_pure_i=0, call_i=2, int_sub=2)
  524. def test_constant_across_mp(self):
  525. myjitdriver = JitDriver(greens = [], reds = ['n'])
  526. class X(object):
  527. pass
  528. def f(n):
  529. while n > -100:
  530. myjitdriver.can_enter_jit(n=n)
  531. myjitdriver.jit_merge_point(n=n)
  532. x = X()
  533. x.arg = 5
  534. if n <= 0: break
  535. n -= x.arg
  536. x.arg = 6 # prevents 'x.arg' from being annotated as constant
  537. return n
  538. res = self.meta_interp(f, [31])
  539. assert res == -4
  540. def test_stopatxpolicy(self):
  541. myjitdriver = JitDriver(greens = [], reds = ['y'])
  542. def internfn(y):
  543. return y * 3
  544. def externfn(y):
  545. return y ^ 4
  546. def f(y):
  547. while y >= 0:
  548. myjitdriver.can_enter_jit(y=y)
  549. myjitdriver.jit_merge_point(y=y)
  550. if y & 7:
  551. f = internfn
  552. else:
  553. f = externfn
  554. f(y)
  555. y -= 1
  556. return 42
  557. policy = StopAtXPolicy(externfn)
  558. res = self.meta_interp(f, [31], policy=policy)
  559. assert res == 42
  560. self.check_resops(int_mul=2, int_xor=0)
  561. def test_we_are_jitted(self):
  562. myjitdriver = JitDriver(greens = [], reds = ['y'])
  563. def f(y):
  564. while y >= 0:
  565. myjitdriver.can_enter_jit(y=y)
  566. myjitdriver.jit_merge_point(y=y)
  567. if we_are_jitted():
  568. x = 1
  569. else:
  570. x = 10
  571. y -= x
  572. return y
  573. assert f(55) == -5
  574. res = self.meta_interp(f, [55])
  575. assert res == -1
  576. def test_confirm_enter_jit(self):
  577. def confirm_enter_jit(x, y):
  578. return x <= 5
  579. myjitdriver = JitDriver(greens = ['x'], reds = ['y'],
  580. confirm_enter_jit = confirm_enter_jit)
  581. def f(x, y):
  582. while y >= 0:
  583. myjitdriver.can_enter_jit(x=x, y=y)
  584. myjitdriver.jit_merge_point(x=x, y=y)
  585. y -= x
  586. return y
  587. #
  588. res = self.meta_interp(f, [10, 84])
  589. assert res == -6
  590. self.check_trace_count(0)
  591. #
  592. res = self.meta_interp(f, [3, 19])
  593. assert res == -2
  594. self.check_trace_count(1)
  595. def test_can_never_inline(self):
  596. def can_never_inline(x):
  597. return x > 50
  598. myjitdriver = JitDriver(greens = ['x'], reds = ['y'],
  599. can_never_inline = can_never_inline)
  600. @dont_look_inside
  601. def marker():
  602. pass
  603. def f(x, y):
  604. while y >= 0:
  605. myjitdriver.can_enter_jit(x=x, y=y)
  606. myjitdriver.jit_merge_point(x=x, y=y)
  607. x += 1
  608. if x == 4 or x == 61:
  609. marker()
  610. y -= x
  611. return y
  612. #
  613. res = self.meta_interp(f, [3, 6], repeat=7, function_threshold=0)
  614. assert res == 6 - 4 - 5
  615. self.check_history(call_n=0) # because the trace starts in the middle
  616. #
  617. res = self.meta_interp(f, [60, 84], repeat=7)
  618. assert res == 84 - 61 - 62
  619. self.check_history(call_n=1) # because the trace starts immediately
  620. def test_unroll_one_loop_iteration(self):
  621. def unroll(code):
  622. return code == 0
  623. myjitdriver = JitDriver(greens = ['code'],
  624. reds = ['loops', 'inner_loops', 's'],
  625. should_unroll_one_iteration=unroll)
  626. def f(code, loops, inner_loops):
  627. s = 0
  628. while loops > 0:
  629. myjitdriver.jit_merge_point(code=code, loops=loops,
  630. inner_loops=inner_loops, s=s)
  631. if code == 1:
  632. s += f(0, inner_loops, 0)
  633. loops -= 1
  634. s += 1
  635. return s
  636. res = self.meta_interp(f, [1, 4, 1], enable_opts="", inline=True)
  637. assert res == f(1, 4, 1)
  638. self.check_history(call_assembler_i=0)
  639. res = self.meta_interp(f, [1, 4, 2], enable_opts="", inline=True)
  640. assert res == f(1, 4, 2)
  641. self.check_history(call_assembler_i=1)
  642. def test_format(self):
  643. def f(n):
  644. return len("<%d>" % n)
  645. res = self.interp_operations(f, [421])
  646. assert res == 5
  647. def test_switch(self):
  648. def f(n):
  649. if n == -5: return 12
  650. elif n == 2: return 51
  651. elif n == 7: return 1212
  652. else: return 42
  653. res = self.interp_operations(f, [7])
  654. assert res == 1212
  655. res = self.interp_operations(f, [12311])
  656. assert res == 42
  657. def test_switch_bridges(self):
  658. from rpython.rlib.rarithmetic import intmask
  659. myjitdriver = JitDriver(greens = [], reds = 'auto')
  660. lsts = [[-5, 2, 20] * 6,
  661. [7, 123, 2] * 6,
  662. [12311, -5, 7] * 6,
  663. [7, 123, 2] * 4 + [-5, -5, -5] * 2,
  664. [7, 123, 2] * 4 + [-5, -5, -5] * 2 + [12311, 12311, 12311],
  665. ]
  666. def f(case):
  667. x = 0
  668. i = 0
  669. lst = lsts[case]
  670. while i < len(lst):
  671. myjitdriver.jit_merge_point()
  672. n = lst[i]
  673. if n == -5: a = 5
  674. elif n == 2: a = 4
  675. elif n == 7: a = 3
  676. else: a = 2
  677. x = intmask(x * 10 + a)
  678. #print "XXXXXXXXXXXXXXXX", x
  679. i += 1
  680. return x
  681. res = self.meta_interp(f, [0], backendopt=True)
  682. assert res == intmask(542 * 1001001001001001)
  683. res = self.meta_interp(f, [1], backendopt=True)
  684. assert res == intmask(324 * 1001001001001001)
  685. res = self.meta_interp(f, [2], backendopt=True)
  686. assert res == intmask(253 * 1001001001001001)
  687. res = self.meta_interp(f, [3], backendopt=True)
  688. assert res == intmask(324324324324555555)
  689. res = self.meta_interp(f, [4], backendopt=True)
  690. assert res == intmask(324324324324555555222)
  691. def test_r_uint(self):
  692. from rpython.rlib.rarithmetic import r_uint
  693. myjitdriver = JitDriver(greens = [], reds = ['y'])
  694. def f(y):
  695. y = r_uint(y)
  696. while y > 0:
  697. myjitdriver.can_enter_jit(y=y)
  698. myjitdriver.jit_merge_point(y=y)
  699. y -= 1
  700. return y
  701. res = self.meta_interp(f, [10])
  702. assert res == 0
  703. def test_uint_operations(self):
  704. from rpython.rlib.rarithmetic import r_uint
  705. def f(n):
  706. return ((r_uint(n) - 123) >> 1) <= r_uint(456)
  707. res = self.interp_operations(f, [50])
  708. assert res == False
  709. self.check_operations_history(int_rshift=0, uint_rshift=1,
  710. int_le=0, uint_le=1,
  711. int_sub=1)
  712. def test_uint_condition(self):
  713. from rpython.rlib.rarithmetic import r_uint
  714. def f(n):
  715. if ((r_uint(n) - 123) >> 1) <= r_uint(456):
  716. return 24
  717. else:
  718. return 12
  719. res = self.interp_operations(f, [50])
  720. assert res == 12
  721. self.check_operations_history(int_rshift=0, uint_rshift=1,
  722. int_le=0, uint_le=1,
  723. int_sub=1)
  724. def test_int_between(self):
  725. #
  726. def check(arg1, arg2, arg3, expect_result, **expect_operations):
  727. from rpython.rtyper.lltypesystem import lltype
  728. from rpython.rtyper.lltypesystem.lloperation import llop
  729. loc = locals().copy()
  730. exec py.code.Source("""
  731. def f(n, m, p):
  732. arg1 = %(arg1)s
  733. arg2 = %(arg2)s
  734. arg3 = %(arg3)s
  735. return llop.int_between(lltype.Bool, arg1, arg2, arg3)
  736. """ % locals()).compile() in loc
  737. res = self.interp_operations(loc['f'], [5, 6, 7])
  738. assert res == expect_result
  739. self.check_operations_history(expect_operations)
  740. #
  741. check('n', 'm', 'p', True, int_sub=2, uint_lt=1)
  742. check('n', 'p', 'm', False, int_sub=2, uint_lt=1)
  743. #
  744. check('n', 'm', 6, False, int_sub=2, uint_lt=1)
  745. #
  746. check('n', 4, 'p', False, int_sub=2, uint_lt=1)
  747. check('n', 5, 'p', True, int_sub=2, uint_lt=1)
  748. check('n', 8, 'p', False, int_sub=2, uint_lt=1)
  749. #
  750. check('n', 6, 7, True, int_sub=2, uint_lt=1)
  751. #
  752. check(-2, 'n', 'p', True, int_sub=2, uint_lt=1)
  753. check(-2, 'm', 'p', True, int_sub=2, uint_lt=1)
  754. check(-2, 'p', 'm', False, int_sub=2, uint_lt=1)
  755. #check(0, 'n', 'p', True, uint_lt=1) xxx implement me
  756. #check(0, 'm', 'p', True, uint_lt=1)
  757. #check(0, 'p', 'm', False, uint_lt=1)
  758. #
  759. check(2, 'n', 6, True, int_sub=1, uint_lt=1)
  760. check(2, 'm', 6, False, int_sub=1, uint_lt=1)
  761. check(2, 'p', 6, False, int_sub=1, uint_lt=1)
  762. check(5, 'n', 6, True, int_eq=1) # 6 == 5+1
  763. check(5, 'm', 6, False, int_eq=1) # 6 == 5+1
  764. #
  765. check(2, 6, 'm', False, int_sub=1, uint_lt=1)
  766. check(2, 6, 'p', True, int_sub=1, uint_lt=1)
  767. #
  768. check(2, 40, 6, False)
  769. check(2, 40, 60, True)
  770. def test_getfield(self):
  771. class A:
  772. pass
  773. a1 = A()
  774. a1.foo = 5
  775. a2 = A()
  776. a2.foo = 8
  777. def f(x):
  778. if x > 5:
  779. a = a1
  780. else:
  781. a = a2
  782. return a.foo * x
  783. res = self.interp_operations(f, [42])
  784. assert res == 210
  785. self.check_operations_history(getfield_gc_i=1)
  786. def test_getfield_immutable(self):
  787. class A:
  788. _immutable_ = True
  789. a1 = A()
  790. a1.foo = 5
  791. a2 = A()
  792. a2.foo = 8
  793. def f(x):
  794. if x > 5:
  795. a = a1
  796. else:
  797. a = a2
  798. return a.foo * x
  799. res = self.interp_operations(f, [42])
  800. assert res == 210
  801. self.check_operations_history(getfield_gc_i=0)
  802. def test_setfield_bool(self):
  803. class A:
  804. def __init__(self):
  805. self.flag = True
  806. myjitdriver = JitDriver(greens = [], reds = ['n', 'obj'])
  807. def f(n):
  808. obj = A()
  809. res = False
  810. while n > 0:
  811. myjitdriver.can_enter_jit(n=n, obj=obj)
  812. myjitdriver.jit_merge_point(n=n, obj=obj)
  813. obj.flag = False
  814. n -= 1
  815. return res
  816. res = self.meta_interp(f, [7])
  817. assert type(res) == bool
  818. assert not res
  819. def test_int_add_ovf(self):
  820. def f(x, y):
  821. try:
  822. return ovfcheck(x + y)
  823. except OverflowError:
  824. return -42
  825. res = self.interp_operations(f, [-100, 2])
  826. assert res == -98
  827. res = self.interp_operations(f, [1, sys.maxint])
  828. assert res == -42
  829. def test_ovf_raise(self):
  830. def g(x, y):
  831. try:
  832. return ovfcheck(x * y)
  833. except OverflowError:
  834. raise
  835. def f(x, y):
  836. try:
  837. return g(x, y)
  838. except OverflowError:
  839. return 3
  840. res = self.interp_operations(f, [sys.maxint, 2])
  841. assert res == 3
  842. res = self.interp_operations(f, [3, 2])
  843. assert res == 6
  844. def test_int_sub_ovf(self):
  845. def f(x, y):
  846. try:
  847. return ovfcheck(x - y)
  848. except OverflowError:
  849. return -42
  850. res = self.interp_operations(f, [-100, 2])
  851. assert res == -102
  852. res = self.interp_operations(f, [1, -sys.maxint])
  853. assert res == -42
  854. def test_int_mul_ovf(self):
  855. def f(x, y):
  856. try:
  857. return ovfcheck(x * y)
  858. except OverflowError:
  859. return -42
  860. res = self.interp_operations(f, [-100, 2])
  861. assert res == -200
  862. res = self.interp_operations(f, [-3, sys.maxint//2])
  863. assert res == -42
  864. def test_mod_ovf(self):
  865. myjitdriver = JitDriver(greens = [], reds = ['n', 'x', 'y'])
  866. def f(n, x, y):
  867. while n > 0:
  868. myjitdriver.can_enter_jit(x=x, y=y, n=n)
  869. myjitdriver.jit_merge_point(x=x, y=y, n=n)
  870. n -= ovfcheck(x % y)
  871. x += 1
  872. return n
  873. res = self.meta_interp(f, [20, 1, 2])
  874. assert res == 0
  875. self.check_resops(call_i=2, int_eq=3, int_and=2)
  876. def test_abs(self):
  877. myjitdriver = JitDriver(greens = [], reds = ['i', 't'])
  878. def f(i):
  879. t = 0
  880. while i < 10:
  881. myjitdriver.can_enter_jit(i=i, t=t)
  882. myjitdriver.jit_merge_point(i=i, t=t)
  883. t += abs(i)
  884. i += 1
  885. return t
  886. res = self.meta_interp(f, [-5])
  887. assert res == 5+4+3+2+1+0+1+2+3+4+5+6+7+8+9
  888. def test_int_c_div(self):
  889. from rpython.rlib.rarithmetic import int_c_div
  890. myjitdriver = JitDriver(greens = [], reds = ['i', 't'])
  891. def f(i):
  892. t = 0
  893. while i < 10:
  894. myjitdriver.can_enter_jit(i=i, t=t)
  895. myjitdriver.jit_merge_point(i=i, t=t)
  896. t += int_c_div(-100, i)
  897. i += 1
  898. return t
  899. expected = -sum([100 // n for n in range(1, 10)])
  900. assert f(1) == expected
  901. res = self.meta_interp(f, [1])
  902. assert res == expected
  903. # should contain a call_i(..., OS=OS_INT_PY_DIV)
  904. def test_int_c_mod(self):
  905. from rpython.rlib.rarithmetic import int_c_mod
  906. myjitdriver = JitDriver(greens = [], reds = ['i', 't'])
  907. def f(i):
  908. t = 0
  909. while i < 10:
  910. myjitdriver.can_enter_jit(i=i, t=t)
  911. myjitdriver.jit_merge_point(i=i, t=t)
  912. t += int_c_mod(-100, i)
  913. i += 1
  914. return t
  915. expected = -sum([100 % n for n in range(1, 10)])
  916. assert f(1) == expected
  917. res = self.meta_interp(f, [1])
  918. assert res == expected
  919. # should contain a call_i(..., OS=OS_INT_PY_MOD)
  920. def test_positive_c_div_mod(self):
  921. from rpython.rlib.rarithmetic import int_c_div, int_c_mod
  922. myjitdriver = JitDriver(greens = [], reds = ['i', 't'])
  923. def f(i):
  924. t = 0
  925. while i < 10:
  926. myjitdriver.can_enter_jit(i=i, t=t)
  927. myjitdriver.jit_merge_point(i=i, t=t)
  928. assert i > 0
  929. t += int_c_div(100, i) - int_c_mod(100, i)
  930. i += 1
  931. return t
  932. expected = sum([100 // n - 100 % n for n in range(1, 10)])
  933. assert f(1) == expected
  934. res = self.meta_interp(f, [1])
  935. assert res == expected
  936. # all the correction code should be dead now, xxx test that
  937. def test_int_c_div_by_constant(self):
  938. from rpython.rlib.rarithmetic import int_c_div
  939. myjitdriver = JitDriver(greens = ['k'], reds = ['i', 't'])
  940. def f(i, k):
  941. t = 0
  942. while i < 100:
  943. myjitdriver.can_enter_jit(i=i, t=t, k=k)
  944. myjitdriver.jit_merge_point(i=i, t=t, k=k)
  945. t += int_c_div(i, k)
  946. i += 1
  947. return t
  948. expected = sum([i // 10 for i in range(51, 100)])
  949. assert f(-50, 10) == expected
  950. res = self.meta_interp(f, [-50, 10])
  951. assert res == expected
  952. self.check_resops(call=0, uint_mul_high=2)
  953. def test_float(self):
  954. myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
  955. def f(x, y):
  956. x = float(x)
  957. y = float(y)
  958. res = 0.0
  959. while y > 0.0:
  960. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  961. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  962. res += x
  963. y -= 1.0
  964. return res
  965. res = self.meta_interp(f, [6, 7])
  966. assert res == 42.0
  967. self.check_trace_count(1)
  968. self.check_resops({'jump': 1, 'float_gt': 2, 'float_add': 2,
  969. 'float_sub': 2, 'guard_true': 2})
  970. def test_print(self):
  971. myjitdriver = JitDriver(greens = [], reds = ['n'])
  972. def f(n):
  973. while n > 0:
  974. myjitdriver.can_enter_jit(n=n)
  975. myjitdriver.jit_merge_point(n=n)
  976. print n
  977. n -= 1
  978. return n
  979. res = self.meta_interp(f, [7])
  980. assert res == 0
  981. def test_bridge_from_interpreter_1(self):
  982. mydriver = JitDriver(reds = ['n'], greens = [])
  983. def f(n):
  984. while n > 0:
  985. mydriver.can_enter_jit(n=n)
  986. mydriver.jit_merge_point(n=n)
  987. n -= 1
  988. self.meta_interp(f, [20], repeat=7)
  989. # the loop and the entry path as a single trace
  990. self.check_jitcell_token_count(1)
  991. # we get:
  992. # ENTER - compile the new loop and the entry bridge
  993. # ENTER - compile the leaving path
  994. self.check_enter_count(2)
  995. def test_bridge_from_interpreter_2(self):
  996. # one case for backend - computing of framesize on guard failure
  997. mydriver = JitDriver(reds = ['n'], greens = [])
  998. glob = [1]
  999. def f(n):
  1000. while n > 0:
  1001. mydriver.can_enter_jit(n=n)
  1002. mydriver.jit_merge_point(n=n)
  1003. if n == 17 and glob[0]:
  1004. glob[0] = 0
  1005. x = n + 1
  1006. y = n + 2
  1007. z = n + 3
  1008. k = n + 4
  1009. n -= 1
  1010. n += x + y + z + k
  1011. n -= x + y + z + k
  1012. n -= 1
  1013. self.meta_interp(f, [20], repeat=7)
  1014. def test_bridge_from_interpreter_3(self):
  1015. # one case for backend - computing of framesize on guard failure
  1016. mydriver = JitDriver(reds = ['n', 'x', 'y', 'z', 'k'], greens = [])
  1017. class Global:
  1018. pass
  1019. glob = Global()
  1020. def f(n):
  1021. glob.x = 1
  1022. x = 0
  1023. y = 0
  1024. z = 0
  1025. k = 0
  1026. while n > 0:
  1027. mydriver.can_enter_jit(n=n, x=x, y=y, z=z, k=k)
  1028. mydriver.jit_merge_point(n=n, x=x, y=y, z=z, k=k)
  1029. x += 10
  1030. y += 3
  1031. z -= 15
  1032. k += 4
  1033. if n == 17 and glob.x:
  1034. glob.x = 0
  1035. x += n + 1
  1036. y += n + 2
  1037. z += n + 3
  1038. k += n + 4
  1039. n -= 1
  1040. n -= 1
  1041. return x + 2*y + 3*z + 5*k + 13*n
  1042. res = self.meta_interp(f, [20], repeat=7)
  1043. assert res == f(20)
  1044. def test_bridge_from_interpreter_4(self):
  1045. jitdriver = JitDriver(reds = ['n', 'k'], greens = [])
  1046. def f(n, k):
  1047. while n > 0:
  1048. jitdriver.can_enter_jit(n=n, k=k)
  1049. jitdriver.jit_merge_point(n=n, k=k)
  1050. if k:
  1051. n -= 2
  1052. else:
  1053. n -= 1
  1054. return n + k
  1055. from rpython.rtyper.test.test_llinterp import get_interpreter, clear_tcache
  1056. from rpython.jit.metainterp.warmspot import WarmRunnerDesc
  1057. interp, graph = get_interpreter(f, [0, 0], backendopt=False,
  1058. inline_threshold=0)
  1059. clear_tcache()
  1060. translator = interp.typer.annotator.translator
  1061. translator.config.translation.gc = "boehm"
  1062. warmrunnerdesc = WarmRunnerDesc(translator,
  1063. CPUClass=self.CPUClass)
  1064. state = warmrunnerdesc.jitdrivers_sd[0].warmstate
  1065. state.set_param_threshold(3) # for tests
  1066. state.set_param_trace_eagerness(0) # for tests
  1067. warmrunnerdesc.finish()
  1068. for n, k in [(20, 0), (20, 1)]:
  1069. interp.eval_graph(graph, [n, k])
  1070. def test_bridge_leaving_interpreter_5(self):
  1071. mydriver = JitDriver(reds = ['n', 'x'], greens = [])
  1072. class Global:
  1073. pass
  1074. glob = Global()
  1075. def f(n):
  1076. x = 0
  1077. glob.x = 1
  1078. while n > 0:
  1079. mydriver.can_enter_jit(n=n, x=x)
  1080. mydriver.jit_merge_point(n=n, x=x)
  1081. glob.x += 1
  1082. x += 3
  1083. n -= 1
  1084. glob.x += 100
  1085. return glob.x + x
  1086. res = self.meta_interp(f, [20], repeat=7)
  1087. assert res == f(20)
  1088. def test_instantiate_classes(self):
  1089. class Base: pass
  1090. class A(Base): foo = 72
  1091. class B(Base): foo = 8
  1092. def f(n):
  1093. if n > 5:
  1094. cls = A
  1095. else:
  1096. cls = B
  1097. return cls().foo
  1098. res = self.interp_operations(f, [3])
  1099. assert res == 8
  1100. res = self.interp_operations(f, [13])
  1101. assert res == 72
  1102. def test_instantiate_does_not_call(self):
  1103. mydriver = JitDriver(reds = ['n', 'x'], greens = [])
  1104. class Base: pass
  1105. class A(Base): foo = 72
  1106. class B(Base): foo = 8
  1107. def f(n):
  1108. x = 0
  1109. while n > 0:
  1110. mydriver.can_enter_jit(n=n, x=x)
  1111. mydriver.jit_merge_point(n=n, x=x)
  1112. if n & 1 == 0:
  1113. cls = A
  1114. else:
  1115. cls = B
  1116. inst = cls()
  1117. x += inst.foo
  1118. n -= 1
  1119. return x
  1120. res = self.meta_interp(f, [20], enable_opts='')
  1121. assert res == f(20)
  1122. self.check_resops(call_i=0, call_r=0)
  1123. def test_zerodivisionerror(self):
  1124. # test the case of exception-raising operation that is not delegated
  1125. # to the backend at all: ZeroDivisionError
  1126. #
  1127. def f(n):
  1128. assert n >= 0
  1129. try:
  1130. return ovfcheck(5 % n)
  1131. except ZeroDivisionError:
  1132. return -666
  1133. except OverflowError:
  1134. return -777
  1135. res = self.interp_operations(f, [0])
  1136. assert res == -666
  1137. #
  1138. def f(n):
  1139. assert n >= 0
  1140. try:
  1141. return ovfcheck(6 // n)
  1142. except ZeroDivisionError:
  1143. return -667
  1144. except OverflowError:
  1145. return -778
  1146. res = self.interp_operations(f, [0])
  1147. assert res == -667
  1148. def test_div_overflow(self):
  1149. import sys
  1150. myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
  1151. def f(x, y):
  1152. res = 0
  1153. while y > 0:
  1154. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  1155. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  1156. try:
  1157. res += ovfcheck((-sys.maxint-1) // x)
  1158. x += 5
  1159. except OverflowError:
  1160. res += 100
  1161. y -= 1
  1162. return res
  1163. expected = ((-sys.maxint-1) // (-41) +
  1164. (-sys.maxint-1) // (-36) +
  1165. (-sys.maxint-1) // (-31) +
  1166. (-sys.maxint-1) // (-26) +
  1167. (-sys.maxint-1) // (-21) +
  1168. (-sys.maxint-1) // (-16) +
  1169. (-sys.maxint-1) // (-11) +
  1170. (-sys.maxint-1) // (-6) +
  1171. 100 * 8)
  1172. assert f(-41, 16) == expected
  1173. res = self.meta_interp(f, [-41, 16])
  1174. assert res == expected
  1175. def test_overflow_fold_if_divisor_constant(self):
  1176. import sys
  1177. myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
  1178. def f(x, y):
  1179. res = 0
  1180. while y > 0:
  1181. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  1182. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  1183. try:
  1184. res += ovfcheck(x // 2)
  1185. res += ovfcheck(x % 2)
  1186. x += 5
  1187. except OverflowError:
  1188. res += 100
  1189. y -= 1
  1190. return res
  1191. res = self.meta_interp(f, [-41, 8])
  1192. # the guard_true are for the loop condition
  1193. # the guard_false needed to check whether an overflow can occur have
  1194. # been folded away
  1195. self.check_resops(guard_true=2, guard_false=0)
  1196. def test_isinstance(self):
  1197. class A:
  1198. pass
  1199. class B(A):
  1200. pass
  1201. @dont_look_inside
  1202. def extern(n):
  1203. if n:
  1204. return A()
  1205. else:
  1206. return B()
  1207. def fn(n):
  1208. obj = extern(n)
  1209. return isinstance(obj, B)
  1210. res = self.interp_operations(fn, [0])
  1211. assert res
  1212. self.check_operations_history(guard_class=1)
  1213. res = self.interp_operations(fn, [1])
  1214. assert not res
  1215. def test_isinstance_2(self):
  1216. driver = JitDriver(greens = [], reds = ['n', 'sum', 'x'])
  1217. class A:
  1218. pass
  1219. class B(A):
  1220. pass
  1221. class C(B):
  1222. pass
  1223. def main():
  1224. return f(5, B()) * 10 + f(5, C()) + f(5, A()) * 100
  1225. def f(n, x):
  1226. sum = 0
  1227. while n > 0:
  1228. driver.can_enter_jit(x=x, n=n, sum=sum)
  1229. driver.jit_merge_point(x=x, n=n, sum=sum)
  1230. if isinstance(x, B):
  1231. sum += 1
  1232. n -= 1
  1233. return sum
  1234. res = self.meta_interp(main, [])
  1235. assert res == 55
  1236. def test_assert_isinstance(self):
  1237. class A:
  1238. pass
  1239. class B(A):
  1240. pass
  1241. def fn(n):
  1242. # this should only be called with n != 0
  1243. if n:
  1244. obj = B()
  1245. obj.a = n
  1246. else:
  1247. obj = A()
  1248. obj.a = 17
  1249. assert isinstance(obj, B)
  1250. return obj.a
  1251. res = self.interp_operations(fn, [1])
  1252. assert res == 1
  1253. self.check_operations_history(guard_class=0)
  1254. def test_r_dict(self):
  1255. from rpython.rlib.objectmodel import r_dict
  1256. class FooError(Exception):
  1257. pass
  1258. def myeq(n, m):
  1259. return n == m
  1260. def myhash(n):
  1261. if n < 0:
  1262. raise FooError
  1263. return -n
  1264. def f(n):
  1265. d = r_dict(myeq, myhash)
  1266. for i in range(10):
  1267. d[i] = i*i
  1268. try:
  1269. return d[n]
  1270. except FooError:
  1271. return 99
  1272. res = self.interp_operations(f, [5])
  1273. assert res == f(5)
  1274. def test_free_object(self):
  1275. import weakref
  1276. myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
  1277. class X(object):
  1278. pass
  1279. def main(n, x):
  1280. while n > 0:
  1281. myjitdriver.can_enter_jit(n=n, x=x)
  1282. myjitdriver.jit_merge_point(n=n, x=x)
  1283. n -= x.foo
  1284. def g(n):
  1285. x = X()
  1286. x.foo = 2
  1287. main(n, x)
  1288. x.foo = 5
  1289. return weakref.ref(x)
  1290. def f(n):
  1291. r = g(n)
  1292. rgc.collect(); rgc.collect(); rgc.collect()
  1293. return r() is None
  1294. #
  1295. assert f(30) == 1
  1296. res = self.meta_interp(f, [30], no_stats=True)
  1297. assert res == 1
  1298. def test_pass_around(self):
  1299. myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
  1300. def call():
  1301. pass
  1302. def f(n, x):
  1303. while n > 0:
  1304. myjitdriver.can_enter_jit(n=n, x=x)
  1305. myjitdriver.jit_merge_point(n=n, x=x)
  1306. if n % 2:
  1307. call()
  1308. if n == 8:
  1309. return x
  1310. x = 3
  1311. else:
  1312. x = 5
  1313. n -= 1
  1314. return 0
  1315. self.meta_interp(f, [40, 0])
  1316. def test_const_inputargs(self):
  1317. myjitdriver = JitDriver(greens = ['m'], reds = ['n', 'x'])
  1318. def f(n, x):
  1319. m = 0x7FFFFFFF
  1320. while n > 0:
  1321. myjitdriver.can_enter_jit(m=m, n=n, x=x)
  1322. myjitdriver.jit_merge_point(m=m, n=n, x=x)
  1323. x = 42
  1324. n -= 1
  1325. m = m >> 1
  1326. return x
  1327. res = self.meta_interp(f, [50, 1], enable_opts='')
  1328. assert res == 42
  1329. def test_set_param(self):
  1330. myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
  1331. def g(n):
  1332. x = 0
  1333. while n > 0:
  1334. myjitdriver.can_enter_jit(n=n, x=x)
  1335. myjitdriver.jit_merge_point(n=n, x=x)
  1336. n -= 1
  1337. x += n
  1338. return x
  1339. def f(n, threshold, arg):
  1340. if arg:
  1341. set_param(myjitdriver, 'threshold', threshold)
  1342. else:
  1343. set_param(None, 'threshold', threshold)
  1344. return g(n)
  1345. res = self.meta_interp(f, [10, 3, 1])
  1346. assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
  1347. self.check_jitcell_token_count(1)
  1348. res = self.meta_interp(f, [10, 13, 0])
  1349. assert res == 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
  1350. self.check_jitcell_token_count(0)
  1351. def test_dont_look_inside(self):
  1352. @dont_look_inside
  1353. def g(a, b):
  1354. return a + b
  1355. def f(a, b):
  1356. return g(a, b)
  1357. res = self.interp_operations(f, [3, 5])
  1358. assert res == 8
  1359. self.check_operations_history(int_add=0, call_i=1)
  1360. def test_listcomp(self):
  1361. myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'lst'])
  1362. def f(x, y):
  1363. lst = [0, 0, 0]
  1364. while y > 0:
  1365. myjitdriver.can_enter_jit(x=x, y=y, lst=lst)
  1366. myjitdriver.jit_merge_point(x=x, y=y, lst=lst)
  1367. lst = [i+x for i in lst if i >=0]
  1368. y -= 1
  1369. return lst[0]
  1370. res = self.meta_interp(f, [6, 7], listcomp=True, backendopt=True, listops=True)
  1371. # XXX: the loop looks inefficient
  1372. assert res == 42
  1373. def test_tuple_immutable(self):
  1374. def new(a, b):
  1375. return a, b
  1376. def f(a, b):
  1377. tup = new(a, b)
  1378. return tup[1]
  1379. res = self.interp_operations(f, [3, 5])
  1380. assert res == 5
  1381. self.check_operations_history(setfield_gc=2, getfield_gc_i=0)
  1382. def test_oosend_look_inside_only_one(self):
  1383. class A:
  1384. pass
  1385. class B(A):
  1386. def g(self):
  1387. return 123
  1388. class C(A):
  1389. @dont_look_inside
  1390. def g(self):
  1391. return 456
  1392. def f(n):
  1393. if n > 3:
  1394. x = B()
  1395. else:
  1396. x = C()
  1397. return x.g() + x.g()
  1398. res = self.interp_operations(f, [10])
  1399. assert res == 123 * 2
  1400. res = self.interp_operations(f, [-10])
  1401. assert res == 456 * 2
  1402. def test_residual_external_call(self):
  1403. import math
  1404. myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
  1405. # When this test was written ll_math couldn't be inlined, now it can,
  1406. # instead of rewriting this test, just ensure that an external call is
  1407. # still generated by wrapping the function.
  1408. @dont_look_inside
  1409. def modf(x):
  1410. return math.modf(x)
  1411. def f(x, y):
  1412. x = float(x)
  1413. res = 0.0
  1414. while y > 0:
  1415. myjitdriver.can_enter_jit(x=x, y=y, res=res)
  1416. myjitdriver.jit_merge_point(x=x, y=y, res=res)
  1417. # this is an external call that the default policy ignores
  1418. rpart, ipart = modf(x)
  1419. res += ipart
  1420. y -= 1
  1421. return res
  1422. res = self.meta_interp(f, [6, 7])
  1423. assert res == 42
  1424. self.check_trace_count(1)
  1425. self.check_resops(call_r=2)
  1426. def test_merge_guardclass_guardvalue(self):
  1427. myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
  1428. class A(object):
  1429. def g(self, x):
  1430. return x - 5
  1431. class B(A):
  1432. def g(self, y):
  1433. return y - 3
  1434. a1 = A()
  1435. a2 = A()
  1436. b = B()
  1437. def f(x):
  1438. l = [a1] * 100 + [a2] * 100 + [b] * 100
  1439. while x > 0:
  1440. myjitdriver.can_enter_jit(x=x, l=l)
  1441. myjitdriver.jit_merge_point(x=x, l=l)
  1442. a = l[x]
  1443. x = a.g(x)
  1444. promote(a)
  1445. return x
  1446. res = self.meta_interp(f, [299], listops=True)
  1447. assert res == f(299)
  1448. self.check_resops(guard_class=0, guard_value=6)
  1449. def test_merge_guardnonnull_guardclass(self):
  1450. myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
  1451. class A(object):
  1452. def g(self, x):
  1453. return x - 3
  1454. class B(A):
  1455. def g(self, y):
  1456. return y - 5
  1457. a1 = A()
  1458. b1 = B()
  1459. def f(x):
  1460. l = [None] * 100 + [b1] * 100 + [a1] * 100
  1461. while x > 0:
  1462. myjitdriver.can_enter_jit(x=x, l=l)
  1463. myjitdriver.jit_merge_point(x=x, l=l)
  1464. a = l[x]
  1465. if a:
  1466. x = a.g(x)
  1467. else:
  1468. x -= 7
  1469. return x
  1470. res = self.meta_interp(f, [299], listops=True)
  1471. assert res == f(299)
  1472. self.check_resops(guard_class=0, guard_nonnull=4,
  1473. guard_nonnull_class=4, guard_isnull=2)
  1474. def test_merge_guardnonnull_guardvalue(self):
  1475. myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
  1476. class A(object):
  1477. pass
  1478. class B(A):
  1479. pass
  1480. a1 = A()
  1481. b1 = B()
  1482. def f(x):
  1483. l = [b1] * 100 + [None] * 100 + [a1] * 100
  1484. while x > 0:
  1485. myjitdriver.can_enter_jit(x=x, l=l)
  1486. myjitdriver.jit_merge_point(x=x, l=l)
  1487. a = l[x]
  1488. if a:
  1489. x -= 5
  1490. else:
  1491. x -= 7
  1492. promote(a)
  1493. return x
  1494. res = self.meta_interp(f, [299], listops=True)
  1495. assert res == f(299)
  1496. self.check_resops(guard_value=4, guard_class=0, guard_nonnull=4,
  1497. guard_nonnull_class=0, guard_isnull=2)
  1498. def test_merge_guardnonnull_guardvalue_2(self):
  1499. myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
  1500. class A(object):
  1501. pass
  1502. class B(A):
  1503. pass
  1504. a1 = A()
  1505. b1 = B()
  1506. def f(x):
  1507. l = [None] * 100 + [b1] * 100 + [a1] * 100
  1508. while x > 0:
  1509. myjitdriver.can_enter_jit(x=x, l=l)
  1510. myjitdriver.jit_merge_point(x=x, l=l)
  1511. a = l[x]
  1512. if a:
  1513. x -= 5
  1514. else:
  1515. x -= 7
  1516. promote(a)
  1517. return x
  1518. res = self.meta_interp(f, [299], listops=True)
  1519. assert res == f(299)
  1520. self.check_resops(guard_value=4, guard_class=0, guard_nonnull=4,
  1521. guard_nonnull_class=0, guard_isnull=2)
  1522. def test_merge_guardnonnull_guardclass_guardvalue(self):
  1523. myjitdriver = JitDriver(greens = [], reds = ['x', 'l'])
  1524. class A(object):
  1525. def g(self, x):
  1526. return x - 3
  1527. class B(A):
  1528. def g(self, y):
  1529. return y - 5
  1530. a1 = A()
  1531. a2 = A()
  1532. b1 = B()
  1533. def f(x):
  1534. l = [a2] * 100 + [None] * 100 + [b1] * 100 + [a1] * 100
  1535. while x > 0:
  1536. myjitdriver.can_enter_jit(x=x, l=l)
  1537. myjitdriver.jit_merge_point(x=x, l=l)
  1538. a = l[x]
  1539. if a:
  1540. x = a.g(x)
  1541. else:
  1542. x -= 7
  1543. promote(a)
  1544. return x
  1545. res = self.meta_interp(f, [399], listops=True)
  1546. assert res == f(399)
  1547. self.check_resops(guard_class=0, guard_nonnull=6, guard_value=6,
  1548. guard_nonnull_class=0, guard_isnull=2)
  1549. def test_residual_call_doesnt_lose_info(self):
  1550. myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'l'])
  1551. class A(object):
  1552. pass
  1553. globall = [""]
  1554. @dont_look_inside
  1555. def g(x):
  1556. globall[0] = str(x)
  1557. return x
  1558. def f(x):
  1559. y = A()
  1560. y.v = x
  1561. l = [0]
  1562. while y.v > 0:
  1563. myjitdriver.can_enter_jit(x=x, y=y, l=l)
  1564. myjitdriver.jit_merge_point(x=x, y=y, l=l)
  1565. l[0] = y.v
  1566. lc = l[0]
  1567. y.v = g(y.v) - y.v/y.v + lc/l[0] - 1
  1568. return y.v
  1569. res = self.meta_interp(f, [20], listops=True)
  1570. self.check_resops(getarrayitem_gc_i=0, getfield_gc_i=1)
  1571. def test_guard_isnull_nonnull(self):
  1572. myjitdriver = JitDriver(greens = [], reds = ['x', 'res'])
  1573. class A(object):
  1574. pass
  1575. @dont_look_inside
  1576. def create(x):
  1577. if x >= -40:
  1578. return A()
  1579. return None
  1580. def f(x):
  1581. res = 0
  1582. while x > 0:
  1583. myjitdriver.can_enter_jit(x=x, res=res)
  1584. myjitdriver.jit_merge_point(x=x, res=res)
  1585. obj = create(x-1)
  1586. if obj is not None:
  1587. res += 1
  1588. obj2 = create(x-1000)
  1589. if obj2 is None:
  1590. res += 1
  1591. x -= 1
  1592. return res
  1593. res = self.meta_interp(f, [21])
  1594. assert res == 42
  1595. self.check_resops(guard_nonnull=2, guard_isnull=2)
  1596. def test_loop_invariant1(self):
  1597. myjitdriver = JitDriver(greens = [], reds = ['x', 'res'])
  1598. class A(object):
  1599. pass
  1600. a = A()
  1601. a.current_a = A()
  1602. a.current_a.x = 1
  1603. @loop_invariant
  1604. def f():
  1605. return a.current_a
  1606. def g(x):
  1607. res = 0
  1608. while x > 0:
  1609. myjitdriver.can_enter_jit(x=x, res=res)
  1610. myjitdriver.jit_merge_point(x=x, res=res)
  1611. res += f().x
  1612. res += f().x
  1613. res += f().x
  1614. x -= 1
  1615. a.current_a = A()
  1616. a.current_a.x = 2
  1617. return res
  1618. res = self.meta_interp(g, [21])
  1619. assert res == 3 * 21
  1620. self.check_resops(call_r=1)
  1621. def test_bug_optimizeopt_mutates_ops(self):
  1622. myjitdriver = JitDriver(greens = [], reds = ['x', 'res', 'const', 'a'])
  1623. class A(object):
  1624. pass
  1625. class B(A):
  1626. pass
  1627. glob = A()
  1628. glob.a = None
  1629. def f(x):
  1630. res = 0
  1631. a = A()
  1632. a.x = 0
  1633. glob.a = A()
  1634. const = 2
  1635. while x > 0:
  1636. myjitdriver.can_enter_jit(x=x, res=res, a=a, const=const)
  1637. myjitdriver.jit_merge_point(x=x, res=res, a=a, const=const)
  1638. if type(glob.a) is B:
  1639. res += 1
  1640. if a is None:
  1641. a = A()
  1642. a.x = x
  1643. glob.a = B()
  1644. const = 2
  1645. else:
  1646. promote(const)
  1647. x -= const
  1648. res += a.x
  1649. a = None
  1650. glob.a = A()
  1651. const = 1
  1652. return res
  1653. res = self.meta_interp(f, [21])
  1654. assert res == f(21)
  1655. def test_getitem_indexerror(self):
  1656. lst = [10, 4, 9, 16]
  1657. def f(n):
  1658. try:
  1659. return lst[n]
  1660. except IndexError:
  1661. return -2
  1662. res = self.interp_operations(f, [2])
  1663. assert res == 9
  1664. res = self.interp_operations(f, [4])
  1665. assert res == -2
  1666. res = self.interp_operations(f, [-4])
  1667. assert res == 10
  1668. res = self.interp_operations(f, [-5])
  1669. assert res == -2
  1670. def test_guard_always_changing_value(self):
  1671. myjitdriver = JitDriver(greens = [], reds = ['x', 'a'])
  1672. def f(x):
  1673. a = 0
  1674. while x > 0:
  1675. myjitdriver.can_enter_jit(x=x, a=a)
  1676. myjitdriver.jit_merge_point(x=x, a=a)
  1677. a += 1
  1678. promote(a)
  1679. x -= 1
  1680. self.meta_interp(f, [50])
  1681. self.check_trace_count(1)
  1682. # this checks that the logic triggered by make_a_counter_per_value()
  1683. # works and prevents generating tons of bridges
  1684. def test_swap_values(self):
  1685. def f(x, y):
  1686. if x > 5:
  1687. x, y = y, x
  1688. return x - y
  1689. res = self.interp_operations(f, [10, 2])
  1690. assert res == -8
  1691. res = self.interp_operations(f, [3, 2])
  1692. assert res == 1
  1693. def test_raw_malloc_and_access(self):
  1694. TP = rffi.CArray(lltype.Signed)
  1695. def f(n):
  1696. a = lltype.malloc(TP, n, flavor='raw')
  1697. a[0] = n
  1698. res = a[0]
  1699. lltype.free(a, flavor='raw')
  1700. return res
  1701. res = self.interp_operations(f, [10])
  1702. assert res == 10
  1703. def test_raw_malloc_and_access_float(self):
  1704. TP = rffi.CArray(lltype.Float)
  1705. def f(n, f):
  1706. a = lltype.malloc(TP, n, flavor='raw')
  1707. a[0] = f
  1708. res = a[0]
  1709. lltype.free(a, flavor='raw')
  1710. return res
  1711. res = self.interp_operations(f, [10, 3.5])
  1712. assert res == 3.5
  1713. def test_jit_debug(self):
  1714. myjitdriver = JitDriver(greens = [], reds = ['x'])
  1715. class A:
  1716. pass
  1717. def f(x):
  1718. while x > 0:
  1719. myjitdriver.can_enter_jit(x=x)
  1720. myjitdriver.jit_merge_point(x=x)
  1721. jit_debug("hi there:", x)
  1722. jit_debug("foobar")
  1723. x -= 1
  1724. return x
  1725. res = self.meta_interp(f, [8])
  1726. assert res == 0
  1727. self.check_resops(jit_debug=4)
  1728. def test_assert_green(self):
  1729. def f(x, promote_flag):
  1730. if promote_flag:
  1731. promote(x)
  1732. assert_green(x)
  1733. return x
  1734. res = self.interp_operations(f, [8, 1])
  1735. assert res == 8
  1736. py.test.raises(AssertGreenFailed, self.interp_operations, f, [8, 0])
  1737. def test_multiple_specialied_versions1(self):
  1738. myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
  1739. class Base:
  1740. def __init__(self, val):
  1741. self.val = val
  1742. class A(Base):
  1743. def binop(self, other):
  1744. return A(self.val + other.val)
  1745. class B(Base):
  1746. def binop(self, other):
  1747. return B(self.val * other.val)
  1748. def f(x, y):
  1749. res = x
  1750. while y > 0:
  1751. myjitdriver.can_enter_jit(y=y, x=x, res=res)
  1752. myjitdriver.jit_merge_point(y=y, x=x, res=res)
  1753. res = res.binop(x)
  1754. y -= 1
  1755. return res
  1756. def g(x, y):
  1757. a1 = f(A(x), y)
  1758. a2 = f(A(x), y)
  1759. b1 = f(B(x), y)
  1760. b2 = f(B(x), y)
  1761. assert a1.val == a2.val
  1762. assert b1.val == b2.val
  1763. return a1.val + b1.val
  1764. res = self.meta_interp(g, [6, 7])
  1765. assert res == 6*8 + 6**8
  1766. self.check_trace_count(4)
  1767. self.check_resops({'guard_class': 2, 'int_gt': 4,
  1768. 'getfield_gc_i': 4, 'guard_true': 4,
  1769. 'int_sub': 4, 'jump': 2, 'int_mul': 2,
  1770. 'int_add': 2})
  1771. def test_multiple_specialied_versions_array(self):
  1772. myjitdriver = JitDriver(greens = [], reds = ['idx', 'y', 'x', 'res',
  1773. 'array'])
  1774. class Base:
  1775. def __init__(self, val):
  1776. self.val = val
  1777. class A(Base):
  1778. def binop(self, other):
  1779. return A(self.val + other.val)
  1780. class B(Base):
  1781. def binop(self, other):
  1782. return B(self.val - other.val)
  1783. def f(x, y):
  1784. res = x
  1785. array = [1, 2, 3]
  1786. array[1] = 7
  1787. idx = 0
  1788. while y > 0:
  1789. myjitdriver.can_enter_jit(idx=idx, y=y, x=x, res=res,
  1790. array=array)
  1791. myjitdriver.jit_merge_point(idx=idx, y=y, x=x, res=res,
  1792. array=array)
  1793. res = res.binop(x)
  1794. res.val += array[idx] + array[1]
  1795. if y < 10:
  1796. idx = 2
  1797. y -= 1
  1798. return res
  1799. def g(x, y):
  1800. a1 = f(A(x), y)
  1801. a2 = f(A(x), y)
  1802. b1 = f(B(x), y)
  1803. b2 = f(B(x), y)
  1804. assert a1.val == a2.val
  1805. assert b1.val == b2.val
  1806. return a1.val + b1.val
  1807. res = self.meta_interp(g, [6, 20])
  1808. assert res == g(6, 20)
  1809. self.check_trace_count(8)
  1810. # 6 extra from sharing guard data
  1811. self.check_resops(getarrayitem_gc_i=10 + 6)
  1812. def test_multiple_specialied_versions_bridge(self):
  1813. myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'z', 'res'])
  1814. class Base:
  1815. def __init__(self, val):
  1816. self.val = val
  1817. def getval(self):
  1818. return self.val
  1819. class A(Base):
  1820. def binop(self, other):
  1821. return A(self.getval() + other.getval())
  1822. class B(Base):
  1823. def binop(self, other):
  1824. return B(self.getval() * other.getval())
  1825. def f(x, y, z):
  1826. res = x
  1827. while y > 0:
  1828. myjitdriver.can_enter_jit(y=y, x=x, z=z, res=res)
  1829. myjitdriver.jit_merge_point(y=y, x=x, z=z, res=res)
  1830. res = res.binop(x)
  1831. y -= 1
  1832. if y < 7:
  1833. x = z
  1834. return res
  1835. def g(x, y):
  1836. a1 = f(A(x), y, A(x))
  1837. a2 = f(A(x), y, A(x))
  1838. assert a1.val == a2.val
  1839. b1 = f(B(x), y, B(x))
  1840. b2 = f(B(x), y, B(x))
  1841. assert b1.val == b2.val
  1842. c1 = f(B(x), y, A(x))
  1843. c2 = f(B(x), y, A(x))
  1844. assert c1.val == c2.val
  1845. d1 = f(A(x), y, B(x))
  1846. d2 = f(A(x), y, B(x))
  1847. assert d1.val == d2.val
  1848. return a1.val + b1.val + c1.val + d1.val
  1849. res = self.meta_interp(g, [3, 14])
  1850. assert res == g(3, 14)
  1851. def test_failing_inlined_guard(self):
  1852. myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'z', 'res'])
  1853. class Base:
  1854. def __init__(self, val):
  1855. self.val = val
  1856. def getval(self):
  1857. return self.val
  1858. class A(Base):
  1859. def binop(self, other):
  1860. return A(self.getval() + other.getval())
  1861. class B(Base):
  1862. def binop(self, other):
  1863. return B(self.getval() * other.getval())
  1864. def f(x, y, z):
  1865. res = x
  1866. while y > 0:
  1867. myjitdriver.can_enter_jit(y=y, x=x, z=z, res=res)
  1868. myjitdriver.jit_merge_point(y=y, x=x, z=z, res=res)
  1869. res = res.binop(x)
  1870. y -= 1
  1871. if y < 8:
  1872. x = z
  1873. return res
  1874. def g(x, y):
  1875. c1 = f(A(x), y, B(x))
  1876. c2 = f(A(x), y, B(x))
  1877. assert c1.val == c2.val
  1878. return c1.val
  1879. res = self.meta_interp(g, [3, 16])
  1880. assert res == g(3, 16)
  1881. def test_inlined_guard_in_short_preamble(self):
  1882. myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'z', 'res'])
  1883. class A:
  1884. def __init__(self, val):
  1885. self.val = val
  1886. def getval(self):
  1887. return self.val
  1888. def binop(self, other):
  1889. return A(self.getval() + other.getval())
  1890. def f(x, y, z):
  1891. res = x
  1892. while y > 0:
  1893. myjitdriver.can_enter_jit(y=y, x=x, z=z, res=res)
  1894. myjitdriver.jit_merge_point(y=y, x=x, z=z, res=res)
  1895. res = res.binop(x)
  1896. y -= 1
  1897. if y < 7:
  1898. x = z
  1899. return res
  1900. def g(x, y):
  1901. a1 = f(A(x), y, A(x))
  1902. a2 = f(A(x), y, A(x))
  1903. assert a1.val == a2.val
  1904. return a1.val
  1905. res = self.meta_interp(g, [3, 14])
  1906. assert res == g(3, 14)
  1907. def test_specialized_bridge(self):
  1908. myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
  1909. class A:
  1910. def __init__(self, val):
  1911. self.val = val
  1912. def binop(self, other):
  1913. return A(self.val + other.val)
  1914. def f(x, y):
  1915. res = A(0)
  1916. while y > 0:
  1917. myjitdriver.can_enter_jit(y=y, x=x, res=res)
  1918. myjitdriver.jit_merge_point(y=y, x=x, res=res)
  1919. res = res.binop(A(y))
  1920. if y<7:
  1921. res = x
  1922. y -= 1
  1923. return res
  1924. def g(x, y):
  1925. a1 = f(A(x), y)
  1926. a2 = f(A(x), y)
  1927. assert a1.val == a2.val
  1928. return a1.val
  1929. res = self.meta_interp(g, [6, 14])
  1930. assert res == g(6, 14)
  1931. def test_specialied_bridge_const(self):
  1932. myjitdriver = JitDriver(greens = [], reds = ['y', 'const', 'x', 'res'])
  1933. class A:
  1934. def __init__(self, val):
  1935. self.val = val
  1936. def binop(self, other):
  1937. return A(self.val + other.val)
  1938. def f(x, y):
  1939. res = A(0)
  1940. const = 7
  1941. while y > 0:
  1942. myjitdriver.can_enter_jit(y=y, x=x, res=res, const=const)
  1943. myjitdriver.jit_merge_point(y=y, x=x, res=res, const=const)
  1944. const = promote(const)
  1945. res = res.binop(A(const))
  1946. if y<7:
  1947. res = x
  1948. y -= 1
  1949. return res
  1950. def g(x, y):
  1951. a1 = f(A(x), y)
  1952. a2 = f(A(x), y)
  1953. assert a1.val == a2.val
  1954. return a1.val
  1955. res = self.meta_interp(g, [6, 14])
  1956. assert res == g(6, 14)
  1957. def test_multiple_specialied_zigzag(self):
  1958. myjitdriver = JitDriver(greens = [], reds = ['y', 'x', 'res'])
  1959. class Base:
  1960. def __init__(self, val):
  1961. self.val = val
  1962. class A(Base):
  1963. def binop(self, other):
  1964. return A(self.val + other.val)
  1965. def switch(self):
  1966. return B(self.val)
  1967. class B(Base):
  1968. def binop(self, other):
  1969. return B(self.val * other.val)
  1970. def switch(self):
  1971. return A(self.val)
  1972. def f(x, y):
  1973. res = x
  1974. while y > 0:
  1975. myjitdriver.can_enter_jit(y=y, x=x, res=res)
  1976. myjitdriver.jit_merge_point(y=y, x=x, res=res)
  1977. if y % 4 == 0:
  1978. res = res.switch()
  1979. res = res.binop(x)
  1980. y -= 1
  1981. return res
  1982. def g(x, y):
  1983. set_param(myjitdriver, 'max_unroll_loops', 5)
  1984. a1 = f(A(x), y)
  1985. a2 = f(A(x), y)
  1986. b1 = f(B(x), y)
  1987. b2 = f(B(x), y)
  1988. assert a1.val == a2.val
  1989. assert b1.val == b2.val
  1990. return a1.val + b1.val
  1991. res = self.meta_interp(g, [3, 23])
  1992. assert res == 7068153
  1993. self.check_trace_count(6)
  1994. self.check_resops(guard_true=8, guard_class=2, int_mul=3,
  1995. int_add=3, guard_false=4)
  1996. def test_dont_trace_every_iteration(self):
  1997. myjitdriver = JitDriver(greens = [], reds = ['a', 'b', 'i', 'sa'])
  1998. def main(a, b):
  1999. i = sa = 0
  2000. #while i < 200:
  2001. while i < 200:
  2002. myjitdriver.can_enter_jit(a=a, b=b, i=i, sa=sa)
  2003. myjitdriver.jit_merge_point(a=a, b=b, i=i, sa=sa)
  2004. if a > 0: pass
  2005. if b < 2: pass
  2006. sa += a % b
  2007. i += 1
  2008. return sa
  2009. def g():
  2010. return main(10, 20) + main(-10, -20)
  2011. res = self.meta_interp(g, [])
  2012. assert res == g()
  2013. self.check_enter_count(2)
  2014. def test_current_trace_length(self):
  2015. myjitdriver = JitDriver(greens = ['g'], reds = ['x', 'l'])
  2016. @dont_look_inside
  2017. def residual():
  2018. print "hi there"
  2019. @unroll_safe
  2020. def loop(g):
  2021. y = 0
  2022. while y < g:
  2023. residual()
  2024. y += 1
  2025. def f(x, g):
  2026. l = []
  2027. n = 0
  2028. while x > 0:
  2029. myjitdriver.can_enter_jit(x=x, g=g, l=l)
  2030. myjitdriver.jit_merge_point(x=x, g=g, l=l)
  2031. loop(g)
  2032. x -= 1
  2033. l.append(current_trace_length())
  2034. return l[-2] # not the blackholed version
  2035. res = self.meta_interp(f, [5, 8])
  2036. assert 14 < res < 42
  2037. res = self.meta_interp(f, [5, 2])
  2038. assert 4 < res < 14
  2039. def test_compute_identity_hash(self):
  2040. from rpython.rlib.objectmodel import compute_identity_hash
  2041. class A(object):
  2042. pass
  2043. def f():
  2044. a = A()
  2045. return compute_identity_hash(a) == compute_identity_hash(a)
  2046. res = self.interp_operations(f, [])
  2047. assert res
  2048. # a "did not crash" kind of test
  2049. def test_compute_unique_id(self):
  2050. from rpython.rlib.objectmodel import compute_unique_id
  2051. class A(object):
  2052. pass
  2053. def f():
  2054. a1 = A()
  2055. a2 = A()
  2056. return (compute_unique_id(a1) == compute_unique_id(a1) and
  2057. compute_unique_id(a1) != compute_unique_id(a2))
  2058. res = self.interp_operations(f, [])
  2059. assert res
  2060. def test_wrap_around_add(self):
  2061. myjitdriver = JitDriver(greens = [], reds = ['x', 'n'])
  2062. class A:
  2063. pass
  2064. def f(x):
  2065. n = 0
  2066. while x > 0:
  2067. myjitdriver.can_enter_jit(x=x, n=n)
  2068. myjitdriver.jit_merge_point(x=x, n=n)
  2069. x += 1
  2070. n += 1
  2071. return n
  2072. res = self.meta_interp(f, [sys.maxint-10])
  2073. assert res == 11
  2074. self.check_jitcell_token_count(1)
  2075. def test_wrap_around_mul(self):
  2076. myjitdriver = JitDriver(greens = [], reds = ['x', 'n'])
  2077. class A:
  2078. pass
  2079. def f(x):
  2080. n = 0
  2081. while x > 0:
  2082. myjitdriver.can_enter_jit(x=x, n=n)
  2083. myjitdriver.jit_merge_point(x=x, n=n)
  2084. x *= 2
  2085. n += 1
  2086. return n
  2087. res = self.meta_interp(f, [sys.maxint>>10])
  2088. assert res == 11
  2089. self.check_jitcell_token_count(1)
  2090. def test_wrap_around_sub(self):
  2091. myjitdriver = JitDriver(greens = [], reds = ['x', 'n'])
  2092. class A:
  2093. pass
  2094. def f(x):
  2095. n = 0
  2096. while x < 0:
  2097. myjitdriver.can_enter_jit(x=x, n=n)
  2098. myjitdriver.jit_merge_point(x=x, n=n)
  2099. x -= 1
  2100. n += 1
  2101. return n
  2102. res = self.meta_interp(f, [10-sys.maxint])
  2103. assert res == 12
  2104. self.check_jitcell_token_count(1)
  2105. def test_caching_setfield(self):
  2106. myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'node'])
  2107. class A:
  2108. pass
  2109. def f(n, a):
  2110. i = sa = 0
  2111. node = A()
  2112. node.val1 = node.val2 = 0
  2113. while i < n:
  2114. myjitdriver.can_enter_jit(sa=sa, i=i, n=n, a=a, node=node)
  2115. myjitdriver.jit_merge_point(sa=sa, i=i, n=n, a=a, node=node)
  2116. sa += node.val1 + node.val2
  2117. if i < n/2:
  2118. node.val1 = a
  2119. node.val2 = a
  2120. else:
  2121. node.val1 = a
  2122. node.val2 = a + 1
  2123. i += 1
  2124. return sa
  2125. res = self.meta_interp(f, [32, 7])
  2126. assert res == f(32, 7)
  2127. def test_caching_setarrayitem_fixed(self):
  2128. myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'node'])
  2129. def f(n, a):
  2130. i = sa = 0
  2131. node = [1, 2, 3]
  2132. while i < n:
  2133. myjitdriver.can_enter_jit(sa=sa, i=i, n=n, a=a, node=node)
  2134. myjitdriver.jit_merge_point(sa=sa, i=i, n=n, a=a, node=node)
  2135. sa += node[0] + node[1]
  2136. if i < n/2:
  2137. node[0] = a
  2138. node[1] = a
  2139. else:
  2140. node[0] = a
  2141. node[1] = a + 1
  2142. i += 1
  2143. return sa
  2144. res = self.meta_interp(f, [32, 7])
  2145. assert res == f(32, 7)
  2146. def test_caching_setarrayitem_var(self):
  2147. myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'b', 'node'])
  2148. def f(n, a, b):
  2149. i = sa = 0
  2150. node = [1, 2, 3]
  2151. while i < n:
  2152. myjitdriver.can_enter_jit(sa=sa, i=i, n=n, a=a, b=b, node=node)
  2153. myjitdriver.jit_merge_point(sa=sa, i=i, n=n, a=a, b=b, node=node)
  2154. sa += node[0] + node[b]
  2155. if i < n/2:
  2156. node[0] = a
  2157. node[b] = a
  2158. else:
  2159. node[0] = a
  2160. node[b] = a + 1
  2161. i += 1
  2162. return sa
  2163. res = self.meta_interp(f, [32, 7, 2])
  2164. assert res == f(32, 7, 2)
  2165. def test_getfield_result_with_intbound(self):
  2166. myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'node'])
  2167. class A:
  2168. pass
  2169. def f(n, a):
  2170. i = sa = 0
  2171. node = A()
  2172. node.val1 = a
  2173. while i < n:
  2174. myjitdriver.can_enter_jit(sa=sa, i=i, n=n, a=a, node=node)
  2175. myjitdriver.jit_merge_point(sa=sa, i=i, n=n, a=a, node=node)
  2176. if node.val1 > 0:
  2177. sa += 1
  2178. if i > n/2:
  2179. node.val1 = -a
  2180. i += 1
  2181. return sa
  2182. res = self.meta_interp(f, [32, 7])
  2183. assert res == f(32, 7)
  2184. def test_getfield_result_constant(self):
  2185. myjitdriver = JitDriver(greens = [], reds = ['sa', 'i', 'n', 'a', 'node'])
  2186. class A:
  2187. pass
  2188. def f(n, a):
  2189. i = sa = 0
  2190. node = A()
  2191. node.val1 = 7
  2192. while i < n:
  2193. myjitdriver.can_enter_jit(sa=sa, i=i, n=n, a=a, node=node)
  2194. myjitdriver.jit_merge_point(sa=sa, i=i, n=n, a=a, node=node)
  2195. if node.val1 == 7:
  2196. sa += 1
  2197. if i > n/2:
  2198. node.val1 = -7
  2199. i += 1
  2200. return sa
  2201. res = self.meta_interp(f, [32, 7])
  2202. assert res == f(32, 7)
  2203. def test_overflowing_shift_pos(self):
  2204. myjitdriver = JitDriver(greens = [], reds = ['a', 'b', 'n', 'sa'])
  2205. def f1(a, b):
  2206. n = sa = 0
  2207. while n < 10:
  2208. myjitdriver.jit_merge_point(a=a, b=b, n=n, sa=sa)
  2209. if 0 < a <= 5: pass
  2210. if 0 < b <= 5: pass
  2211. sa += (((((a << b) << b) << b) >> b) >> b) >> b
  2212. n += 1
  2213. return sa
  2214. def f2(a, b):
  2215. n = sa = 0
  2216. while n < 10:
  2217. myjitdriver.jit_merge_point(a=a, b=b, n=n, sa=sa)
  2218. if 0 < a < promote(sys.maxint/2): pass
  2219. if 0 < b < 100: pass
  2220. sa += (((((a << b) << b) << b) >> b) >> b) >> b
  2221. n += 1
  2222. return sa
  2223. assert self.meta_interp(f1, [5, 5]) == 50
  2224. self.check_resops(int_rshift=0)
  2225. for f in (f1, f2):
  2226. assert self.meta_interp(f, [5, 6]) == 50
  2227. self.check_resops(int_rshift=3)
  2228. assert self.meta_interp(f, [10, 5]) == 100
  2229. self.check_resops(int_rshift=3)
  2230. assert self.meta_interp(f, [10, 6]) == 100
  2231. self.check_resops(int_rshift=3)
  2232. assert self.meta_interp(f, [5, 31]) == 0
  2233. self.check_resops(int_rshift=3)
  2234. bigval = 1
  2235. while is_valid_int(bigval << 3):
  2236. bigval = bigval << 1
  2237. assert self.meta_interp(f, [bigval, 5]) == 0
  2238. self.check_resops(int_rshift=3)
  2239. def test_overflowing_shift_neg(self):
  2240. myjitdriver = JitDriver(greens = [], reds = ['a', 'b', 'n', 'sa'])
  2241. def f1(a, b):
  2242. n = sa = 0
  2243. while n < 10:
  2244. myjitdriver.jit_merge_point(a=a, b=b, n=n, sa=sa)
  2245. if -5 <= a < 0: pass
  2246. if 0 < b <= 5: pass
  2247. sa += (((((a << b) << b) << b) >> b) >> b) >> b
  2248. n += 1
  2249. return sa
  2250. def f2(a, b):
  2251. n = sa = 0
  2252. while n < 10:
  2253. myjitdriver.jit_merge_point(a=a, b=b, n=n, sa=sa)
  2254. if -promote(sys.maxint/2) < a < 0: pass
  2255. if 0 < b < 100: pass
  2256. sa += (((((a << b) << b) << b) >> b) >> b) >> b
  2257. n += 1
  2258. return sa
  2259. assert self.meta_interp(f1, [-5, 5]) == -50
  2260. self.check_resops(int_rshift=0)
  2261. for f in (f1, f2):
  2262. assert self.meta_interp(f, [-5, 6]) == -50
  2263. self.check_resops(int_rshift=3)
  2264. assert self.meta_interp(f, [-10, 5]) == -100
  2265. self.check_resops(int_rshift=3)
  2266. assert self.meta_interp(f, [-10, 6]) == -100
  2267. self.check_resops(int_rshift=3)
  2268. assert self.meta_interp(f, [-5, 31]) == 0
  2269. self.check_resops(int_rshift=3)
  2270. bigval = 1
  2271. while is_valid_int(bigval << 3):
  2272. bigval = bigval << 1
  2273. assert self.meta_interp(f, [bigval, 5]) == 0
  2274. self.check_resops(int_rshift=3)
  2275. def test_pure_op_not_to_be_propagated(self):
  2276. myjitdriver = JitDriver(greens = [], reds = ['n', 'sa'])
  2277. def f(n):
  2278. sa = 0
  2279. while n > 0:
  2280. myjitdriver.jit_merge_point(n=n, sa=sa)
  2281. sa += n + 1
  2282. n -= 1
  2283. return sa
  2284. assert self.meta_interp(f, [10]) == f(10)
  2285. def test_inputarg_reset_bug(self):
  2286. ## j = 0
  2287. ## while j < 100:
  2288. ## j += 1
  2289. ## c = 0
  2290. ## j = 0
  2291. ## while j < 2:
  2292. ## j += 1
  2293. ## if c == 0:
  2294. ## c = 1
  2295. ## else:
  2296. ## c = 0
  2297. ## j = 0
  2298. ## while j < 100:
  2299. ## j += 1
  2300. def get_printable_location(i):
  2301. return str(i)
  2302. myjitdriver = JitDriver(greens = ['i'], reds = ['j', 'c', 'a'],
  2303. get_printable_location=get_printable_location)
  2304. bytecode = "0j10jc20a3"
  2305. def f():
  2306. set_param(myjitdriver, 'threshold', 7)
  2307. set_param(myjitdriver, 'trace_eagerness', 1)
  2308. i = j = c = a = 1
  2309. while True:
  2310. myjitdriver.jit_merge_point(i=i, j=j, c=c, a=a)
  2311. if i >= len(bytecode):
  2312. break
  2313. op = bytecode[i]
  2314. i += 1
  2315. if op == 'j':
  2316. j += 1
  2317. elif op == 'c':
  2318. promote(c)
  2319. c = 1 - c
  2320. elif op == '2':
  2321. if j < 3:
  2322. i -= 3
  2323. myjitdriver.can_enter_jit(i=i, j=j, c=c, a=a)
  2324. elif op == '1':
  2325. k = j*a
  2326. if j < 100:
  2327. i -= 2
  2328. a += k
  2329. myjitdriver.can_enter_jit(i=i, j=j, c=c, a=a)
  2330. else:
  2331. a += k*2
  2332. elif op == '0':
  2333. j = c = a = 0
  2334. elif op == 'a':
  2335. j += 1
  2336. a += 1
  2337. elif op == '3':
  2338. if a < 100:
  2339. i -= 2
  2340. myjitdriver.can_enter_jit(i=i, j=j, c=c, a=a)
  2341. else:
  2342. return ord(op)
  2343. return 42
  2344. assert f() == 42
  2345. def g():
  2346. res = 1
  2347. for i in range(10):
  2348. res = f()
  2349. return res
  2350. res = self.meta_interp(g, [])
  2351. assert res == 42
  2352. def test_read_timestamp(self):
  2353. import time
  2354. from rpython.rlib.rtimer import read_timestamp
  2355. def busy_loop():
  2356. start = time.time()
  2357. while time.time() - start < 0.1:
  2358. # busy wait
  2359. pass
  2360. def f():
  2361. t1 = read_timestamp()
  2362. busy_loop()
  2363. t2 = read_timestamp()
  2364. return t2 - t1 > 1000
  2365. res = self.interp_operations(f, [])
  2366. assert res
  2367. def test_bug688_multiple_immutable_fields(self):
  2368. myjitdriver = JitDriver(greens=[], reds=['counter','context'])
  2369. class Tag:
  2370. pass
  2371. class InnerContext():
  2372. _immutable_fields_ = ['variables','local_names']
  2373. def __init__(self, variables):
  2374. self.variables = variables
  2375. self.local_names = [0]
  2376. def store(self):
  2377. self.local_names[0] = 1
  2378. def retrieve(self):
  2379. variables = self.variables
  2380. promote(variables)
  2381. result = self.local_names[0]
  2382. if result == 0:
  2383. return -1
  2384. else:
  2385. return -1
  2386. def build():
  2387. context = InnerContext(Tag())
  2388. context.store()
  2389. counter = 0
  2390. while True:
  2391. myjitdriver.jit_merge_point(context=context, counter = counter)
  2392. context.retrieve()
  2393. context.retrieve()
  2394. counter += 1
  2395. if counter > 10:
  2396. return 7
  2397. assert self.meta_interp(build, []) == 7
  2398. self.check_resops(getfield_gc_r=2)
  2399. def test_args_becomming_equal(self):
  2400. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a', 'b'])
  2401. def f(n, a, b):
  2402. sa = i = 0
  2403. while i < n:
  2404. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a, b=b)
  2405. sa += a
  2406. sa *= b
  2407. if i > n/2:
  2408. a = b
  2409. i += 1
  2410. return sa
  2411. assert self.meta_interp(f, [20, 1, 2]) == f(20, 1, 2)
  2412. def test_args_becomming_equal_boxed1(self):
  2413. class A(object):
  2414. def __init__(self, a, b):
  2415. self.a = a
  2416. self.b = b
  2417. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a', 'b', 'node'])
  2418. def f(n, a, b):
  2419. sa = i = 0
  2420. node = A(a,b)
  2421. while i < n:
  2422. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a, b=b, node=node)
  2423. sa += node.a
  2424. sa *= node.b
  2425. if i > n/2:
  2426. node = A(b, b)
  2427. else:
  2428. node = A(a, b)
  2429. i += 1
  2430. return sa
  2431. assert self.meta_interp(f, [20, 1, 2]) == f(20, 1, 2)
  2432. def test_args_becomming_not_equal_boxed1(self):
  2433. class A(object):
  2434. def __init__(self, a, b):
  2435. self.a = a
  2436. self.b = b
  2437. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a', 'b', 'node'])
  2438. def f(n, a, b):
  2439. sa = i = 0
  2440. node = A(b, b)
  2441. while i < n:
  2442. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a, b=b, node=node)
  2443. sa += node.a
  2444. sa *= node.b
  2445. if i > n/2:
  2446. node = A(a, b)
  2447. else:
  2448. node = A(b, b)
  2449. i += 1
  2450. return sa
  2451. assert self.meta_interp(f, [20, 1, 2]) == f(20, 1, 2)
  2452. def test_args_becomming_equal_boxed2(self):
  2453. class A(object):
  2454. def __init__(self, a, b):
  2455. self.a = a
  2456. self.b = b
  2457. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'node'])
  2458. def f(n, a, b):
  2459. sa = i = 0
  2460. node = A(a, b)
  2461. while i < n:
  2462. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, node=node)
  2463. sa += node.a
  2464. sa *= node.b
  2465. if i > n/2:
  2466. node = A(node.b, node.b)
  2467. else:
  2468. node = A(node.b, node.a)
  2469. i += 1
  2470. return sa
  2471. assert self.meta_interp(f, [20, 1, 2]) == f(20, 1, 2)
  2472. def test_inlined_short_preamble_guard_needed_in_loop1(self):
  2473. class A(object):
  2474. def __init__(self, a):
  2475. self.a = a
  2476. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa',
  2477. 'a', 'b'])
  2478. def f(n, a, b):
  2479. sa = i = 0
  2480. while i < n:
  2481. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a, b=b)
  2482. if a.a < 10:
  2483. sa += a.a
  2484. b.a = i
  2485. i += 1
  2486. return sa
  2487. def g(n):
  2488. return f(n, A(5), A(10))
  2489. assert self.meta_interp(g, [20]) == g(20)
  2490. def test_ovf_guard_in_short_preamble2(self):
  2491. class A(object):
  2492. def __init__(self, val):
  2493. self.val = val
  2494. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a', 'node1', 'node2'])
  2495. def f(n, a):
  2496. node1 = node2 = A(0)
  2497. sa = i = 0
  2498. while i < n:
  2499. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a, node1=node1, node2=node2)
  2500. node2.val = 7
  2501. if a >= 100:
  2502. sa += 1
  2503. try:
  2504. sa += ovfcheck(i + i)
  2505. except OverflowError:
  2506. assert 0
  2507. node1 = A(i)
  2508. i += 1
  2509. assert self.meta_interp(f, [20, 7]) == f(20, 7)
  2510. def test_intbounds_generalized(self):
  2511. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa'])
  2512. def f(n):
  2513. sa = i = 0
  2514. while i < n:
  2515. myjitdriver.jit_merge_point(n=n, i=i, sa=sa)
  2516. if i > n/2:
  2517. sa += 1
  2518. else:
  2519. sa += 2
  2520. i += 1
  2521. return sa
  2522. assert self.meta_interp(f, [20]) == f(20)
  2523. self.check_resops(int_lt=4, int_le=0, int_ge=0, int_gt=4)
  2524. def test_intbounds_not_generalized1(self):
  2525. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa'])
  2526. def f(n):
  2527. sa = i = 0
  2528. while i < n:
  2529. myjitdriver.jit_merge_point(n=n, i=i, sa=sa)
  2530. if i > n/2:
  2531. sa += 1
  2532. else:
  2533. sa += 2
  2534. assert -100 < i < 100
  2535. i += 1
  2536. return sa
  2537. assert self.meta_interp(f, [20]) == f(20)
  2538. self.check_resops(int_lt=6, int_le=2, int_ge=4, int_gt=5)
  2539. def test_intbounds_not_generalized2(self):
  2540. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'node'])
  2541. class A(object):
  2542. def __init__(self, val):
  2543. self.val = val
  2544. def f(n):
  2545. sa = i = 0
  2546. node = A(n)
  2547. while i < n:
  2548. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, node=node)
  2549. if i > n/2:
  2550. sa += 1
  2551. else:
  2552. sa += 2
  2553. assert -100 <= node.val <= 100
  2554. i += 1
  2555. return sa
  2556. assert self.meta_interp(f, [20]) == f(20)
  2557. self.check_resops(int_lt=4, int_le=3, int_ge=3, int_gt=4)
  2558. def test_retrace_limit1(self):
  2559. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a'])
  2560. def f(n, limit):
  2561. set_param(myjitdriver, 'retrace_limit', limit)
  2562. sa = i = a = 0
  2563. while i < n:
  2564. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a)
  2565. a = i/4
  2566. a = hint(a, promote=True)
  2567. sa += a
  2568. i += 1
  2569. return sa
  2570. assert self.meta_interp(f, [20, 2]) == f(20, 2)
  2571. self.check_jitcell_token_count(1)
  2572. self.check_target_token_count(4)
  2573. assert self.meta_interp(f, [20, 3]) == f(20, 3)
  2574. self.check_jitcell_token_count(1)
  2575. self.check_target_token_count(5)
  2576. def test_max_retrace_guards(self):
  2577. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a'])
  2578. def f(n, limit):
  2579. set_param(myjitdriver, 'retrace_limit', 3)
  2580. set_param(myjitdriver, 'max_retrace_guards', limit)
  2581. sa = i = a = 0
  2582. while i < n:
  2583. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a)
  2584. a = i/4
  2585. a = hint(a, promote=True)
  2586. sa += a
  2587. i += 1
  2588. return sa
  2589. assert self.meta_interp(f, [20, 1]) == f(20, 1)
  2590. self.check_jitcell_token_count(1)
  2591. self.check_target_token_count(2)
  2592. assert self.meta_interp(f, [20, 10]) == f(20, 10)
  2593. self.check_jitcell_token_count(1)
  2594. self.check_target_token_count(5)
  2595. def test_max_unroll_loops(self):
  2596. from rpython.jit.metainterp.optimize import InvalidLoop
  2597. from rpython.jit.metainterp import optimizeopt
  2598. myjitdriver = JitDriver(greens = [], reds = ['n', 'i'])
  2599. #
  2600. def f(n, limit):
  2601. set_param(myjitdriver, 'threshold', 5)
  2602. set_param(myjitdriver, 'max_unroll_loops', limit)
  2603. i = 0
  2604. while i < n:
  2605. myjitdriver.jit_merge_point(n=n, i=i)
  2606. print i
  2607. i += 1
  2608. return i
  2609. #
  2610. def my_optimize_trace(*args, **kwds):
  2611. raise InvalidLoop
  2612. old_optimize_trace = optimizeopt.optimize_trace
  2613. optimizeopt.optimize_trace = my_optimize_trace
  2614. try:
  2615. res = self.meta_interp(f, [23, 4])
  2616. assert res == 23
  2617. self.check_trace_count(0)
  2618. self.check_aborted_count(3)
  2619. #
  2620. res = self.meta_interp(f, [23, 20])
  2621. assert res == 23
  2622. self.check_trace_count(0)
  2623. self.check_aborted_count(2)
  2624. finally:
  2625. optimizeopt.optimize_trace = old_optimize_trace
  2626. def test_max_unroll_loops_retry_without_unroll(self):
  2627. from rpython.jit.metainterp.optimize import InvalidLoop
  2628. from rpython.jit.metainterp import optimizeopt
  2629. myjitdriver = JitDriver(greens = [], reds = ['n', 'i'])
  2630. #
  2631. def f(n, limit):
  2632. set_param(myjitdriver, 'threshold', 5)
  2633. set_param(myjitdriver, 'max_unroll_loops', limit)
  2634. i = 0
  2635. while i < n:
  2636. myjitdriver.jit_merge_point(n=n, i=i)
  2637. print i
  2638. i += 1
  2639. return i
  2640. #
  2641. seen = []
  2642. def my_optimize_trace(metainterp_sd, jitdriver_sd, data, memo=None):
  2643. seen.append('unroll' in data.enable_opts)
  2644. raise InvalidLoop
  2645. old_optimize_trace = optimizeopt.optimize_trace
  2646. optimizeopt.optimize_trace = my_optimize_trace
  2647. try:
  2648. if not self.basic:
  2649. py.test.skip("unrolling")
  2650. res = self.meta_interp(f, [23, 4])
  2651. assert res == 23
  2652. assert False in seen
  2653. assert True in seen
  2654. finally:
  2655. optimizeopt.optimize_trace = old_optimize_trace
  2656. def test_retrace_limit_with_extra_guards(self):
  2657. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa', 'a',
  2658. 'node'])
  2659. def f(n, limit):
  2660. set_param(myjitdriver, 'retrace_limit', limit)
  2661. sa = i = a = 0
  2662. node = [1, 2, 3]
  2663. node[1] = n
  2664. while i < n:
  2665. myjitdriver.jit_merge_point(n=n, i=i, sa=sa, a=a, node=node)
  2666. a = i/4
  2667. a = hint(a, promote=True)
  2668. if i&1 == 0:
  2669. sa += node[i%3]
  2670. sa += a
  2671. i += 1
  2672. return sa
  2673. assert self.meta_interp(f, [20, 2]) == f(20, 2)
  2674. self.check_jitcell_token_count(1)
  2675. self.check_target_token_count(4)
  2676. assert self.meta_interp(f, [20, 3]) == f(20, 3)
  2677. self.check_jitcell_token_count(1)
  2678. self.check_target_token_count(5)
  2679. def test_retrace_ending_up_retracing_another_loop(self):
  2680. myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'i', 'sa'])
  2681. bytecode = "0+sI0+SI"
  2682. def f(n):
  2683. set_param(None, 'threshold', 3)
  2684. set_param(None, 'trace_eagerness', 1)
  2685. set_param(None, 'retrace_limit', 5)
  2686. set_param(None, 'function_threshold', -1)
  2687. pc = sa = i = 0
  2688. while pc < len(bytecode):
  2689. myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i)
  2690. n = hint(n, promote=True)
  2691. op = bytecode[pc]
  2692. if op == '0':
  2693. i = 0
  2694. elif op == '+':
  2695. i += 1
  2696. elif op == 's':
  2697. sa += i
  2698. elif op == 'S':
  2699. sa += 2
  2700. elif op == 'I':
  2701. if i < n:
  2702. pc -= 2
  2703. myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i)
  2704. continue
  2705. pc += 1
  2706. return sa
  2707. def g(n1, n2):
  2708. for i in range(10):
  2709. f(n1)
  2710. for i in range(10):
  2711. f(n2)
  2712. nn = [10, 3]
  2713. assert self.meta_interp(g, nn) == g(*nn)
  2714. # The attempts of retracing first loop will end up retracing the
  2715. # second and thus fail 5 times, saturating the retrace_count. Instead a
  2716. # bridge back to the preamble of the first loop is produced. A guard in
  2717. # this bridge is later traced resulting in a failed attempt of retracing
  2718. # the second loop.
  2719. self.check_trace_count(8)
  2720. # FIXME: Add a gloabl retrace counter and test that we are not trying more than 5 times.
  2721. def g(n):
  2722. for i in range(n):
  2723. for j in range(10):
  2724. f(n-i)
  2725. res = self.meta_interp(g, [10])
  2726. assert res == g(10)
  2727. self.check_jitcell_token_count(2)
  2728. if 0:
  2729. for cell in get_stats().get_all_jitcell_tokens():
  2730. # Initialal trace with two labels and 5 retraces
  2731. assert len(cell.target_tokens) <= 7
  2732. def test_nested_retrace(self):
  2733. myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'a', 'i', 'j', 'sa'])
  2734. bytecode = "ij+Jj+JI"
  2735. def f(n, a):
  2736. set_param(None, 'threshold', 5)
  2737. set_param(None, 'trace_eagerness', 1)
  2738. set_param(None, 'retrace_limit', 2)
  2739. pc = sa = i = j = 0
  2740. while pc < len(bytecode):
  2741. myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, a=a)
  2742. a = hint(a, promote=True)
  2743. op = bytecode[pc]
  2744. if op == 'i':
  2745. i = 0
  2746. elif op == 'j':
  2747. j = 0
  2748. elif op == '+':
  2749. sa += a
  2750. elif op == 'J':
  2751. j += 1
  2752. if j < 3:
  2753. pc -= 1
  2754. myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, a=a)
  2755. continue
  2756. elif op == 'I':
  2757. i += 1
  2758. if i < n:
  2759. pc -= 6
  2760. myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, a=a)
  2761. continue
  2762. pc += 1
  2763. return sa
  2764. res = self.meta_interp(f, [10, 7])
  2765. assert res == f(10, 7)
  2766. self.check_jitcell_token_count(2)
  2767. if self.basic:
  2768. for cell in get_stats().get_all_jitcell_tokens():
  2769. assert len(cell.target_tokens) == 2
  2770. def g(n):
  2771. return f(n, 2) + f(n, 3)
  2772. res = self.meta_interp(g, [10])
  2773. assert res == g(10)
  2774. self.check_jitcell_token_count(2)
  2775. if self.basic:
  2776. for cell in get_stats().get_all_jitcell_tokens():
  2777. assert len(cell.target_tokens) <= 3
  2778. def g(n):
  2779. return f(n, 2) + f(n, 3) + f(n, 4) + f(n, 5) + f(n, 6) + f(n, 7)
  2780. res = self.meta_interp(g, [10])
  2781. assert res == g(10)
  2782. # 2 loops and one function
  2783. self.check_jitcell_token_count(3)
  2784. cnt = 0
  2785. if self.basic:
  2786. for cell in get_stats().get_all_jitcell_tokens():
  2787. if cell.target_tokens is None:
  2788. cnt += 1
  2789. else:
  2790. assert len(cell.target_tokens) <= 4
  2791. assert cnt == 1
  2792. def test_frame_finished_during_retrace(self):
  2793. class Base(object):
  2794. pass
  2795. class A(Base):
  2796. def __init__(self, a):
  2797. self.val = a
  2798. self.num = 1
  2799. def inc(self):
  2800. return A(self.val + 1)
  2801. class B(Base):
  2802. def __init__(self, a):
  2803. self.val = a
  2804. self.num = 1000
  2805. def inc(self):
  2806. return B(self.val + 1)
  2807. myjitdriver = JitDriver(greens = [], reds = ['sa', 'a'])
  2808. def f():
  2809. set_param(None, 'threshold', 3)
  2810. set_param(None, 'trace_eagerness', 2)
  2811. a = A(0)
  2812. sa = 0
  2813. while a.val < 8:
  2814. myjitdriver.jit_merge_point(a=a, sa=sa)
  2815. a = a.inc()
  2816. if a.val > 4:
  2817. a = B(a.val)
  2818. sa += a.num
  2819. return sa
  2820. res = self.meta_interp(f, [])
  2821. assert res == f()
  2822. def test_frame_finished_during_continued_retrace(self):
  2823. class Base(object):
  2824. pass
  2825. class A(Base):
  2826. def __init__(self, a):
  2827. self.val = a
  2828. self.num = 100
  2829. def inc(self):
  2830. return A(self.val + 1)
  2831. class B(Base):
  2832. def __init__(self, a):
  2833. self.val = a
  2834. self.num = 10000
  2835. def inc(self):
  2836. return B(self.val + 1)
  2837. myjitdriver = JitDriver(greens = [], reds = ['sa', 'b', 'a'])
  2838. def f(b):
  2839. set_param(None, 'threshold', 6)
  2840. set_param(None, 'trace_eagerness', 4)
  2841. a = A(0)
  2842. sa = 0
  2843. while a.val < 15:
  2844. myjitdriver.jit_merge_point(a=a, b=b, sa=sa)
  2845. a = a.inc()
  2846. if a.val > 8:
  2847. a = B(a.val)
  2848. if b == 1:
  2849. b = 2
  2850. else:
  2851. b = 1
  2852. sa += a.num + b
  2853. return sa
  2854. res = self.meta_interp(f, [1])
  2855. assert res == f(1)
  2856. def test_remove_array_operations(self):
  2857. myjitdriver = JitDriver(greens = [], reds = ['a'])
  2858. class W_Int:
  2859. def __init__(self, intvalue):
  2860. self.intvalue = intvalue
  2861. def f(x):
  2862. a = [W_Int(x)]
  2863. while a[0].intvalue > 0:
  2864. myjitdriver.jit_merge_point(a=a)
  2865. a[0] = W_Int(a[0].intvalue - 3)
  2866. return a[0].intvalue
  2867. res = self.meta_interp(f, [100])
  2868. assert res == -2
  2869. self.check_resops(setarrayitem_gc=2, getarrayitem_gc_r=1)
  2870. def test_continue_tracing_with_boxes_in_start_snapshot_replaced_by_optimizer(self):
  2871. myjitdriver = JitDriver(greens = [], reds = ['sa', 'n', 'a', 'b'])
  2872. def f(n):
  2873. sa = a = 0
  2874. b = 10
  2875. while n:
  2876. myjitdriver.jit_merge_point(sa=sa, n=n, a=a, b=b)
  2877. sa += b
  2878. b += 1
  2879. if b > 7:
  2880. pass
  2881. if a == 0:
  2882. a = 1
  2883. elif a == 1:
  2884. a = 2
  2885. elif a == 2:
  2886. a = 0
  2887. sa += a
  2888. sa += 0
  2889. n -= 1
  2890. return sa
  2891. res = self.meta_interp(f, [16])
  2892. assert res == f(16)
  2893. def test_loopinvariant_array_shrinking1(self):
  2894. myjitdriver = JitDriver(greens = [], reds = ['sa', 'n', 'i', 'a'])
  2895. def f(n):
  2896. sa = i = 0
  2897. a = [0, 1, 2, 3, 4]
  2898. while i < n:
  2899. myjitdriver.jit_merge_point(sa=sa, n=n, a=a, i=i)
  2900. if i < n / 2:
  2901. sa += a[4]
  2902. elif i == n / 2:
  2903. a.pop()
  2904. i += 1
  2905. res = self.meta_interp(f, [32])
  2906. assert res == f(32)
  2907. self.check_resops(arraylen_gc=3)
  2908. def test_ulonglong_mod(self):
  2909. myjitdriver = JitDriver(greens = [], reds = ['n', 'a'])
  2910. class A:
  2911. pass
  2912. def f(n):
  2913. sa = i = rffi.cast(rffi.ULONGLONG, 1)
  2914. a = A()
  2915. while i < rffi.cast(rffi.ULONGLONG, n):
  2916. a.sa = sa
  2917. a.i = i
  2918. myjitdriver.jit_merge_point(n=n, a=a)
  2919. sa = a.sa
  2920. i = a.i
  2921. sa += sa % i
  2922. i += 1
  2923. res = self.meta_interp(f, [32])
  2924. assert res == f(32)
  2925. def test_int_signext(self):
  2926. def f(n):
  2927. return rffi.cast(rffi.SIGNEDCHAR, n)
  2928. def f1(n):
  2929. return rffi.cast(rffi.SIGNEDCHAR, n + 1)
  2930. res = self.interp_operations(f, [128])
  2931. assert res == -128
  2932. res = self.interp_operations(f1, [127])
  2933. assert res == -128
  2934. res = self.interp_operations(f, [-35 + 256 * 29])
  2935. assert res == -35
  2936. res = self.interp_operations(f, [127 - 256 * 29])
  2937. assert res == 127
  2938. class BaseLLtypeTests(BasicTests):
  2939. def test_identityhash(self):
  2940. A = lltype.GcStruct("A")
  2941. def f():
  2942. obj1 = lltype.malloc(A)
  2943. obj2 = lltype.malloc(A)
  2944. return lltype.identityhash(obj1) == lltype.identityhash(obj2)
  2945. assert not f()
  2946. res = self.interp_operations(f, [])
  2947. assert not res
  2948. def test_oops_on_nongc(self):
  2949. from rpython.rtyper.lltypesystem import lltype
  2950. TP = lltype.Struct('x')
  2951. def f(i1, i2):
  2952. p1 = prebuilt[i1]
  2953. p2 = prebuilt[i2]
  2954. a = p1 is p2
  2955. b = p1 is not p2
  2956. c = bool(p1)
  2957. d = not bool(p2)
  2958. return 1000*a + 100*b + 10*c + d
  2959. prebuilt = [lltype.malloc(TP, flavor='raw', immortal=True)] * 2
  2960. expected = f(0, 1)
  2961. assert self.interp_operations(f, [0, 1]) == expected
  2962. def test_casts(self):
  2963. py.test.skip("xxx fix or kill")
  2964. if not self.basic:
  2965. py.test.skip("test written in a style that "
  2966. "means it's frontend only")
  2967. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  2968. TP = lltype.GcStruct('S1')
  2969. def f(p):
  2970. n = lltype.cast_ptr_to_int(p)
  2971. return n
  2972. x = lltype.malloc(TP)
  2973. xref = lltype.cast_opaque_ptr(llmemory.GCREF, x)
  2974. res = self.interp_operations(f, [xref])
  2975. y = llmemory.cast_ptr_to_adr(x)
  2976. y = llmemory.cast_adr_to_int(y)
  2977. assert rffi.get_real_int(res) == rffi.get_real_int(y)
  2978. #
  2979. TP = lltype.Struct('S2')
  2980. prebuilt = [lltype.malloc(TP, immortal=True),
  2981. lltype.malloc(TP, immortal=True)]
  2982. def f(x):
  2983. p = prebuilt[x]
  2984. n = lltype.cast_ptr_to_int(p)
  2985. return n
  2986. res = self.interp_operations(f, [1])
  2987. y = llmemory.cast_ptr_to_adr(prebuilt[1])
  2988. y = llmemory.cast_adr_to_int(y)
  2989. assert rffi.get_real_int(res) == rffi.get_real_int(y)
  2990. def test_collapsing_ptr_eq(self):
  2991. S = lltype.GcStruct('S')
  2992. p = lltype.malloc(S)
  2993. driver = JitDriver(greens = [], reds = ['n', 'x'])
  2994. def f(n, x):
  2995. while n > 0:
  2996. driver.can_enter_jit(n=n, x=x)
  2997. driver.jit_merge_point(n=n, x=x)
  2998. if x:
  2999. n -= 1
  3000. n -= 1
  3001. def main():
  3002. f(10, p)
  3003. f(10, lltype.nullptr(S))
  3004. self.meta_interp(main, [])
  3005. def test_enable_opts(self):
  3006. jitdriver = JitDriver(greens = [], reds = ['a'])
  3007. class A(object):
  3008. def __init__(self, i):
  3009. self.i = i
  3010. def f():
  3011. a = A(0)
  3012. while a.i < 10:
  3013. jitdriver.jit_merge_point(a=a)
  3014. jitdriver.can_enter_jit(a=a)
  3015. a = A(a.i + 1)
  3016. self.meta_interp(f, [])
  3017. self.check_resops(new_with_vtable=0)
  3018. self.meta_interp(f, [], enable_opts='')
  3019. self.check_resops(new_with_vtable=1)
  3020. def test_two_loopinvariant_arrays1(self):
  3021. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  3022. myjitdriver = JitDriver(greens = [], reds = ['sa', 'n', 'i', 'a'])
  3023. TP = lltype.GcArray(lltype.Signed)
  3024. def f(n):
  3025. sa = i = 0
  3026. a = lltype.malloc(TP, 5)
  3027. a[4] = 7
  3028. while i < n:
  3029. myjitdriver.jit_merge_point(sa=sa, n=n, a=a, i=i)
  3030. if i < n/2:
  3031. sa += a[4]
  3032. if i == n/2:
  3033. a = lltype.malloc(TP, 3)
  3034. i += 1
  3035. return sa
  3036. res = self.meta_interp(f, [32])
  3037. assert res == f(32)
  3038. self.check_trace_count(2)
  3039. def test_two_loopinvariant_arrays2(self):
  3040. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  3041. myjitdriver = JitDriver(greens = [], reds = ['sa', 'n', 'i', 'a'])
  3042. TP = lltype.GcArray(lltype.Signed)
  3043. def f(n):
  3044. sa = i = 0
  3045. a = lltype.malloc(TP, 5)
  3046. a[4] = 7
  3047. while i < n:
  3048. myjitdriver.jit_merge_point(sa=sa, n=n, a=a, i=i)
  3049. if i < n/2:
  3050. sa += a[4]
  3051. elif i > n/2:
  3052. sa += a[2]
  3053. if i == n/2:
  3054. a = lltype.malloc(TP, 3)
  3055. a[2] = 42
  3056. i += 1
  3057. return sa
  3058. res = self.meta_interp(f, [32])
  3059. assert res == f(32)
  3060. self.check_trace_count(2)
  3061. def test_two_loopinvariant_arrays3(self):
  3062. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  3063. myjitdriver = JitDriver(greens = [], reds = ['sa', 'n', 'i', 'a'])
  3064. TP = lltype.GcArray(lltype.Signed)
  3065. def f(n):
  3066. sa = i = 0
  3067. a = lltype.malloc(TP, 5)
  3068. a[2] = 7
  3069. while i < n:
  3070. myjitdriver.jit_merge_point(sa=sa, n=n, a=a, i=i)
  3071. if i < n/2:
  3072. sa += a[2]
  3073. elif i > n/2:
  3074. sa += a[3]
  3075. if i == n/2:
  3076. a = lltype.malloc(TP, 7)
  3077. a[3] = 10
  3078. a[2] = 42
  3079. i += 1
  3080. return sa
  3081. res = self.meta_interp(f, [32])
  3082. assert res == f(32)
  3083. self.check_trace_count(3)
  3084. def test_two_loopinvariant_arrays_boxed(self):
  3085. class A(object):
  3086. def __init__(self, a):
  3087. self.a = a
  3088. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  3089. myjitdriver = JitDriver(greens = [], reds = ['sa', 'n', 'i', 'a'])
  3090. TP = lltype.GcArray(lltype.Signed)
  3091. a1 = A(lltype.malloc(TP, 5))
  3092. a2 = A(lltype.malloc(TP, 3))
  3093. def f(n):
  3094. sa = i = 0
  3095. a = a1
  3096. a.a[4] = 7
  3097. while i < n:
  3098. myjitdriver.jit_merge_point(sa=sa, n=n, a=a, i=i)
  3099. if i < n/2:
  3100. sa += a.a[4]
  3101. if i == n/2:
  3102. a = a2
  3103. i += 1
  3104. return sa
  3105. res = self.meta_interp(f, [32])
  3106. assert res == f(32)
  3107. self.check_resops(arraylen_gc=2)
  3108. def test_release_gil_flush_heap_cache(self):
  3109. T = rffi.CArrayPtr(rffi.TIME_T)
  3110. external = rffi.llexternal("time", [T], rffi.TIME_T, releasegil=True)
  3111. # Not a real lock, has all the same properties with respect to GIL
  3112. # release though, so good for this test.
  3113. class Lock(object):
  3114. @dont_look_inside
  3115. def acquire(self):
  3116. external(lltype.nullptr(T.TO))
  3117. @dont_look_inside
  3118. def release(self):
  3119. external(lltype.nullptr(T.TO))
  3120. class X(object):
  3121. def __init__(self, idx):
  3122. self.field = idx
  3123. @dont_look_inside
  3124. def get_obj(z):
  3125. return X(z)
  3126. myjitdriver = JitDriver(greens=[], reds=["n", "l", "z", "lock"])
  3127. def f(n, z):
  3128. lock = Lock()
  3129. l = 0
  3130. while n > 0:
  3131. myjitdriver.jit_merge_point(lock=lock, l=l, n=n, z=z)
  3132. x = get_obj(z)
  3133. l += x.field
  3134. lock.acquire()
  3135. # This must not reuse the previous one.
  3136. n -= x.field
  3137. lock.release()
  3138. return n
  3139. res = self.meta_interp(f, [10, 1])
  3140. self.check_resops(getfield_gc_i=4)
  3141. assert res == f(10, 1)
  3142. def test_jit_merge_point_with_raw_pointer(self):
  3143. driver = JitDriver(greens = [], reds = ['n', 'x'])
  3144. TP = lltype.Array(lltype.Signed, hints={'nolength': True})
  3145. def f(n):
  3146. x = lltype.malloc(TP, 10, flavor='raw')
  3147. x[0] = 1
  3148. while n > 0:
  3149. driver.jit_merge_point(n=n, x=x)
  3150. n -= x[0]
  3151. lltype.free(x, flavor='raw')
  3152. return n
  3153. self.meta_interp(f, [10], repeat=3)
  3154. def test_jit_merge_point_with_pbc(self):
  3155. driver = JitDriver(greens = [], reds = ['x'])
  3156. class A(object):
  3157. def __init__(self, x):
  3158. self.x = x
  3159. def _freeze_(self):
  3160. return True
  3161. pbc = A(1)
  3162. def main(x):
  3163. return f(x, pbc)
  3164. def f(x, pbc):
  3165. while x > 0:
  3166. driver.jit_merge_point(x = x)
  3167. x -= pbc.x
  3168. return x
  3169. self.meta_interp(main, [10])
  3170. def test_look_inside_iff_const(self):
  3171. @look_inside_iff(lambda arg: isconstant(arg))
  3172. def f(arg):
  3173. s = 0
  3174. while arg > 0:
  3175. s += arg
  3176. arg -= 1
  3177. return s
  3178. driver = JitDriver(greens = ['code'], reds = ['n', 'arg', 's'])
  3179. def main(code, n, arg):
  3180. s = 0
  3181. while n > 0:
  3182. driver.jit_merge_point(code=code, n=n, arg=arg, s=s)
  3183. if code == 0:
  3184. s += f(arg)
  3185. else:
  3186. s += f(1)
  3187. n -= 1
  3188. return s
  3189. res = self.meta_interp(main, [0, 10, 2], enable_opts='')
  3190. assert res == main(0, 10, 2)
  3191. self.check_resops(call_i=1)
  3192. res = self.meta_interp(main, [1, 10, 2], enable_opts='')
  3193. assert res == main(1, 10, 2)
  3194. self.check_resops(call_i=0)
  3195. def test_look_inside_iff_const_float(self):
  3196. @look_inside_iff(lambda arg: isconstant(arg))
  3197. def f(arg):
  3198. return arg + 0.5
  3199. driver = JitDriver(greens = [], reds = ['n', 'total'])
  3200. def main(n):
  3201. total = 0.0
  3202. while n > 0:
  3203. driver.jit_merge_point(n=n, total=total)
  3204. total = f(total)
  3205. n -= 1
  3206. return total
  3207. res = self.meta_interp(main, [10], enable_opts='')
  3208. assert res == 5.0
  3209. self.check_resops(call_f=1)
  3210. def test_look_inside_iff_virtual(self):
  3211. # There's no good reason for this to be look_inside_iff, but it's a test!
  3212. @look_inside_iff(lambda arg, n: isvirtual(arg))
  3213. def f(arg, n):
  3214. if n == 100:
  3215. for i in xrange(n):
  3216. n += i
  3217. return arg.x
  3218. class A(object):
  3219. def __init__(self, x):
  3220. self.x = x
  3221. driver = JitDriver(greens=['n'], reds=['i', 'a'])
  3222. def main(n):
  3223. i = 0
  3224. a = A(3)
  3225. while i < 20:
  3226. driver.jit_merge_point(i=i, n=n, a=a)
  3227. if n == 0:
  3228. i += f(a, n)
  3229. else:
  3230. i += f(A(2), n)
  3231. res = self.meta_interp(main, [0], enable_opts='')
  3232. assert res == main(0)
  3233. self.check_resops(call_i=1, getfield_gc_i=0)
  3234. res = self.meta_interp(main, [1], enable_opts='')
  3235. assert res == main(1)
  3236. self.check_resops(call_i=0, getfield_gc_i=0)
  3237. def test_isvirtual_call_assembler(self):
  3238. driver = JitDriver(greens = ['code'], reds = ['n', 's'])
  3239. @look_inside_iff(lambda t1, t2: isvirtual(t1))
  3240. def g(t1, t2):
  3241. return t1[0] == t2[0]
  3242. def create(n):
  3243. return (1, 2, n)
  3244. create._dont_inline_ = True
  3245. def f(code, n):
  3246. s = 0
  3247. while n > 0:
  3248. driver.can_enter_jit(code=code, n=n, s=s)
  3249. driver.jit_merge_point(code=code, n=n, s=s)
  3250. t = create(n)
  3251. if code:
  3252. f(0, 3)
  3253. s += t[2]
  3254. g(t, (1, 2, n))
  3255. n -= 1
  3256. return s
  3257. self.meta_interp(f, [1, 10], inline=True)
  3258. self.check_resops(call_i=0, call_may_force_i=0, call_assembler_i=2)
  3259. def test_reuse_elidable_result(self):
  3260. driver = JitDriver(reds=['n', 's'], greens = [])
  3261. def main(n):
  3262. s = 0
  3263. while n > 0:
  3264. driver.jit_merge_point(s=s, n=n)
  3265. s += len(str(n)) + len(str(n))
  3266. n -= 1
  3267. return s
  3268. res = self.meta_interp(main, [10])
  3269. assert res == main(10)
  3270. self.check_resops({'int_gt': 2, 'strlen': 2, 'guard_true': 2,
  3271. 'int_sub': 2, 'jump': 1, 'call_r': 2,
  3272. 'guard_no_exception': 2, 'int_add': 4})
  3273. def test_elidable_method(self):
  3274. py.test.skip("not supported so far: @elidable methods")
  3275. class A(object):
  3276. @elidable
  3277. def meth(self):
  3278. return 41
  3279. class B(A):
  3280. @elidable
  3281. def meth(self):
  3282. return 42
  3283. x = B()
  3284. def callme(x):
  3285. return x.meth()
  3286. def f():
  3287. callme(A())
  3288. return callme(x)
  3289. res = self.interp_operations(f, [])
  3290. assert res == 42
  3291. self.check_operations_history({'finish': 1})
  3292. def test_look_inside_iff_const_getarrayitem_gc_pure(self):
  3293. driver = JitDriver(greens=['unroll'], reds=['s', 'n'])
  3294. class A(object):
  3295. _immutable_fields_ = ["x[*]"]
  3296. def __init__(self, x):
  3297. self.x = [x]
  3298. @look_inside_iff(lambda x: isconstant(x))
  3299. def f(x):
  3300. i = 0
  3301. for c in x:
  3302. i += 1
  3303. return i
  3304. def main(unroll, n):
  3305. s = 0
  3306. while n > 0:
  3307. driver.jit_merge_point(s=s, n=n, unroll=unroll)
  3308. if unroll:
  3309. x = A("xx")
  3310. else:
  3311. x = A("x" * n)
  3312. s += f(x.x[0])
  3313. n -= 1
  3314. return s
  3315. res = self.meta_interp(main, [0, 10])
  3316. assert res == main(0, 10)
  3317. # 2 calls, one for f() and one for char_mul
  3318. self.check_resops(call_i=2, call_r=2)
  3319. res = self.meta_interp(main, [1, 10])
  3320. assert res == main(1, 10)
  3321. self.check_resops(call_i=0, call_r=0)
  3322. def test_setarrayitem_followed_by_arraycopy(self):
  3323. myjitdriver = JitDriver(greens = [], reds = ['n', 'sa', 'x', 'y'])
  3324. def f(n):
  3325. sa = 0
  3326. x = [1,2,n]
  3327. y = [1,2,3]
  3328. while n > 0:
  3329. myjitdriver.jit_merge_point(sa=sa, n=n, x=x, y=y)
  3330. y[0] = n
  3331. x[0:3] = y
  3332. sa += x[0]
  3333. n -= 1
  3334. return sa
  3335. res = self.meta_interp(f, [16])
  3336. assert res == f(16)
  3337. def test_ptr_eq(self):
  3338. myjitdriver = JitDriver(greens = [], reds = ["n", "x"])
  3339. class A(object):
  3340. def __init__(self, v):
  3341. self.v = v
  3342. def f(n, x):
  3343. while n > 0:
  3344. myjitdriver.jit_merge_point(n=n, x=x)
  3345. z = 0 / x
  3346. a1 = A("key")
  3347. a2 = A("\x00")
  3348. n -= [a1, a2][z].v is not a2.v
  3349. return n
  3350. res = self.meta_interp(f, [10, 1])
  3351. assert res == 0
  3352. def test_instance_ptr_eq(self):
  3353. myjitdriver = JitDriver(greens = [], reds = ["n", "i", "a1", "a2"])
  3354. class A(object):
  3355. pass
  3356. def f(n):
  3357. a1 = A()
  3358. a2 = A()
  3359. i = 0
  3360. while n > 0:
  3361. myjitdriver.jit_merge_point(n=n, i=i, a1=a1, a2=a2)
  3362. if n % 2:
  3363. a = a2
  3364. else:
  3365. a = a1
  3366. i += a is a1
  3367. n -= 1
  3368. return i
  3369. res = self.meta_interp(f, [10])
  3370. assert res == f(10)
  3371. def f(n):
  3372. a1 = A()
  3373. a2 = A()
  3374. i = 0
  3375. while n > 0:
  3376. myjitdriver.jit_merge_point(n=n, i=i, a1=a1, a2=a2)
  3377. if n % 2:
  3378. a = a2
  3379. else:
  3380. a = a1
  3381. if a is a2:
  3382. i += 1
  3383. n -= 1
  3384. return i
  3385. res = self.meta_interp(f, [10])
  3386. assert res == f(10)
  3387. def test_virtual_array_of_structs(self):
  3388. myjitdriver = JitDriver(greens = [], reds=["n", "d"])
  3389. def f(n):
  3390. d = None
  3391. while n > 0:
  3392. myjitdriver.jit_merge_point(n=n, d=d)
  3393. d = {"q": 1}
  3394. if n % 2:
  3395. d["k"] = n
  3396. else:
  3397. d["z"] = n
  3398. n -= len(d) - d["q"]
  3399. return n
  3400. res = self.meta_interp(f, [10])
  3401. assert res == 0
  3402. def test_virtual_dict_constant_keys(self):
  3403. myjitdriver = JitDriver(greens = [], reds = ["n"])
  3404. def g(d):
  3405. return d["key"] - 1
  3406. def f(n):
  3407. while n > 0:
  3408. myjitdriver.jit_merge_point(n=n)
  3409. x = {"key": n}
  3410. n = g(x)
  3411. del x["key"]
  3412. return n
  3413. res = self.meta_interp(f, [10])
  3414. assert res == 0
  3415. self.check_resops({'jump': 1, 'guard_true': 2, 'int_gt': 2,
  3416. 'int_sub': 2})
  3417. def test_virtual_opaque_ptr(self):
  3418. myjitdriver = JitDriver(greens = [], reds = ["n"])
  3419. erase, unerase = rerased.new_erasing_pair("x")
  3420. @look_inside_iff(lambda x: isvirtual(x))
  3421. def g(x):
  3422. return x[0]
  3423. def f(n):
  3424. while n > 0:
  3425. myjitdriver.jit_merge_point(n=n)
  3426. x = []
  3427. y = erase(x)
  3428. z = unerase(y)
  3429. z.append(1)
  3430. n -= g(z)
  3431. return n
  3432. res = self.meta_interp(f, [10])
  3433. assert res == 0
  3434. self.check_resops({'jump': 1, 'guard_true': 2, 'int_gt': 2,
  3435. 'int_sub': 2})
  3436. def test_virtual_opaque_dict(self):
  3437. myjitdriver = JitDriver(greens = [], reds = ["n"])
  3438. erase, unerase = rerased.new_erasing_pair("x")
  3439. @look_inside_iff(lambda x: isvirtual(x))
  3440. def g(x):
  3441. return x[0]["key"] - 1
  3442. def f(n):
  3443. while n > 0:
  3444. myjitdriver.jit_merge_point(n=n)
  3445. x = [{}]
  3446. x[0]["key"] = n
  3447. x[0]["other key"] = n
  3448. y = erase(x)
  3449. z = unerase(y)
  3450. n = g(x)
  3451. return n
  3452. res = self.meta_interp(f, [10])
  3453. assert res == 0
  3454. self.check_resops({'int_gt': 2, 'getfield_gc_i': 1, 'int_eq': 1,
  3455. 'guard_true': 2, 'int_sub': 2, 'jump': 1,
  3456. 'guard_false': 1})
  3457. def test_virtual_after_bridge(self):
  3458. myjitdriver = JitDriver(greens = [], reds = ["n"])
  3459. @look_inside_iff(lambda x: isvirtual(x))
  3460. def g(x):
  3461. return x[0]
  3462. def f(n):
  3463. while n > 0:
  3464. myjitdriver.jit_merge_point(n=n)
  3465. x = [1]
  3466. if n & 1: # bridge
  3467. n -= g(x)
  3468. else:
  3469. n -= g(x)
  3470. return n
  3471. res = self.meta_interp(f, [10])
  3472. assert res == 0
  3473. self.check_resops(call_i=0, call_may_force_i=0, new_array=0)
  3474. def test_convert_from_SmallFunctionSetPBCRepr_to_FunctionsPBCRepr(self):
  3475. f1 = lambda n: n+1
  3476. f2 = lambda n: n+2
  3477. f3 = lambda n: n+3
  3478. f4 = lambda n: n+4
  3479. f5 = lambda n: n+5
  3480. f6 = lambda n: n+6
  3481. f7 = lambda n: n+7
  3482. f8 = lambda n: n+8
  3483. def h(n, x):
  3484. return x(n)
  3485. h._dont_inline = True
  3486. def g(n, x):
  3487. return h(n, x)
  3488. g._dont_inline = True
  3489. def f(n):
  3490. n = g(n, f1)
  3491. n = g(n, f2)
  3492. n = h(n, f3)
  3493. n = h(n, f4)
  3494. n = h(n, f5)
  3495. n = h(n, f6)
  3496. n = h(n, f7)
  3497. n = h(n, f8)
  3498. return n
  3499. assert f(5) == 41
  3500. translationoptions = {'withsmallfuncsets': 3}
  3501. self.interp_operations(f, [5], translationoptions=translationoptions)
  3502. def test_annotation_gives_class_knowledge_to_tracer(self):
  3503. py.test.skip("disabled")
  3504. class Base(object):
  3505. pass
  3506. class A(Base):
  3507. def f(self):
  3508. return self.a
  3509. def g(self):
  3510. return self.a + 1
  3511. class B(Base):
  3512. def f(self):
  3513. return self.b
  3514. def g(self):
  3515. return self.b + 1
  3516. class C(B):
  3517. def f(self):
  3518. self.c += 1
  3519. return self.c
  3520. def g(self):
  3521. return self.c + 1
  3522. @dont_look_inside
  3523. def make(x):
  3524. if x > 0:
  3525. a = A()
  3526. a.a = x + 1
  3527. elif x < 0:
  3528. a = B()
  3529. a.b = -x
  3530. else:
  3531. a = C()
  3532. a.c = 10
  3533. return a
  3534. def f(x):
  3535. a = make(x)
  3536. if x > 0:
  3537. assert isinstance(a, A)
  3538. z = a.f()
  3539. elif x < 0:
  3540. assert isinstance(a, B)
  3541. z = a.f()
  3542. else:
  3543. assert isinstance(a, C)
  3544. z = a.f()
  3545. return z + a.g()
  3546. res1 = f(6)
  3547. res2 = self.interp_operations(f, [6])
  3548. assert res1 == res2
  3549. self.check_operations_history(guard_class=0, record_exact_class=1)
  3550. res1 = f(-6)
  3551. res2 = self.interp_operations(f, [-6])
  3552. assert res1 == res2
  3553. # cannot use record_exact_class here, because B has a subclass
  3554. self.check_operations_history(guard_class=1)
  3555. res1 = f(0)
  3556. res2 = self.interp_operations(f, [0])
  3557. assert res1 == res2
  3558. # here it works again
  3559. self.check_operations_history(guard_class=0, record_exact_class=1)
  3560. def test_give_class_knowledge_to_tracer_explicitly(self):
  3561. class Base(object):
  3562. def f(self):
  3563. raise NotImplementedError
  3564. def g(self):
  3565. raise NotImplementedError
  3566. class A(Base):
  3567. def f(self):
  3568. return self.a
  3569. def g(self):
  3570. return self.a + 1
  3571. class B(Base):
  3572. def f(self):
  3573. return self.b
  3574. def g(self):
  3575. return self.b + 1
  3576. class C(B):
  3577. def f(self):
  3578. self.c += 1
  3579. return self.c
  3580. def g(self):
  3581. return self.c + 1
  3582. @dont_look_inside
  3583. def make(x):
  3584. if x > 0:
  3585. a = A()
  3586. a.a = x + 1
  3587. elif x < 0:
  3588. a = B()
  3589. a.b = -x
  3590. else:
  3591. a = C()
  3592. a.c = 10
  3593. return a
  3594. def f(x):
  3595. a = make(x)
  3596. if x > 0:
  3597. record_exact_class(a, A)
  3598. z = a.f()
  3599. elif x < 0:
  3600. record_exact_class(a, B)
  3601. z = a.f()
  3602. else:
  3603. record_exact_class(a, C)
  3604. z = a.f()
  3605. return z + a.g()
  3606. res1 = f(6)
  3607. res2 = self.interp_operations(f, [6])
  3608. assert res1 == res2
  3609. self.check_operations_history(guard_class=0, record_exact_class=1)
  3610. res1 = f(-6)
  3611. res2 = self.interp_operations(f, [-6])
  3612. assert res1 == res2
  3613. self.check_operations_history(guard_class=0, record_exact_class=1)
  3614. res1 = f(0)
  3615. res2 = self.interp_operations(f, [0])
  3616. assert res1 == res2
  3617. # here it works again
  3618. self.check_operations_history(guard_class=0, record_exact_class=1)
  3619. def test_generator(self):
  3620. def g(n):
  3621. yield n+1
  3622. yield n+2
  3623. yield n+3
  3624. def f(n):
  3625. gen = g(n)
  3626. return gen.next() * gen.next() * gen.next()
  3627. res = self.interp_operations(f, [10])
  3628. assert res == 11 * 12 * 13
  3629. self.check_operations_history(int_add=3, int_mul=2)
  3630. def test_setinteriorfield(self):
  3631. A = lltype.GcArray(lltype.Struct('S', ('x', lltype.Signed)))
  3632. a = lltype.malloc(A, 5, immortal=True)
  3633. def g(n):
  3634. a[n].x = n + 2
  3635. return a[n].x
  3636. res = self.interp_operations(g, [1])
  3637. assert res == 3
  3638. def test_float_bytes(self):
  3639. from rpython.rlib.rfloat import isnan
  3640. def f(n):
  3641. ll = float2longlong(n)
  3642. return longlong2float(ll)
  3643. for x in [2.5, float("nan"), -2.5, float("inf")]:
  3644. # There are tests elsewhere to verify the correctness of this.
  3645. res = self.interp_operations(f, [x])
  3646. assert res == x or isnan(x) and isnan(res)
  3647. class TestLLtype(BaseLLtypeTests, LLJitMixin):
  3648. def test_tagged(self):
  3649. py.test.skip("tagged unsupported")
  3650. from rpython.rlib.objectmodel import UnboxedValue
  3651. class Base(object):
  3652. __slots__ = ()
  3653. class Int(UnboxedValue, Base):
  3654. __slots__ = ["a"]
  3655. def is_pos(self):
  3656. return self.a > 0
  3657. def dec(self):
  3658. try:
  3659. return Int(self.a - 1)
  3660. except OverflowError:
  3661. raise
  3662. class Float(Base):
  3663. def __init__(self, a):
  3664. self.a = a
  3665. def is_pos(self):
  3666. return self.a > 0
  3667. def dec(self):
  3668. return Float(self.a - 1)
  3669. driver = JitDriver(greens=['pc', 's'], reds=['o'])
  3670. def main(fl, n, s):
  3671. if s:
  3672. s = "--j"
  3673. else:
  3674. s = "---j"
  3675. if fl:
  3676. o = Float(float(n))
  3677. else:
  3678. o = Int(n)
  3679. pc = 0
  3680. while True:
  3681. driver.jit_merge_point(s=s, pc=pc, o=o)
  3682. c = s[pc]
  3683. if c == "j":
  3684. driver.can_enter_jit(s=s, pc=pc, o=o)
  3685. if o.is_pos():
  3686. pc = 0
  3687. continue
  3688. else:
  3689. break
  3690. elif c == "-":
  3691. o = o.dec()
  3692. pc += 1
  3693. return pc
  3694. topt = {'taggedpointers': True}
  3695. res = self.meta_interp(main, [False, 100, True],
  3696. translationoptions=topt)
  3697. def test_rerased(self):
  3698. eraseX, uneraseX = rerased.new_erasing_pair("X")
  3699. #
  3700. class X:
  3701. def __init__(self, a, b):
  3702. self.a = a
  3703. self.b = b
  3704. #
  3705. def f(i, j):
  3706. # 'j' should be 0 or 1, not other values
  3707. if j > 0:
  3708. e = eraseX(X(i, j))
  3709. else:
  3710. try:
  3711. e = rerased.erase_int(i)
  3712. except OverflowError:
  3713. return -42
  3714. if j & 1:
  3715. x = uneraseX(e)
  3716. return x.a - x.b
  3717. else:
  3718. return rerased.unerase_int(e)
  3719. #
  3720. topt = {'taggedpointers': True}
  3721. x = self.interp_operations(f, [-128, 0], translationoptions=topt)
  3722. assert x == -128
  3723. bigint = sys.maxint//2 + 1
  3724. x = self.interp_operations(f, [bigint, 0], translationoptions=topt)
  3725. assert x == -42
  3726. x = self.interp_operations(f, [1000, 1], translationoptions=topt)
  3727. assert x == 999
  3728. def test_retracing_bridge_from_interpreter_to_finnish(self):
  3729. myjitdriver = JitDriver(greens = [], reds = ['n', 'i', 'sa'])
  3730. def f(n):
  3731. sa = i = 0
  3732. while i < n:
  3733. myjitdriver.jit_merge_point(n=n, i=i, sa=sa)
  3734. n = hint(n, promote=True)
  3735. sa += 2*n
  3736. i += 1
  3737. return sa
  3738. def g(n):
  3739. return f(n) + f(n) + f(n) + f(n) + f(10*n) + f(11*n)
  3740. res = self.meta_interp(g, [1], repeat=3)
  3741. assert res == g(1)
  3742. #self.check_jitcell_token_count(1)
  3743. self.check_jitcell_token_count(2)
  3744. # XXX A bridge from the interpreter to a finish is first
  3745. # constructed for n=1. It is later replaced with a trace for
  3746. # the case n=10 which is extended with a retrace for n=11 and
  3747. # finnaly a new bridge to finnish is again traced and created
  3748. # for the case n=1. We were not able to reuse the orignial n=1
  3749. # bridge as a preamble since it does not start with a
  3750. # label. The alternative would be to have all such bridges
  3751. # start with labels. I dont know which is better...
  3752. def test_ll_arraycopy(self):
  3753. A = lltype.GcArray(lltype.Char)
  3754. a = lltype.malloc(A, 10)
  3755. for i in range(10): a[i] = chr(i)
  3756. b = lltype.malloc(A, 10)
  3757. #
  3758. def f(c, d, e):
  3759. rgc.ll_arraycopy(a, b, c, d, e)
  3760. return 42
  3761. self.interp_operations(f, [1, 2, 3])
  3762. self.check_operations_history(call_n=1, guard_no_exception=0)
  3763. def test_weakref(self):
  3764. import weakref
  3765. class A(object):
  3766. def __init__(self, x):
  3767. self.x = x
  3768. def f(i):
  3769. a = A(i)
  3770. w = weakref.ref(a)
  3771. return w().x + a.x
  3772. assert self.interp_operations(f, [3]) == 6
  3773. def test_gc_add_memory_pressure(self):
  3774. def f():
  3775. rgc.add_memory_pressure(1234)
  3776. return 3
  3777. self.interp_operations(f, [])
  3778. def test_external_call(self):
  3779. from rpython.rlib import rgil
  3780. TIME_T = lltype.Signed
  3781. # ^^^ some 32-bit platforms have a 64-bit rffi.TIME_T, but we
  3782. # don't want that here; we just want always a Signed value
  3783. T = rffi.CArrayPtr(TIME_T)
  3784. external = rffi.llexternal("time", [T], TIME_T)
  3785. class Oups(Exception):
  3786. pass
  3787. class State:
  3788. pass
  3789. state = State()
  3790. def after():
  3791. if we_are_jitted():
  3792. raise Oups
  3793. state.l.append("after")
  3794. def f():
  3795. state.l = []
  3796. rgil.invoke_after_thread_switch(after)
  3797. external(lltype.nullptr(T.TO))
  3798. return len(state.l)
  3799. res = self.interp_operations(f, [])
  3800. assert res == 1
  3801. res = self.interp_operations(f, [])
  3802. assert res == 1
  3803. self.check_operations_history(call_release_gil_i=1, call_may_force_i=0)
  3804. def test_unescaped_write_zero(self):
  3805. class A:
  3806. pass
  3807. def g():
  3808. return A()
  3809. @dont_look_inside
  3810. def escape():
  3811. print "hi!"
  3812. def f(n):
  3813. a = g()
  3814. a.x = n
  3815. escape()
  3816. a.x = 0
  3817. escape()
  3818. return a.x
  3819. res = self.interp_operations(f, [42])
  3820. assert res == 0
  3821. def test_conditions_without_guards(self):
  3822. def f(n):
  3823. if (n == 1) | (n == 3) | (n == 17):
  3824. return 42
  3825. return 5
  3826. res = self.interp_operations(f, [17])
  3827. assert res == 42
  3828. self.check_operations_history(guard_true=1, guard_false=0)
  3829. def test_not_in_trace(self):
  3830. class X:
  3831. n = 0
  3832. def g(x):
  3833. if we_are_jitted():
  3834. raise NotImplementedError
  3835. x.n += 1
  3836. g.oopspec = 'jit.not_in_trace()'
  3837. jitdriver = JitDriver(greens=[], reds=['n', 'token', 'x'])
  3838. def f(n):
  3839. token = 0
  3840. x = X()
  3841. while n >= 0:
  3842. jitdriver.jit_merge_point(n=n, x=x, token=token)
  3843. if not we_are_jitted():
  3844. token += 1
  3845. g(x)
  3846. n -= 1
  3847. return x.n + token * 1000
  3848. res = self.meta_interp(f, [10])
  3849. assert res == 2003 # two runs before jitting; then one tracing run
  3850. self.check_resops(int_add=0, call_i=0, call_may_force_i=0,
  3851. call_r=0, call_may_force_r=0, call_f=0,
  3852. call_may_force_f=0)
  3853. def test_not_in_trace_exception(self):
  3854. def g():
  3855. if we_are_jitted():
  3856. raise NotImplementedError
  3857. raise ValueError
  3858. g.oopspec = 'jit.not_in_trace()'
  3859. jitdriver = JitDriver(greens=[], reds=['n'])
  3860. def f(n):
  3861. while n >= 0:
  3862. jitdriver.jit_merge_point(n=n)
  3863. try:
  3864. g()
  3865. except ValueError:
  3866. n -= 1
  3867. return 42
  3868. res = self.meta_interp(f, [10])
  3869. assert res == 42
  3870. self.check_aborted_count(3)
  3871. def test_not_in_trace_blackhole(self):
  3872. class X:
  3873. seen = 0
  3874. def g(x):
  3875. if we_are_jitted():
  3876. raise NotImplementedError
  3877. x.seen = 42
  3878. g.oopspec = 'jit.not_in_trace()'
  3879. jitdriver = JitDriver(greens=[], reds=['n'])
  3880. def f(n):
  3881. while n >= 0:
  3882. jitdriver.jit_merge_point(n=n)
  3883. n -= 1
  3884. x = X()
  3885. g(x)
  3886. return x.seen
  3887. res = self.meta_interp(f, [10])
  3888. assert res == 42
  3889. def test_int_force_ge_zero(self):
  3890. def f(n):
  3891. return int_force_ge_zero(n)
  3892. res = self.interp_operations(f, [42])
  3893. assert res == 42
  3894. res = self.interp_operations(f, [-42])
  3895. assert res == 0
  3896. def test_cmp_fastpaths(self):
  3897. class Z: pass
  3898. def make_int(cmp):
  3899. def f(x):
  3900. if cmp == 'eq':
  3901. return x == x and x == x
  3902. if cmp == 'ne':
  3903. return x != x or x != x
  3904. if cmp == 'lt':
  3905. return x < x or x != x
  3906. if cmp == 'le':
  3907. return x <= x and x <= x
  3908. if cmp == 'gt':
  3909. return x > x or x > x
  3910. if cmp == 'ge':
  3911. return x >= x and x >= x
  3912. assert 0
  3913. return f
  3914. def make_str(cmp):
  3915. def f(x):
  3916. x = str(x)
  3917. if cmp == 'eq':
  3918. return x is x or x is x
  3919. if cmp == 'ne':
  3920. return x is not x and x is not x
  3921. assert 0
  3922. return f
  3923. def make_object(cmp):
  3924. def f(x):
  3925. y = Z()
  3926. y.x = x
  3927. x = y
  3928. if cmp == 'eq':
  3929. return x is x
  3930. if cmp == 'ne':
  3931. return x is not x
  3932. assert 0
  3933. return f
  3934. for cmp in 'eq ne lt le gt ge'.split():
  3935. f = make_int(cmp)
  3936. res = self.interp_operations(f, [42])
  3937. assert res == f(42)
  3938. opname = "int_%s" % cmp
  3939. self.check_operations_history(**{opname: 0})
  3940. for cmp in 'eq ne'.split():
  3941. f = make_str(cmp)
  3942. res = self.interp_operations(f, [42])
  3943. assert res == f(42)
  3944. opname = "ptr_%s" % cmp
  3945. self.check_operations_history(**{opname: 0})
  3946. f = make_object(cmp)
  3947. res = self.interp_operations(f, [42])
  3948. assert res == f(42)
  3949. opname = "instance_ptr_%s" % cmp
  3950. self.check_operations_history(**{opname: 0})
  3951. def test_compile_framework_9(self):
  3952. class X(object):
  3953. def __init__(self, x=0):
  3954. self.x = x
  3955. next = None
  3956. class CheckError(Exception):
  3957. pass
  3958. def check(flag):
  3959. if not flag:
  3960. raise CheckError
  3961. def before(n, x):
  3962. return n, x, None, None, None, None, None, None, None, None, [X(123)], None
  3963. def f(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s):
  3964. if n < 1900:
  3965. check(l[0].x == 123)
  3966. num = 512 + (n & 7)
  3967. l = [None] * num
  3968. l[0] = X(123)
  3969. l[1] = X(n)
  3970. l[2] = X(n+10)
  3971. l[3] = X(n+20)
  3972. l[4] = X(n+30)
  3973. l[5] = X(n+40)
  3974. l[6] = X(n+50)
  3975. l[7] = X(n+60)
  3976. l[num-8] = X(n+70)
  3977. l[num-9] = X(n+80)
  3978. l[num-10] = X(n+90)
  3979. l[num-11] = X(n+100)
  3980. l[-12] = X(n+110)
  3981. l[-13] = X(n+120)
  3982. l[-14] = X(n+130)
  3983. l[-15] = X(n+140)
  3984. if n < 1800:
  3985. num = 512 + (n & 7)
  3986. check(len(l) == num)
  3987. check(l[0].x == 123)
  3988. check(l[1].x == n)
  3989. check(l[2].x == n+10)
  3990. check(l[3].x == n+20)
  3991. check(l[4].x == n+30)
  3992. check(l[5].x == n+40)
  3993. check(l[6].x == n+50)
  3994. check(l[7].x == n+60)
  3995. check(l[num-8].x == n+70)
  3996. check(l[num-9].x == n+80)
  3997. check(l[num-10].x == n+90)
  3998. check(l[num-11].x == n+100)
  3999. check(l[-12].x == n+110)
  4000. check(l[-13].x == n+120)
  4001. check(l[-14].x == n+130)
  4002. check(l[-15].x == n+140)
  4003. n -= x.foo
  4004. return n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s
  4005. def after(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s):
  4006. check(len(l) >= 512)
  4007. check(l[0].x == 123)
  4008. check(l[1].x == 2)
  4009. check(l[2].x == 12)
  4010. check(l[3].x == 22)
  4011. check(l[4].x == 32)
  4012. check(l[5].x == 42)
  4013. check(l[6].x == 52)
  4014. check(l[7].x == 62)
  4015. check(l[-8].x == 72)
  4016. check(l[-9].x == 82)
  4017. check(l[-10].x == 92)
  4018. check(l[-11].x == 102)
  4019. check(l[-12].x == 112)
  4020. check(l[-13].x == 122)
  4021. check(l[-14].x == 132)
  4022. check(l[-15].x == 142)
  4023. def allfuncs(num, n):
  4024. x = X()
  4025. x.foo = 2
  4026. main_allfuncs(num, n, x)
  4027. x.foo = 5
  4028. return x
  4029. def main_allfuncs(num, n, x):
  4030. n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s = before(n, x)
  4031. while n > 0:
  4032. myjitdriver.can_enter_jit(num=num, n=n, x=x, x0=x0, x1=x1,
  4033. x2=x2, x3=x3, x4=x4, x5=x5, x6=x6, x7=x7, l=l, s=s)
  4034. myjitdriver.jit_merge_point(num=num, n=n, x=x, x0=x0, x1=x1,
  4035. x2=x2, x3=x3, x4=x4, x5=x5, x6=x6, x7=x7, l=l, s=s)
  4036. n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s = f(
  4037. n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s)
  4038. after(n, x, x0, x1, x2, x3, x4, x5, x6, x7, l, s)
  4039. myjitdriver = JitDriver(greens = ['num'],
  4040. reds = ['n', 'x', 'x0', 'x1', 'x2', 'x3', 'x4',
  4041. 'x5', 'x6', 'x7', 'l', 's'])
  4042. self.meta_interp(allfuncs, [9, 2000])
  4043. def test_unichar_ord_is_never_signed_on_64bit(self):
  4044. import sys
  4045. if sys.maxunicode == 0xffff:
  4046. py.test.skip("test for 32-bit unicodes")
  4047. def f(x):
  4048. return ord(rffi.cast(lltype.UniChar, x))
  4049. res = self.interp_operations(f, [-1])
  4050. if sys.maxint == 2147483647:
  4051. assert res == -1
  4052. else:
  4053. assert res == 4294967295
  4054. def test_issue2200_recursion(self):
  4055. # Reproduces issue #2200. This test contains no recursion,
  4056. # but due to an unlikely combination of factors it ends up
  4057. # creating an RPython-level recursion, one per loop iteration.
  4058. # The recursion is: blackhole interp from the failing guard ->
  4059. # does the call to enter() as a normal call -> enter() runs
  4060. # can_enter_jit() as if we're interpreted -> we enter the JIT
  4061. # again from the start of the loop -> the guard fails again
  4062. # during the next iteration -> blackhole interp. All arrows
  4063. # in the previous sentence are one or more levels of RPython
  4064. # function calls.
  4065. driver = JitDriver(greens=[], reds=["i"])
  4066. def enter(i):
  4067. driver.can_enter_jit(i=i)
  4068. def f():
  4069. set_param(None, 'trace_eagerness', 999999)
  4070. i = 0
  4071. while True:
  4072. driver.jit_merge_point(i=i)
  4073. i += 1
  4074. if i >= 300:
  4075. return i
  4076. promote(i + 1) # a failing guard
  4077. enter(i)
  4078. self.meta_interp(f, [])
  4079. def test_issue2335_recursion(self):
  4080. # Reproduces issue #2335: same as issue #2200, but the workaround
  4081. # in c4c54cb69aba was not enough.
  4082. driver = JitDriver(greens=["level"], reds=["i"])
  4083. def enter(level, i):
  4084. if level == 0:
  4085. f(1) # recursive call
  4086. driver.can_enter_jit(level=level, i=i)
  4087. def f(level):
  4088. i = 0 if level == 0 else 298
  4089. while True:
  4090. driver.jit_merge_point(level=level, i=i)
  4091. i += 1
  4092. if i >= 300:
  4093. return i
  4094. promote(i + 1) # a failing guard
  4095. enter(level, i)
  4096. def main():
  4097. set_param(None, 'trace_eagerness', 999999)
  4098. f(0)
  4099. self.meta_interp(main, [])
  4100. def test_pending_setarrayitem_with_indirect_constant_index(self):
  4101. driver = JitDriver(greens=[], reds='auto')
  4102. class X:
  4103. pass
  4104. def f():
  4105. xs = [None]
  4106. i = 0
  4107. while i < 17:
  4108. driver.jit_merge_point()
  4109. xs[noConst(0)] = X()
  4110. if i & 5:
  4111. pass
  4112. i += 1
  4113. return i
  4114. self.meta_interp(f, [])
  4115. def test_round_trip_raw_pointer(self):
  4116. # The goal of this test to to get a raw pointer op into the short preamble
  4117. # so we can check that the proper guards are generated
  4118. # In this case, the resulting short preamble contains
  4119. #
  4120. # i1 = getfield_gc_i(p0, descr=inst__ptr)
  4121. # i2 = int_eq(i1, 0)
  4122. # guard_false(i2)
  4123. #
  4124. # as opposed to what the JIT used to produce
  4125. #
  4126. # i1 = getfield_gc_i(p0, descr=inst__ptr)
  4127. # guard_nonnull(i1)
  4128. #
  4129. # Which will probably generate correct assembly, but the optimization
  4130. # pipline expects guard_nonnull arguments to be pointer ops and may crash
  4131. # and may crash on other input types.
  4132. driver = JitDriver(greens=[], reds=['i', 'val'])
  4133. class Box(object):
  4134. _ptr = lltype.nullptr(rffi.CCHARP.TO)
  4135. def new_int_buffer(value):
  4136. data = lltype.malloc(rffi.CCHARP.TO, rffi.sizeof(rffi.INT), flavor='raw')
  4137. rffi.cast(rffi.INTP, data)[0] = rffi.cast(rffi.INT, value)
  4138. return data
  4139. def read_int_buffer(buf):
  4140. return rffi.cast(rffi.INTP, buf)[0]
  4141. def f():
  4142. i = 0
  4143. val = Box()
  4144. val._ptr = new_int_buffer(1)
  4145. set_param(None, 'retrace_limit', -1)
  4146. while i < 100:
  4147. driver.jit_merge_point(i=i, val=val)
  4148. driver.can_enter_jit(i=i, val=val)
  4149. # Just to produce a side exit
  4150. if i & 0b100:
  4151. i += 1
  4152. i += int(read_int_buffer(val._ptr))
  4153. lltype.free(val._ptr, flavor='raw')
  4154. val._ptr = new_int_buffer(1)
  4155. lltype.free(val._ptr, flavor='raw')
  4156. self.meta_interp(f, [])
  4157. self.check_resops(guard_nonnull=0)