PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/rpython/jit/backend/llsupport/test/test_rewrite.py

https://bitbucket.org/pypy/pypy/
Python | 1431 lines | 1398 code | 18 blank | 15 comment | 14 complexity | 4099a8a8ffdf7a27f48dd6c6b3b5259c MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0

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

  1. import py
  2. from rpython.jit.backend.llsupport.descr import get_size_descr,\
  3. get_field_descr, get_array_descr, ArrayDescr, FieldDescr,\
  4. SizeDescr, get_interiorfield_descr
  5. from rpython.jit.backend.llsupport.gc import GcLLDescr_boehm,\
  6. GcLLDescr_framework
  7. from rpython.jit.backend.llsupport import jitframe
  8. from rpython.jit.metainterp.gc import get_description
  9. from rpython.jit.tool.oparser import parse
  10. from rpython.jit.metainterp.optimizeopt.util import equaloplists
  11. from rpython.jit.metainterp.history import JitCellToken, FLOAT
  12. from rpython.jit.metainterp.history import AbstractFailDescr
  13. from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
  14. from rpython.rtyper import rclass
  15. from rpython.jit.backend.llsupport.symbolic import (WORD,
  16. get_array_token)
  17. class Evaluator(object):
  18. def __init__(self, scope):
  19. self.scope = scope
  20. def __getitem__(self, key):
  21. return eval(key, self.scope)
  22. class FakeLoopToken(object):
  23. pass
  24. o_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
  25. class RewriteTests(object):
  26. def check_rewrite(self, frm_operations, to_operations, **namespace):
  27. def setfield(baseptr, newvalue, descr):
  28. assert isinstance(baseptr, str)
  29. assert isinstance(newvalue, (str, int))
  30. assert not isinstance(descr, (str, int))
  31. return 'gc_store(%s, %d, %s, %d)' % (baseptr, descr.offset,
  32. newvalue, descr.field_size)
  33. def zero_array(baseptr, start, length, descr_name, descr):
  34. assert isinstance(baseptr, str)
  35. assert isinstance(start, (str, int))
  36. assert isinstance(length, (str, int))
  37. assert isinstance(descr_name, str)
  38. assert not isinstance(descr, (str,int))
  39. itemsize = descr.itemsize
  40. start = start * itemsize
  41. length_scale = 1
  42. if isinstance(length, str):
  43. length_scale = itemsize
  44. else:
  45. length = length * itemsize
  46. return 'zero_array(%s, %s, %s, 1, %d, descr=%s)' % \
  47. (baseptr, start, length, length_scale, descr_name)
  48. def setarrayitem(baseptr, index, newvalue, descr):
  49. assert isinstance(baseptr, str)
  50. assert isinstance(index, (str, int))
  51. assert isinstance(newvalue, (str, int))
  52. assert not isinstance(descr, (str, int))
  53. if isinstance(index, int):
  54. offset = descr.basesize + index * descr.itemsize
  55. return 'gc_store(%s, %d, %s, %d)' % (baseptr, offset,
  56. newvalue, descr.itemsize)
  57. else:
  58. return 'gc_store_indexed(%s, %s, %s, %d, %d, %s)' % (
  59. baseptr, index, newvalue,
  60. descr.itemsize, descr.basesize, descr.itemsize)
  61. #
  62. WORD = globals()['WORD']
  63. S = lltype.GcStruct('S', ('x', lltype.Signed),
  64. ('y', lltype.Signed))
  65. sdescr = get_size_descr(self.gc_ll_descr, S)
  66. sdescr.tid = 1234
  67. #
  68. T = lltype.GcStruct('T', ('y', lltype.Signed),
  69. ('z', lltype.Ptr(S)),
  70. ('t', lltype.Signed))
  71. tdescr = get_size_descr(self.gc_ll_descr, T)
  72. tdescr.tid = 5678
  73. tzdescr = get_field_descr(self.gc_ll_descr, T, 'z')
  74. myT = lltype.cast_opaque_ptr(llmemory.GCREF,
  75. lltype.malloc(T, zero=True))
  76. self.myT = myT
  77. #
  78. A = lltype.GcArray(lltype.Signed)
  79. adescr = get_array_descr(self.gc_ll_descr, A)
  80. adescr.tid = 4321
  81. alendescr = adescr.lendescr
  82. #
  83. B = lltype.GcArray(lltype.Char)
  84. bdescr = get_array_descr(self.gc_ll_descr, B)
  85. bdescr.tid = 8765
  86. blendescr = bdescr.lendescr
  87. #
  88. C = lltype.GcArray(lltype.Ptr(S))
  89. cdescr = get_array_descr(self.gc_ll_descr, C)
  90. cdescr.tid = 8111
  91. clendescr = cdescr.lendescr
  92. #
  93. S1 = lltype.GcStruct('S1')
  94. S1I = lltype.GcArray(('x', lltype.Ptr(S1)),
  95. ('y', lltype.Ptr(S1)),
  96. ('z', lltype.Ptr(S1)))
  97. itzdescr = get_interiorfield_descr(self.gc_ll_descr, S1I, 'z')
  98. itydescr = get_interiorfield_descr(self.gc_ll_descr, S1I, 'y')
  99. itxdescr = get_interiorfield_descr(self.gc_ll_descr, S1I, 'x')
  100. S2I = lltype.GcArray(('x', lltype.Ptr(S1)),
  101. ('y', lltype.Ptr(S1)),
  102. ('z', lltype.Ptr(S1)),
  103. ('t', lltype.Ptr(S1))) # size is a power of two
  104. s2i_item_size_in_bits = (4 if WORD == 4 else 5)
  105. ity2descr = get_interiorfield_descr(self.gc_ll_descr, S2I, 'y')
  106. R1 = lltype.GcStruct('R', ('x', lltype.Signed),
  107. ('y', lltype.Float),
  108. ('z', lltype.Ptr(S1)))
  109. xdescr = get_field_descr(self.gc_ll_descr, R1, 'x')
  110. ydescr = get_field_descr(self.gc_ll_descr, R1, 'y')
  111. zdescr = get_field_descr(self.gc_ll_descr, R1, 'z')
  112. myR1 = lltype.cast_opaque_ptr(llmemory.GCREF,
  113. lltype.malloc(R1, zero=True))
  114. myR1b = lltype.cast_opaque_ptr(llmemory.GCREF,
  115. lltype.malloc(R1, zero=True))
  116. self.myR1 = myR1
  117. self.myR1b = myR1b
  118. #
  119. E = lltype.GcStruct('Empty')
  120. edescr = get_size_descr(self.gc_ll_descr, E)
  121. edescr.tid = 9000
  122. #
  123. vtable_descr = self.gc_ll_descr.fielddescr_vtable
  124. O = lltype.GcStruct('O', ('parent', rclass.OBJECT),
  125. ('x', lltype.Signed))
  126. o_descr = self.cpu.sizeof(O, True)
  127. o_vtable = globals()['o_vtable']
  128. #
  129. tiddescr = self.gc_ll_descr.fielddescr_tid
  130. wbdescr = self.gc_ll_descr.write_barrier_descr
  131. #
  132. F = lltype.GcArray(lltype.Float)
  133. fdescr = get_array_descr(self.gc_ll_descr, F)
  134. SF = lltype.GcArray(lltype.SingleFloat)
  135. sfdescr = get_array_descr(self.gc_ll_descr, SF)
  136. RAW_SF = lltype.Array(lltype.SingleFloat)
  137. raw_sfdescr = get_array_descr(self.gc_ll_descr, RAW_SF)
  138. #
  139. strdescr = self.gc_ll_descr.str_descr
  140. unicodedescr = self.gc_ll_descr.unicode_descr
  141. strlendescr = strdescr.lendescr
  142. unicodelendescr = unicodedescr.lendescr
  143. strhashdescr = self.gc_ll_descr.str_hash_descr
  144. unicodehashdescr = self.gc_ll_descr.unicode_hash_descr
  145. casmdescr = JitCellToken()
  146. clt = FakeLoopToken()
  147. clt._ll_initial_locs = [0, 8]
  148. frame_info = lltype.malloc(jitframe.JITFRAMEINFO, flavor='raw')
  149. clt.frame_info = frame_info
  150. frame_info.jfi_frame_depth = 13
  151. frame_info.jfi_frame_size = 255
  152. framedescrs = self.gc_ll_descr.getframedescrs(self.cpu)
  153. framelendescr = framedescrs.arraydescr.lendescr
  154. jfi_frame_depth = framedescrs.jfi_frame_depth
  155. jfi_frame_size = framedescrs.jfi_frame_size
  156. jf_frame_info = framedescrs.jf_frame_info
  157. jf_savedata = framedescrs.jf_savedata
  158. jf_force_descr = framedescrs.jf_force_descr
  159. jf_descr = framedescrs.jf_descr
  160. jf_guard_exc = framedescrs.jf_guard_exc
  161. jf_forward = framedescrs.jf_forward
  162. jf_extra_stack_depth = framedescrs.jf_extra_stack_depth
  163. signedframedescr = self.cpu.signedframedescr
  164. floatframedescr = self.cpu.floatframedescr
  165. casmdescr.compiled_loop_token = clt
  166. #
  167. guarddescr = AbstractFailDescr()
  168. #
  169. namespace.update(locals())
  170. #
  171. for funcname in self.gc_ll_descr._generated_functions:
  172. namespace[funcname] = self.gc_ll_descr.get_malloc_fn(funcname)
  173. namespace[funcname + '_descr'] = getattr(self.gc_ll_descr,
  174. '%s_descr' % funcname)
  175. #
  176. ops = parse(frm_operations, namespace=namespace)
  177. expected = parse(to_operations % Evaluator(namespace),
  178. namespace=namespace)
  179. self.gcrefs = []
  180. operations = self.gc_ll_descr.rewrite_assembler(self.cpu,
  181. ops.operations,
  182. self.gcrefs)
  183. remap = {}
  184. for a, b in zip(ops.inputargs, expected.inputargs):
  185. remap[b] = a
  186. equaloplists(operations, expected.operations, remap=remap)
  187. lltype.free(frame_info, flavor='raw')
  188. class FakeTracker(object):
  189. pass
  190. class BaseFakeCPU(object):
  191. JITFRAME_FIXED_SIZE = 0
  192. load_constant_offset = True
  193. load_supported_factors = (1,2,4,8)
  194. translate_support_code = None
  195. def __init__(self):
  196. self.tracker = FakeTracker()
  197. self._cache = {}
  198. self.signedframedescr = ArrayDescr(3, 8, FieldDescr('len', 0, 0, 0), 0)
  199. self.floatframedescr = ArrayDescr(5, 8, FieldDescr('len', 0, 0, 0), 0)
  200. def getarraydescr_for_frame(self, tp):
  201. if tp == FLOAT:
  202. return self.floatframedescr
  203. return self.signedframedescr
  204. def unpack_arraydescr_size(self, d):
  205. return 0, d.itemsize, 0
  206. def unpack_fielddescr(self, d):
  207. return d.offset
  208. def arraydescrof(self, ARRAY):
  209. try:
  210. return self._cache[ARRAY]
  211. except KeyError:
  212. r = ArrayDescr(1, 2, FieldDescr('len', 0, 0, 0), 0)
  213. self._cache[ARRAY] = r
  214. return r
  215. def fielddescrof(self, STRUCT, fname):
  216. key = (STRUCT, fname)
  217. try:
  218. return self._cache[key]
  219. except KeyError:
  220. r = FieldDescr(fname, 1, 1, 1)
  221. self._cache[key] = r
  222. return r
  223. class TestBoehm(RewriteTests):
  224. def setup_method(self, meth):
  225. class FakeCPU(BaseFakeCPU):
  226. def sizeof(self, STRUCT, is_object):
  227. assert is_object
  228. return SizeDescr(102, gc_fielddescrs=[],
  229. vtable=o_vtable)
  230. self.cpu = FakeCPU()
  231. self.gc_ll_descr = GcLLDescr_boehm(None, None, None)
  232. def test_new(self):
  233. self.check_rewrite("""
  234. []
  235. p0 = new(descr=sdescr)
  236. jump()
  237. """, """
  238. [p1]
  239. p0 = call_r(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
  240. descr=malloc_fixedsize_descr)
  241. check_memory_error(p0)
  242. jump()
  243. """)
  244. def test_no_collapsing(self):
  245. self.check_rewrite("""
  246. []
  247. p0 = new(descr=sdescr)
  248. p1 = new(descr=sdescr)
  249. jump()
  250. """, """
  251. []
  252. p0 = call_r(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
  253. descr=malloc_fixedsize_descr)
  254. check_memory_error(p0)
  255. p1 = call_r(ConstClass(malloc_fixedsize), %(sdescr.size)d,\
  256. descr=malloc_fixedsize_descr)
  257. check_memory_error(p1)
  258. jump()
  259. """)
  260. def test_new_array_fixed(self):
  261. self.check_rewrite("""
  262. []
  263. p0 = new_array(10, descr=adescr)
  264. jump()
  265. """, """
  266. []
  267. p0 = call_r(ConstClass(malloc_array), \
  268. %(adescr.basesize)d, \
  269. 10, \
  270. %(adescr.itemsize)d, \
  271. %(adescr.lendescr.offset)d, \
  272. descr=malloc_array_descr)
  273. check_memory_error(p0)
  274. jump()
  275. """)
  276. ## should ideally be:
  277. ## p0 = call_r(ConstClass(malloc_fixedsize), \
  278. ## %(adescr.basesize + 10 * adescr.itemsize)d, \
  279. ## descr=malloc_fixedsize_descr)
  280. ## setfield_gc(p0, 10, descr=alendescr)
  281. def test_new_array_variable(self):
  282. self.check_rewrite("""
  283. [i1]
  284. p0 = new_array(i1, descr=adescr)
  285. jump()
  286. """, """
  287. [i1]
  288. p0 = call_r(ConstClass(malloc_array), \
  289. %(adescr.basesize)d, \
  290. i1, \
  291. %(adescr.itemsize)d, \
  292. %(adescr.lendescr.offset)d, \
  293. descr=malloc_array_descr)
  294. check_memory_error(p0)
  295. jump()
  296. """)
  297. def test_new_with_vtable(self):
  298. self.check_rewrite("""
  299. []
  300. p0 = new_with_vtable(descr=o_descr)
  301. jump()
  302. """, """
  303. [p1]
  304. p0 = call_r(ConstClass(malloc_fixedsize), 102, \
  305. descr=malloc_fixedsize_descr)
  306. check_memory_error(p0)
  307. gc_store(p0, 0, ConstClass(o_vtable), %(vtable_descr.field_size)s)
  308. jump()
  309. """)
  310. def test_newstr(self):
  311. self.check_rewrite("""
  312. [i1]
  313. p0 = newstr(i1)
  314. jump()
  315. """, """
  316. [i1]
  317. p0 = call_r(ConstClass(malloc_array), \
  318. %(strdescr.basesize)d, \
  319. i1, \
  320. %(strdescr.itemsize)d, \
  321. %(strlendescr.offset)d, \
  322. descr=malloc_array_descr)
  323. check_memory_error(p0)
  324. jump()
  325. """)
  326. def test_newunicode(self):
  327. self.check_rewrite("""
  328. [i1]
  329. p0 = newunicode(10)
  330. jump()
  331. """, """
  332. [i1]
  333. p0 = call_r(ConstClass(malloc_array), \
  334. %(unicodedescr.basesize)d, \
  335. 10, \
  336. %(unicodedescr.itemsize)d, \
  337. %(unicodelendescr.offset)d, \
  338. descr=malloc_array_descr)
  339. check_memory_error(p0)
  340. jump()
  341. """)
  342. ## should ideally be:
  343. ## p0 = call_r(ConstClass(malloc_fixedsize), \
  344. ## %(unicodedescr.basesize + \
  345. ## 10 * unicodedescr.itemsize)d, \
  346. ## descr=malloc_fixedsize_descr)
  347. ## setfield_gc(p0, 10, descr=unicodelendescr)
  348. class TestFramework(RewriteTests):
  349. def setup_method(self, meth):
  350. class config_(object):
  351. class translation(object):
  352. gc = 'minimark'
  353. gcrootfinder = 'asmgcc'
  354. gctransformer = 'framework'
  355. gcremovetypeptr = False
  356. gcdescr = get_description(config_)
  357. self.gc_ll_descr = GcLLDescr_framework(gcdescr, None, None, None,
  358. really_not_translated=True)
  359. self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
  360. lambda cpu: True)
  361. self.gc_ll_descr.malloc_zero_filled = False
  362. #
  363. class FakeCPU(BaseFakeCPU):
  364. def sizeof(self, STRUCT, is_object):
  365. descr = SizeDescr(104, gc_fielddescrs=[])
  366. descr.tid = 9315
  367. return descr
  368. self.cpu = FakeCPU()
  369. def test_rewrite_assembler_new_to_malloc(self):
  370. self.check_rewrite("""
  371. [p1]
  372. p0 = new(descr=sdescr)
  373. jump()
  374. """, """
  375. [p1]
  376. p0 = call_malloc_nursery(%(sdescr.size)d)
  377. gc_store(p0, 0, 1234, 8)
  378. jump()
  379. """)
  380. def test_rewrite_assembler_new3_to_malloc(self):
  381. self.check_rewrite("""
  382. []
  383. p0 = new(descr=sdescr)
  384. p1 = new(descr=tdescr)
  385. p2 = new(descr=sdescr)
  386. jump()
  387. """, """
  388. []
  389. p0 = call_malloc_nursery( \
  390. %(sdescr.size + tdescr.size + sdescr.size)d)
  391. gc_store(p0, 0, 1234, 8)
  392. p1 = nursery_ptr_increment(p0, %(sdescr.size)d)
  393. gc_store(p1, 0, 5678, 8)
  394. p2 = nursery_ptr_increment(p1, %(tdescr.size)d)
  395. gc_store(p2, 0, 1234, 8)
  396. %(setfield('p1', 0, tdescr.gc_fielddescrs[0]))s
  397. jump()
  398. """)
  399. def test_rewrite_assembler_new_array_fixed_to_malloc(self):
  400. self.check_rewrite("""
  401. []
  402. p0 = new_array(10, descr=adescr)
  403. jump()
  404. """, """
  405. []
  406. p0 = call_malloc_nursery( \
  407. %(adescr.basesize + 10 * adescr.itemsize)d)
  408. gc_store(p0, 0, 4321, %(tiddescr.field_size)s)
  409. gc_store(p0, 0, 10, %(alendescr.field_size)s)
  410. jump()
  411. """)
  412. def test_rewrite_assembler_new_and_new_array_fixed_to_malloc(self):
  413. self.check_rewrite("""
  414. []
  415. p0 = new(descr=sdescr)
  416. p1 = new_array(10, descr=adescr)
  417. jump()
  418. """, """
  419. []
  420. p0 = call_malloc_nursery( \
  421. %(sdescr.size + \
  422. adescr.basesize + 10 * adescr.itemsize)d)
  423. gc_store(p0, 0, 1234, %(tiddescr.field_size)s)
  424. p1 = nursery_ptr_increment(p0, %(sdescr.size)d)
  425. gc_store(p1, 0, 4321, %(tiddescr.field_size)s)
  426. gc_store(p1, 0, 10, %(alendescr.field_size)s)
  427. jump()
  428. """)
  429. def test_rewrite_assembler_round_up(self):
  430. self.check_rewrite("""
  431. []
  432. p0 = new_array(6, descr=bdescr)
  433. jump()
  434. """, """
  435. []
  436. p0 = call_malloc_nursery(%(bdescr.basesize + 8)d)
  437. gc_store(p0, 0, 8765, %(tiddescr.field_size)s)
  438. gc_store(p0, 0, 6, %(blendescr.field_size)s)
  439. jump()
  440. """)
  441. def test_rewrite_assembler_round_up_always(self):
  442. self.check_rewrite("""
  443. []
  444. p0 = new_array(5, descr=bdescr)
  445. p1 = new_array(5, descr=bdescr)
  446. p2 = new_array(5, descr=bdescr)
  447. p3 = new_array(5, descr=bdescr)
  448. jump()
  449. """, """
  450. []
  451. p0 = call_malloc_nursery(%(4 * (bdescr.basesize + 8))d)
  452. gc_store(p0, 0, 8765, %(tiddescr.field_size)s)
  453. gc_store(p0, 0, 5, %(blendescr.field_size)s)
  454. p1 = nursery_ptr_increment(p0, %(bdescr.basesize + 8)d)
  455. gc_store(p1, 0, 8765, %(tiddescr.field_size)s)
  456. gc_store(p1, 0, 5, %(blendescr.field_size)s)
  457. p2 = nursery_ptr_increment(p1, %(bdescr.basesize + 8)d)
  458. gc_store(p2, 0, 8765, %(tiddescr.field_size)s)
  459. gc_store(p2, 0, 5, %(blendescr.field_size)s)
  460. p3 = nursery_ptr_increment(p2, %(bdescr.basesize + 8)d)
  461. gc_store(p3, 0, 8765, %(tiddescr.field_size)s)
  462. gc_store(p3, 0, 5, %(blendescr.field_size)s)
  463. jump()
  464. """)
  465. def test_rewrite_assembler_minimal_size(self):
  466. self.check_rewrite("""
  467. []
  468. p0 = new(descr=edescr)
  469. p1 = new(descr=edescr)
  470. jump()
  471. """, """
  472. []
  473. p0 = call_malloc_nursery(%(4*WORD)d)
  474. gc_store(p0, 0, 9000, %(tiddescr.field_size)s)
  475. p1 = nursery_ptr_increment(p0, %(2*WORD)d)
  476. gc_store(p1, 0, 9000, %(tiddescr.field_size)s)
  477. jump()
  478. """)
  479. def test_rewrite_assembler_variable_size(self):
  480. self.check_rewrite("""
  481. [i0]
  482. p0 = new_array(i0, descr=bdescr)
  483. jump(i0)
  484. """, """
  485. [i0]
  486. p0 = call_malloc_nursery_varsize(0, 1, i0, descr=bdescr)
  487. gc_store(p0, 0, i0, %(bdescr.basesize)s)
  488. jump(i0)
  489. """)
  490. def test_rewrite_new_string(self):
  491. self.check_rewrite("""
  492. [i0]
  493. p0 = newstr(i0)
  494. jump(i0)
  495. """, """
  496. [i0]
  497. p0 = call_malloc_nursery_varsize(1, 1, i0, descr=strdescr)
  498. gc_store(p0, %(strlendescr.offset)s, i0, %(strlendescr.field_size)s)
  499. gc_store(p0, 0, 0, %(strlendescr.field_size)s)
  500. jump(i0)
  501. """)
  502. def test_rewrite_assembler_nonstandard_array(self):
  503. # a non-standard array is a bit hard to get; e.g. GcArray(Float)
  504. # is like that on Win32, but not on Linux. Build one manually...
  505. NONSTD = lltype.GcArray(lltype.Float)
  506. nonstd_descr = get_array_descr(self.gc_ll_descr, NONSTD)
  507. nonstd_descr.tid = 6464
  508. nonstd_descr.basesize = 64 # <= hacked
  509. nonstd_descr.itemsize = 8
  510. nonstd_descr_gcref = 123
  511. # REVIEW: added descr=nonstd_descr to setarrayitem
  512. # is it even valid to have a setarrayitem WITHOUT a descr?
  513. self.check_rewrite("""
  514. [i0, p1]
  515. p0 = new_array(i0, descr=nonstd_descr)
  516. setarrayitem_gc(p0, i0, p1, descr=nonstd_descr)
  517. jump(i0)
  518. """, """
  519. [i0, p1]
  520. p0 = call_r(ConstClass(malloc_array_nonstandard), \
  521. 64, 8, \
  522. %(nonstd_descr.lendescr.offset)d, \
  523. 6464, i0, \
  524. descr=malloc_array_nonstandard_descr)
  525. check_memory_error(p0)
  526. cond_call_gc_wb_array(p0, i0, descr=wbdescr)
  527. gc_store_indexed(p0, i0, p1, 8, 64, 8)
  528. jump(i0)
  529. """, nonstd_descr=nonstd_descr)
  530. def test_rewrite_assembler_maximal_size_1(self):
  531. self.gc_ll_descr.max_size_of_young_obj = 100
  532. self.check_rewrite("""
  533. []
  534. p0 = new_array(103, descr=bdescr)
  535. jump()
  536. """, """
  537. []
  538. p0 = call_r(ConstClass(malloc_array), 1, \
  539. %(bdescr.tid)d, 103, \
  540. descr=malloc_array_descr)
  541. check_memory_error(p0)
  542. jump()
  543. """)
  544. def test_rewrite_assembler_maximal_size_2(self):
  545. self.gc_ll_descr.max_size_of_young_obj = 300
  546. self.check_rewrite("""
  547. []
  548. p0 = new_array(101, descr=bdescr)
  549. p1 = new_array(102, descr=bdescr) # two new_arrays can be combined
  550. p2 = new_array(103, descr=bdescr) # but not all three
  551. jump()
  552. """, """
  553. []
  554. p0 = call_malloc_nursery( \
  555. %(2 * (bdescr.basesize + 104))d)
  556. gc_store(p0, 0, 8765, %(tiddescr.field_size)s)
  557. gc_store(p0, 0, 101, %(blendescr.field_size)s)
  558. p1 = nursery_ptr_increment(p0, %(bdescr.basesize + 104)d)
  559. gc_store(p1, 0, 8765, %(tiddescr.field_size)s)
  560. gc_store(p1, 0, 102, %(blendescr.field_size)s)
  561. p2 = call_malloc_nursery( \
  562. %(bdescr.basesize + 104)d)
  563. gc_store(p2, 0, 8765, %(tiddescr.field_size)s)
  564. gc_store(p2, 0, 103, %(blendescr.field_size)s)
  565. jump()
  566. """)
  567. def test_rewrite_assembler_huge_size(self):
  568. # "huge" is defined as "larger than 0xffffff bytes, or 16MB"
  569. self.check_rewrite("""
  570. []
  571. p0 = new_array(20000000, descr=bdescr)
  572. jump()
  573. """, """
  574. []
  575. p0 = call_r(ConstClass(malloc_array), 1, \
  576. %(bdescr.tid)d, 20000000, \
  577. descr=malloc_array_descr)
  578. check_memory_error(p0)
  579. jump()
  580. """)
  581. def test_new_with_vtable(self):
  582. self.check_rewrite("""
  583. []
  584. p0 = new_with_vtable(descr=o_descr)
  585. jump()
  586. """, """
  587. [p1]
  588. p0 = call_malloc_nursery(104) # rounded up
  589. gc_store(p0, 0, 9315, %(tiddescr.field_size)s)
  590. gc_store(p0, 0, 0, %(vtable_descr.field_size)s)
  591. jump()
  592. """)
  593. def test_new_with_vtable_too_big(self):
  594. self.gc_ll_descr.max_size_of_young_obj = 100
  595. self.check_rewrite("""
  596. []
  597. p0 = new_with_vtable(descr=o_descr)
  598. jump()
  599. """, """
  600. [p1]
  601. p0 = call_r(ConstClass(malloc_big_fixedsize), 104, 9315, \
  602. descr=malloc_big_fixedsize_descr)
  603. check_memory_error(p0)
  604. gc_store(p0, 0, 0, %(vtable_descr.field_size)s)
  605. jump()
  606. """)
  607. def test_rewrite_assembler_newstr_newunicode(self):
  608. # note: strdescr.basesize already contains the extra final character,
  609. # so that's why newstr(14) is rounded up to 'basesize+15' and not
  610. # 'basesize+16'.
  611. self.check_rewrite("""
  612. [i2]
  613. p0 = newstr(14)
  614. p1 = newunicode(10)
  615. p2 = newunicode(i2)
  616. p3 = newstr(i2)
  617. jump()
  618. """, """
  619. [i2]
  620. p0 = call_malloc_nursery( \
  621. %(strdescr.basesize + 15 * strdescr.itemsize + \
  622. unicodedescr.basesize + 10 * unicodedescr.itemsize)d)
  623. gc_store(p0, 0, %(strdescr.tid)d, %(tiddescr.field_size)s)
  624. gc_store(p0, %(strlendescr.offset)s, 14, %(strlendescr.field_size)s)
  625. gc_store(p0, 0, 0, %(strhashdescr.field_size)s)
  626. p1 = nursery_ptr_increment(p0, %(strdescr.basesize + 15 * strdescr.itemsize)d)
  627. gc_store(p1, 0, %(unicodedescr.tid)d, %(tiddescr.field_size)s)
  628. gc_store(p1, %(unicodelendescr.offset)s, 10, %(unicodelendescr.field_size)s)
  629. gc_store(p1, 0, 0, %(unicodehashdescr.field_size)s)
  630. p2 = call_malloc_nursery_varsize(2, %(unicodedescr.itemsize)d, i2,\
  631. descr=unicodedescr)
  632. gc_store(p2, %(unicodelendescr.offset)s, i2, %(unicodelendescr.field_size)s)
  633. gc_store(p2, 0, 0, %(unicodehashdescr.field_size)s)
  634. p3 = call_malloc_nursery_varsize(1, 1, i2, \
  635. descr=strdescr)
  636. gc_store(p3, %(strlendescr.offset)s, i2, %(strlendescr.field_size)s)
  637. gc_store(p3, 0, 0, %(strhashdescr.field_size)s)
  638. jump()
  639. """)
  640. def test_write_barrier_before_setfield_gc(self):
  641. self.check_rewrite("""
  642. [p1, p2]
  643. setfield_gc(p1, p2, descr=tzdescr)
  644. jump()
  645. """, """
  646. [p1, p2]
  647. cond_call_gc_wb(p1, descr=wbdescr)
  648. gc_store(p1, %(tzdescr.offset)s, p2, %(tzdescr.field_size)s)
  649. jump()
  650. """)
  651. def test_write_barrier_before_array_without_from_array(self):
  652. self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
  653. lambda cpu: False)
  654. self.check_rewrite("""
  655. [p1, i2, p3]
  656. setarrayitem_gc(p1, i2, p3, descr=cdescr)
  657. jump()
  658. """, """
  659. [p1, i2, p3]
  660. cond_call_gc_wb(p1, descr=wbdescr)
  661. %(setarrayitem('p1', 'i2', 'p3', cdescr))s
  662. jump()
  663. """)
  664. def test_write_barrier_before_short_array(self):
  665. self.gc_ll_descr.max_size_of_young_obj = 2000
  666. self.check_rewrite("""
  667. [i2, p3]
  668. p1 = new_array_clear(129, descr=cdescr)
  669. call_n(123456)
  670. setarrayitem_gc(p1, i2, p3, descr=cdescr)
  671. jump()
  672. """, """
  673. [i2, p3]
  674. p1 = call_malloc_nursery( \
  675. %(cdescr.basesize + 129 * cdescr.itemsize)d)
  676. gc_store(p1, 0, 8111, %(tiddescr.field_size)s)
  677. gc_store(p1, 0, 129, %(clendescr.field_size)s)
  678. %(zero_array('p1', 0, 129, 'cdescr', cdescr))s
  679. call_n(123456)
  680. cond_call_gc_wb(p1, descr=wbdescr)
  681. %(setarrayitem('p1', 'i2', 'p3', cdescr))s
  682. jump()
  683. """)
  684. def test_write_barrier_before_long_array(self):
  685. # the limit of "being too long" is fixed, arbitrarily, at 130
  686. self.gc_ll_descr.max_size_of_young_obj = 2000
  687. self.check_rewrite("""
  688. [i2, p3]
  689. p1 = new_array_clear(130, descr=cdescr)
  690. call_n(123456)
  691. setarrayitem_gc(p1, i2, p3, descr=cdescr)
  692. jump()
  693. """, """
  694. [i2, p3]
  695. p1 = call_malloc_nursery( \
  696. %(cdescr.basesize + 130 * cdescr.itemsize)d)
  697. gc_store(p1, 0, 8111, %(tiddescr.field_size)s)
  698. gc_store(p1, 0, 130, %(clendescr.field_size)s)
  699. %(zero_array('p1', 0, 130, 'cdescr', cdescr))s
  700. call_n(123456)
  701. cond_call_gc_wb_array(p1, i2, descr=wbdescr)
  702. %(setarrayitem('p1', 'i2', 'p3', cdescr))s
  703. jump()
  704. """)
  705. def test_write_barrier_before_unknown_array(self):
  706. self.check_rewrite("""
  707. [p1, i2, p3]
  708. setarrayitem_gc(p1, i2, p3, descr=cdescr)
  709. jump()
  710. """, """
  711. [p1, i2, p3]
  712. cond_call_gc_wb_array(p1, i2, descr=wbdescr)
  713. %(setarrayitem('p1', 'i2', 'p3', cdescr))s
  714. jump()
  715. """)
  716. def test_label_makes_size_unknown(self):
  717. self.check_rewrite("""
  718. [i2, p3]
  719. p1 = new_array_clear(5, descr=cdescr)
  720. label(p1, i2, p3)
  721. setarrayitem_gc(p1, i2, p3, descr=cdescr)
  722. jump()
  723. """, """
  724. [i2, p3]
  725. p1 = call_malloc_nursery( \
  726. %(cdescr.basesize + 5 * cdescr.itemsize)d)
  727. gc_store(p1, 0, 8111, %(tiddescr.field_size)s)
  728. gc_store(p1, 0, 5, %(clendescr.field_size)s)
  729. %(zero_array('p1', 0, 5, 'cdescr', cdescr))s
  730. label(p1, i2, p3)
  731. cond_call_gc_wb_array(p1, i2, descr=wbdescr)
  732. %(setarrayitem('p1', 'i2', 'p3', cdescr))s
  733. jump()
  734. """)
  735. def test_write_barrier_before_setinteriorfield_gc(self):
  736. S1 = lltype.GcStruct('S1')
  737. INTERIOR = lltype.GcArray(('z', lltype.Ptr(S1)))
  738. interiordescr = get_array_descr(self.gc_ll_descr, INTERIOR)
  739. interiordescr.tid = 1291
  740. interiorlendescr = interiordescr.lendescr
  741. interiorzdescr = get_interiorfield_descr(self.gc_ll_descr,
  742. INTERIOR, 'z')
  743. scale = interiorzdescr.arraydescr.itemsize
  744. offset = interiorzdescr.arraydescr.basesize
  745. offset += interiorzdescr.fielddescr.offset
  746. size = interiorzdescr.arraydescr.itemsize
  747. self.check_rewrite("""
  748. [p1, p2]
  749. setinteriorfield_gc(p1, 7, p2, descr=interiorzdescr)
  750. jump(p1, p2)
  751. """, """
  752. [p1, p2]
  753. cond_call_gc_wb_array(p1, 7, descr=wbdescr)
  754. gc_store(p1, %(offset + 7 * scale)s, p2, %(size)s)
  755. jump(p1, p2)
  756. """, interiorzdescr=interiorzdescr, scale=scale,
  757. offset=offset, size=size)
  758. def test_initialization_store(self):
  759. self.check_rewrite("""
  760. [p1]
  761. p0 = new(descr=tdescr)
  762. setfield_gc(p0, p1, descr=tzdescr)
  763. jump()
  764. """, """
  765. [p1]
  766. p0 = call_malloc_nursery(%(tdescr.size)d)
  767. gc_store(p0, 0, 5678, %(tiddescr.field_size)s)
  768. gc_store(p0, %(tzdescr.offset)s, p1, %(tzdescr.field_size)s)
  769. jump()
  770. """)
  771. def test_initialization_store_2(self):
  772. self.check_rewrite("""
  773. []
  774. p0 = new(descr=tdescr)
  775. p1 = new(descr=sdescr)
  776. setfield_gc(p0, p1, descr=tzdescr)
  777. jump()
  778. """, """
  779. []
  780. p0 = call_malloc_nursery(%(tdescr.size + sdescr.size)d)
  781. gc_store(p0, 0, 5678, %(tiddescr.field_size)s)
  782. p1 = nursery_ptr_increment(p0, %(tdescr.size)d)
  783. gc_store(p1, 0, 1234, %(tiddescr.field_size)s)
  784. # <<<no cond_call_gc_wb here>>>
  785. gc_store(p0, %(tzdescr.offset)s, p1, %(tzdescr.field_size)s)
  786. jump()
  787. """)
  788. def test_initialization_store_array(self):
  789. self.check_rewrite("""
  790. [p1, i2]
  791. p0 = new_array_clear(5, descr=cdescr)
  792. setarrayitem_gc(p0, i2, p1, descr=cdescr)
  793. jump()
  794. """, """
  795. [p1, i2]
  796. p0 = call_malloc_nursery( \
  797. %(cdescr.basesize + 5 * cdescr.itemsize)d)
  798. gc_store(p0, 0, 8111, %(tiddescr.field_size)s)
  799. gc_store(p0, 0, 5, %(clendescr.field_size)s)
  800. %(zero_array('p0', 0, 5, 'cdescr', cdescr))s
  801. %(setarrayitem('p0', 'i2', 'p1', cdescr))s
  802. jump()
  803. """)
  804. def test_zero_array_reduced_left(self):
  805. self.check_rewrite("""
  806. [p1, p2]
  807. p0 = new_array_clear(5, descr=cdescr)
  808. setarrayitem_gc(p0, 1, p1, descr=cdescr)
  809. setarrayitem_gc(p0, 0, p2, descr=cdescr)
  810. jump()
  811. """, """
  812. [p1, p2]
  813. p0 = call_malloc_nursery( \
  814. %(cdescr.basesize + 5 * cdescr.itemsize)d)
  815. gc_store(p0, 0, 8111, %(tiddescr.field_size)s)
  816. gc_store(p0, 0, 5, %(clendescr.field_size)s)
  817. %(zero_array('p0', 2, 3, 'cdescr', cdescr))s
  818. %(setarrayitem('p0', 1, 'p1', cdescr))s
  819. %(setarrayitem('p0', 0, 'p2', cdescr))s
  820. jump()
  821. """)
  822. def test_zero_array_reduced_right(self):
  823. self.check_rewrite("""
  824. [p1, p2]
  825. p0 = new_array_clear(5, descr=cdescr)
  826. setarrayitem_gc(p0, 3, p1, descr=cdescr)
  827. setarrayitem_gc(p0, 4, p2, descr=cdescr)
  828. jump()
  829. """, """
  830. [p1, p2]
  831. p0 = call_malloc_nursery( \
  832. %(cdescr.basesize + 5 * cdescr.itemsize)d)
  833. gc_store(p0, 0, 8111, %(tiddescr.field_size)s)
  834. gc_store(p0, 0, 5, %(clendescr.field_size)s)
  835. %(zero_array('p0', 0, 3, 'cdescr', cdescr))s
  836. %(setarrayitem('p0', 3, 'p1', cdescr))s
  837. %(setarrayitem('p0', 4, 'p2', cdescr))s
  838. jump()
  839. """)
  840. def test_zero_array_not_reduced_at_all(self):
  841. self.check_rewrite("""
  842. [p1, p2]
  843. p0 = new_array_clear(5, descr=cdescr)
  844. setarrayitem_gc(p0, 3, p1, descr=cdescr)
  845. setarrayitem_gc(p0, 2, p2, descr=cdescr)
  846. setarrayitem_gc(p0, 1, p2, descr=cdescr)
  847. jump()
  848. """, """
  849. [p1, p2]
  850. p0 = call_malloc_nursery( \
  851. %(cdescr.basesize + 5 * cdescr.itemsize)d)
  852. gc_store(p0, 0, 8111, %(tiddescr.field_size)s)
  853. gc_store(p0, 0, 5, %(clendescr.field_size)s)
  854. %(zero_array('p0', 0, 5, 'cdescr', cdescr))s
  855. %(setarrayitem('p0', 3, 'p1', cdescr))s
  856. %(setarrayitem('p0', 2, 'p2', cdescr))s
  857. %(setarrayitem('p0', 1, 'p2', cdescr))s
  858. jump()
  859. """)
  860. def test_zero_array_reduced_completely(self):
  861. self.check_rewrite("""
  862. [p1, p2]
  863. p0 = new_array_clear(5, descr=cdescr)
  864. setarrayitem_gc(p0, 3, p1, descr=cdescr)
  865. setarrayitem_gc(p0, 4, p2, descr=cdescr)
  866. setarrayitem_gc(p0, 0, p1, descr=cdescr)
  867. setarrayitem_gc(p0, 2, p2, descr=cdescr)
  868. setarrayitem_gc(p0, 1, p2, descr=cdescr)
  869. jump()
  870. """, """
  871. [p1, p2]
  872. p0 = call_malloc_nursery( \
  873. %(cdescr.basesize + 5 * cdescr.itemsize)d)
  874. gc_store(p0, 0, 8111, %(tiddescr.field_size)s)
  875. gc_store(p0, 0, 5, %(clendescr.field_size)s)
  876. %(zero_array('p0', 5, 0, 'cdescr', cdescr))s
  877. %(setarrayitem('p0', 3, 'p1', cdescr))s
  878. %(setarrayitem('p0', 4, 'p2', cdescr))s
  879. %(setarrayitem('p0', 0, 'p1', cdescr))s
  880. %(setarrayitem('p0', 2, 'p2', cdescr))s
  881. %(setarrayitem('p0', 1, 'p2', cdescr))s
  882. jump()
  883. """)
  884. def test_zero_array_reduced_left_with_call(self):
  885. self.check_rewrite("""
  886. [p1, p2]
  887. p0 = new_array_clear(5, descr=cdescr)
  888. setarrayitem_gc(p0, 0, p1, descr=cdescr)
  889. call_n(321321)
  890. setarrayitem_gc(p0, 1, p2, descr=cdescr)
  891. jump()
  892. """, """
  893. [p1, p2]
  894. p0 = call_malloc_nursery( \
  895. %(cdescr.basesize + 5 * cdescr.itemsize)d)
  896. gc_store(p0, 0, 8111, %(tiddescr.field_size)s)
  897. gc_store(p0, 0, 5, %(clendescr.field_size)s)
  898. %(zero_array('p0', 1, 4, 'cdescr', cdescr))s
  899. %(setarrayitem('p0', 0, 'p1', cdescr))s
  900. call_n(321321)
  901. cond_call_gc_wb(p0, descr=wbdescr)
  902. %(setarrayitem('p0', 1, 'p2', cdescr))s
  903. jump()
  904. """)
  905. def test_zero_array_reduced_left_with_label(self):
  906. self.check_rewrite("""
  907. [p1, p2]
  908. p0 = new_array_clear(5, descr=cdescr)
  909. setarrayitem_gc(p0, 0, p1, descr=cdescr)
  910. label(p0, p2)
  911. setarrayitem_gc(p0, 1, p2, descr=cdescr)
  912. jump()
  913. """, """
  914. [p1, p2]
  915. p0 = call_malloc_nursery( \
  916. %(cdescr.basesize + 5 * cdescr.itemsize)d)
  917. gc_store(p0, 0, 8111, %(tiddescr.field_size)s)
  918. gc_store(p0, 0, 5, %(clendescr.field_size)s)
  919. %(zero_array('p0', 1, 4, 'cdescr', cdescr))s
  920. %(setarrayitem('p0', 0, 'p1', cdescr))s
  921. label(p0, p2)
  922. cond_call_gc_wb_array(p0, 1, descr=wbdescr)
  923. %(setarrayitem('p0', 1, 'p2', cdescr))s
  924. jump()
  925. """)
  926. def test_zero_array_varsize(self):
  927. self.check_rewrite("""
  928. [p1, p2, i3]
  929. p0 = new_array_clear(i3, descr=bdescr)
  930. jump()
  931. """, """
  932. [p1, p2, i3]
  933. p0 = call_malloc_nursery_varsize(0, 1, i3, descr=bdescr)
  934. gc_store(p0, 0, i3, %(blendescr.field_size)s)
  935. %(zero_array('p0', 0, 'i3', 'bdescr', bdescr))s
  936. jump()
  937. """)
  938. def test_zero_array_varsize_cannot_reduce(self):
  939. self.check_rewrite("""
  940. [p1, p2, i3]
  941. p0 = new_array_clear(i3, descr=bdescr)
  942. setarrayitem_gc(p0, 0, p1, descr=bdescr)
  943. jump()
  944. """, """
  945. [p1, p2, i3]
  946. p0 = call_malloc_nursery_varsize(0, 1, i3, descr=bdescr)
  947. gc_store(p0, 0, i3, %(blendescr.field_size)s)
  948. %(zero_array('p0', 0, 'i3', 'bdescr', bdescr))s
  949. cond_call_gc_wb_array(p0, 0, descr=wbdescr)
  950. %(setarrayitem('p0', 0, 'p1', bdescr))s
  951. jump()
  952. """)
  953. def test_initialization_store_potentially_large_array(self):
  954. # the write barrier cannot be omitted, because we might get
  955. # an array with cards and the GC assumes that the write
  956. # barrier is always called, even on young (but large) arrays
  957. self.check_rewrite("""
  958. [i0, p1, i2]
  959. p0 = new_array(i0, descr=bdescr)
  960. setarrayitem_gc(p0, i2, p1, descr=bdescr)
  961. jump()
  962. """, """
  963. [i0, p1, i2]
  964. p0 = call_malloc_nursery_varsize(0, 1, i0, descr=bdescr)
  965. gc_store(p0, 0, i0, %(blendescr.field_size)s)
  966. cond_call_gc_wb_array(p0, i2, descr=wbdescr)
  967. gc_store_indexed(p0, i2, p1, 1, %(bdescr.basesize)s, 1)
  968. jump()
  969. """)
  970. def test_non_initialization_store(self):
  971. self.check_rewrite("""
  972. [i0]
  973. p0 = new(descr=tdescr)
  974. p1 = newstr(i0)
  975. setfield_gc(p0, p1, descr=tzdescr)
  976. jump()
  977. """, """
  978. [i0]
  979. p0 = call_malloc_nursery(%(tdescr.size)d)
  980. gc_store(p0, 0, 5678, %(tiddescr.field_size)s)
  981. gc_store(p0, %(tdescr.gc_fielddescrs[0].offset)s, 0, %(tdescr.gc_fielddescrs[0].offset)s)
  982. p1 = call_malloc_nursery_varsize(1, 1, i0, \
  983. descr=strdescr)
  984. gc_store(p1, %(strlendescr.offset)s, i0, %(strlendescr.field_size)s)
  985. gc_store(p1, 0, 0, %(strhashdescr.field_size)s)
  986. cond_call_gc_wb(p0, descr=wbdescr)
  987. gc_store(p0, %(tzdescr.offset)s, p1, %(tzdescr.field_size)s)
  988. jump()
  989. """)
  990. def test_non_initialization_store_label(self):
  991. self.check_rewrite("""
  992. [p1]
  993. p0 = new(descr=tdescr)
  994. label(p0, p1)
  995. setfield_gc(p0, p1, descr=tzdescr)
  996. jump()
  997. """, """
  998. [p1]
  999. p0 = call_malloc_nursery(%(tdescr.size)d)
  1000. gc_store(p0, 0, 5678, %(tiddescr.field_size)s)
  1001. gc_store(p0, %(tdescr.gc_fielddescrs[0].offset)s, 0, %(tdescr.gc_fielddescrs[0].offset)s)
  1002. label(p0, p1)
  1003. cond_call_gc_wb(p0, descr=wbdescr)
  1004. gc_store(p0, %(tzdescr.offset)s, p1, %(tzdescr.field_size)s)
  1005. jump()
  1006. """)
  1007. def test_multiple_writes(self):
  1008. self.check_rewrite("""
  1009. [p0, p1, p2]
  1010. setfield_gc(p0, p1, descr=tzdescr)
  1011. setfield_gc(p0, p2, descr=tzdescr)
  1012. jump(p1, p2, p0)
  1013. """, """
  1014. [p0, p1, p2]
  1015. cond_call_gc_wb(p0, descr=wbdescr)
  1016. gc_store(p0, %(tzdescr.offset)s, p1, %(tzdescr.field_size)s)
  1017. gc_store(p0, %(tzdescr.offset)s, p2, %(tzdescr.field_size)s)
  1018. jump(p1, p2, p0)
  1019. """)
  1020. def test_rewrite_call_assembler(self):
  1021. self.check_rewrite("""
  1022. [i0, f0]
  1023. i2 = call_assembler_i(i0, f0, descr=casmdescr)
  1024. """, """
  1025. [i0, f0]
  1026. i1 = gc_load_i(ConstClass(frame_info), %(jfi_frame_size.offset)s, %(jfi_frame_size.field_size)s)
  1027. p1 = call_malloc_nursery_varsize_frame(i1)
  1028. gc_store(p1, 0, 0, %(tiddescr.field_size)s)
  1029. i2 = gc_load_i(ConstClass(frame_info), %(jfi_frame_depth.offset)s, %(jfi_frame_depth.field_size)s)
  1030. %(setfield('p1', 0, jf_extra_stack_depth))s
  1031. %(setfield('p1', 'NULL', jf_savedata))s
  1032. %(setfield('p1', 'NULL', jf_force_descr))s
  1033. %(setfield('p1', 'NULL', jf_descr))s
  1034. %(setfield('p1', 'NULL', jf_guard_exc))s
  1035. %(setfield('p1', 'NULL', jf_forward))s
  1036. gc_store(p1, 0, i2, %(framelendescr.field_size)s)
  1037. %(setfield('p1', 'ConstClass(frame_info)', jf_frame_info))s
  1038. gc_store(p1, 3, i0, 8)
  1039. gc_store(p1, 13, f0, 8)
  1040. i3 = call_assembler_i(p1, descr=casmdescr)
  1041. """)
  1042. def test_int_add_ovf(self):
  1043. self.check_rewrite("""
  1044. [i0]
  1045. p0 = new(descr=tdescr)
  1046. i1 = int_add_ovf(i0, 123)
  1047. guard_overflow(descr=guarddescr) []
  1048. jump()
  1049. """, """
  1050. [i0]
  1051. p0 = call_malloc_nursery(%(tdescr.size)d)
  1052. gc_store(p0, 0, 5678, %(tiddescr.field_size)s)
  1053. gc_store(p0, %(tdescr.gc_fielddescrs[0].offset)s, 0, %(tdescr.gc_fielddescrs[0].offset)s)
  1054. i1 = int_add_ovf(i0, 123)
  1055. guard_overflow(descr=guarddescr) []
  1056. jump()
  1057. """)
  1058. def test_int_gt(self):
  1059. self.check_rewrite("""
  1060. [i0]
  1061. p0 = new(descr=tdescr)
  1062. i1 = int_gt(i0, 123)
  1063. guard_false(i1, descr=guarddescr) []
  1064. jump()
  1065. """, """
  1066. [i0]
  1067. p0 = call_malloc_nursery(%(tdescr.size)d)
  1068. gc_store(p0, 0, 5678, %(tiddescr.field_size)s)
  1069. gc_store(p0, %(tdescr.gc_fielddescrs[0].offset)s, 0, %(tdescr.gc_fielddescrs[0].offset)s)
  1070. i1 = int_gt(i0, 123)
  1071. guard_false(i1, descr=guarddescr) []
  1072. jump()
  1073. """)
  1074. def test_zero_ptr_field_before_getfield(self):
  1075. # This case may need to be fixed in the metainterp/optimizeopt
  1076. # already so that it no longer occurs for rewrite.py. But anyway
  1077. # it's a good idea to make sure rewrite.py is correct on its own.
  1078. self.check_rewrite("""
  1079. []
  1080. p0 = new(descr=tdescr)
  1081. p1 = getfield_gc_r(p0, descr=tzdescr)
  1082. jump(p1)
  1083. """, """
  1084. []
  1085. p0 = call_malloc_nursery(%(tdescr.size)d)
  1086. gc_store(p0, 0, 5678, %(tiddescr.field_size)s)
  1087. gc_store(p0, %(tdescr.gc_fielddescrs[0].offset)s, 0, %(tdescr.gc_fielddescrs[0].offset)s)
  1088. p1 = gc_load_r(p0, %(tzdescr.offset)s, %(tzdescr.field_size)s)
  1089. jump(p1)
  1090. """)
  1091. def test_remove_tested_failarg(self):
  1092. self.check_rewrite("""
  1093. [i5]
  1094. i2 = int_ge(i5, 10)
  1095. guard_true(i2) [i5, i2]
  1096. jump()
  1097. """, """
  1098. [i5]
  1099. i0 = same_as_i(0)
  1100. i2 = int_ge(i5, 10)
  1101. guard_true(i2) [i5, i0]
  1102. jump()
  1103. """)
  1104. self.check_rewrite("""
  1105. [i5]
  1106. i2 = int_ge(i5, 10)
  1107. guard_false(i2) [i5, i2]
  1108. jump()
  1109. """, """
  1110. [i5]
  1111. i0 = same_as_i(1)
  1112. i2 = int_ge(i5, 10)
  1113. guard_false(i2) [i5, i0]
  1114. jump()
  1115. """)
  1116. @py.test.mark.parametrize('support_offset,factors,fromto',[
  1117. # [False, (1,2,4,8), 'setarrayitem_gc(p0,i1,i2,descr=adescr)' '->'
  1118. # 'i3 = int_mul(i1,%(adescr.itemsize)s);'
  1119. # 'i4 = int_add(i3,%(adescr.basesize)s);'
  1120. # 'gc_store(p0,i4,i2,%(adescr.itemsize)s)'],
  1121. [True, (1,2,4,8), 'setarrayitem_gc(p0,i1,i2,descr=adescr)' '->'
  1122. 'gc_store_indexed(p0,i1,i2,%(adescr.itemsize)s,'
  1123. '%(adescr.basesize)s,%(adescr.itemsize)s)'],
  1124. #[False, (1,), 'setarrayitem_gc(p0,i1,i2,descr=adescr)' '->'
  1125. # 'i3 = int_mul(i1,%(adescr.itemsize)s);'
  1126. # 'i4 = int_add(i3,%(adescr.basesize)s);'
  1127. # 'gc_store(p0,i4,i2,%(adescr.itemsize)s)'],
  1128. [True, None, 'i3 = raw_load_i(p0,i1,descr=adescr)' '->'
  1129. 'gc_load_indexed_i(p0,i1,1,%(adescr.basesize)s,-%(adescr.itemsize)s)'],
  1130. [True, None, 'i3 = raw_load_f(p0,i1,descr=fdescr)' '->'
  1131. 'gc_load_indexed_f(p0,i1,1,%(fdescr.basesize)s,%(fdescr.itemsize)s)'],
  1132. [True, None, 'i3 = raw_load_i(p0,i1,descr=sfdescr)' '->'
  1133. 'gc_load_indexed_i(p0,i1,1,%(sfdescr.basesize)s,%(sfdescr.itemsize)s)'],
  1134. [True, (1,2,4,8), 'i3 = raw_store(p0,i1,i2,descr=raw_sfdescr)' '->'
  1135. 'gc_store_indexed(p0,i1,i2,1,%(raw_sfdescr.basesize)s,%(raw_sfdescr.itemsize)s)'],
  1136. # [False, (1,), 'i3 = raw_store(p0,i1,i2,descr=raw_sfdescr)' '->'
  1137. # 'i5 = int_add(i1,%(raw_sfdescr.basesize)s);'
  1138. # 'gc_store(p0,i5,i2,%(raw_sfdescr.itemsize)s)'],
  1139. [True, (1,2,4,8), 'i3 = getfield_gc_f(p0,descr=ydescr)' '->'
  1140. 'i3 = gc_load_f(p0,%(ydescr.offset)s,%(ydescr.field_size)s)'],
  1141. [True, (1,2,4,8), 'setfield_raw(p0,i1,descr=ydescr)' '->'
  1142. 'gc_store(p0,%(ydescr.offset)s,i1,%(ydescr.field_size)s)'],
  1143. [True, (1,2,4,8), 'setfield_gc(p0,p0,descr=zdescr)' '->'
  1144. 'cond_call_gc_wb(p0, descr=wbdescr);'
  1145. 'gc_store(p0,%(zdescr.offset)s,p0,%(zdescr.field_size)s)'],
  1146. [False, (1,), 'i3 = arraylen_gc(p0, descr=adescr)' '->'
  1147. 'i3 = gc_load_i(p0,0,%(adescr.itemsize)s)'],
  1148. #[False, (1,), 'i3 = strlen(p0)' '->'
  1149. # 'i3 = gc_load_i(p0,'
  1150. # '%(strlendescr.offset)s,%(strlendescr.field_size)s)'],
  1151. [True, (1,), 'i3 = strlen(p0)' '->'
  1152. 'i3 = gc_load_i(p0,'
  1153. '%(strlendescr.offset)s,'
  1154. '%(strlendescr.field_size)s)'],
  1155. #[False, (1,), 'i3 = unicodelen(p0)' '->'
  1156. # 'i3 = gc_load_i(p0,'
  1157. # '%(unicodelendescr.offset)s,'
  1158. # '%(unicodelendescr.field_size)s)'],
  1159. [True, (1,), 'i3 = unicodelen(p0)' '->'
  1160. 'i3 = gc_load_i(p0,'
  1161. '%(unicodelendescr.offset)s,'
  1162. '%(unicodelendescr.field_size)s)'],
  1163. ## getitem str/unicode
  1164. [True, (2,4), 'i3 = unicodegetitem(p0,i1)' '->'
  1165. 'i3 = gc_load_indexed_i(p0,i1,'
  1166. '%(unicodedescr.itemsize)d,'
  1167. '%(unicodedescr.basesize)d,'
  1168. '%(unicodedescr.itemsize)d)'],
  1169. #[False, (2,4), 'i3 = unicodegetitem(p0,i1)' '->'
  1170. # 'i4 = int_mul(i1, %(unicodedescr.itemsize)d);'
  1171. # 'i5 = int_add(i4, %(unicodedescr.basesize)d);'
  1172. # 'i3 = gc_load_i(p0,i5,%(unicodedescr.itemsize)d)'],
  1173. [True, (4,), 'i3 = strgetitem(p0,i1)' '->'
  1174. 'i3 = gc_load_indexed_i(p0,i1,1,'
  1175. '%(strdescr.basesize-1)d,1)'],
  1176. #[False, (4,), 'i3 = strgetitem(p0,i1)' '->'
  1177. # 'i5 = int_add(i1, %(strdescr.basesize-1)d);'
  1178. # 'i3 = gc_load_i(p0,i5,1)'],
  1179. ## setitem str/unicode
  1180. [True, (4,), 'i3 = strsetitem(p0,i1,0)' '->'
  1181. 'i3 = gc_store_indexed(p0,i1,0,1,'
  1182. '%(strdescr.basesize-1)d,1)'],
  1183. [True, (2,4), 'i3 = unicodesetitem(p0,i1,0)' '->'
  1184. 'i3 = gc_store_indexed(p0,i1,0,'
  1185. '%(unicodedescr.itemsize)d,'
  1186. '%(unicodedescr.basesiz…

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