PageRenderTime 72ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/pypy/jit/metainterp/test/test_ajit.py

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