PageRenderTime 67ms CodeModel.GetById 25ms 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

Large files files are truncated, but you can click here to view the full file

  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 ineff

Large files files are truncated, but you can click here to view the full file