PageRenderTime 62ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/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

Large files files are truncated, but you can click here to view the full 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',

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