PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/pypy/pypy/
Python | 473 lines | 402 code | 41 blank | 30 comment | 15 complexity | 5982d7fe0d1a498e44aca593c81ce857 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. from rpython.rtyper.lltypesystem import lltype, rffi, rstr
  2. from rpython.jit.backend.llsupport.descr import *
  3. from rpython.jit.backend.llsupport import symbolic
  4. from rpython.rlib.objectmodel import Symbolic
  5. from rpython.rtyper.annlowlevel import llhelper
  6. from rpython.jit.metainterp import history
  7. from rpython.jit.codewriter import longlong
  8. import sys, struct, py
  9. def test_get_size_descr():
  10. c0 = GcCache(False)
  11. c1 = GcCache(True)
  12. T = lltype.GcStruct('T')
  13. S = lltype.GcStruct('S', ('x', lltype.Char),
  14. ('y', lltype.Ptr(T)))
  15. descr_s = get_size_descr(c0, S)
  16. descr_t = get_size_descr(c0, T)
  17. assert descr_s.size == symbolic.get_size(S, False)
  18. assert descr_t.size == symbolic.get_size(T, False)
  19. assert descr_s.is_immutable() == False
  20. assert descr_t.is_immutable() == False
  21. assert descr_t.gc_fielddescrs == []
  22. assert len(descr_s.gc_fielddescrs) == 1
  23. assert descr_s == get_size_descr(c0, S)
  24. assert descr_s != get_size_descr(c1, S)
  25. #
  26. descr_s = get_size_descr(c1, S)
  27. assert isinstance(descr_s.size, Symbolic)
  28. assert descr_s.is_immutable() == False
  29. PARENT = lltype.Struct('P', ('x', lltype.Ptr(T)))
  30. STRUCT = lltype.GcStruct('S', ('parent', PARENT), ('y', lltype.Ptr(T)))
  31. descr_struct = get_size_descr(c0, STRUCT)
  32. assert len(descr_struct.gc_fielddescrs) == 2
  33. def test_get_size_descr_immut():
  34. S = lltype.GcStruct('S', hints={'immutable': True})
  35. T = lltype.GcStruct('T', ('parent', S),
  36. ('x', lltype.Char),
  37. hints={'immutable': True})
  38. U = lltype.GcStruct('U', ('parent', T),
  39. ('u', lltype.Ptr(T)),
  40. ('v', lltype.Signed),
  41. hints={'immutable': True})
  42. V = lltype.GcStruct('V', ('parent', U),
  43. ('miss1', lltype.Void),
  44. ('miss2', lltype.Void),
  45. hints={'immutable': True})
  46. for STRUCT in [S, T, U, V]:
  47. for translated in [False, True]:
  48. c0 = GcCache(translated)
  49. descr_s = get_size_descr(c0, STRUCT)
  50. assert descr_s.is_immutable() == True
  51. def test_get_field_descr():
  52. U = lltype.Struct('U')
  53. T = lltype.GcStruct('T')
  54. S = lltype.GcStruct('S', ('x', lltype.Char),
  55. ('y', lltype.Ptr(T)),
  56. ('z', lltype.Ptr(U)),
  57. ('f', lltype.Float),
  58. ('s', lltype.SingleFloat))
  59. #
  60. c0 = GcCache(False)
  61. c1 = GcCache(True)
  62. assert get_field_descr(c0, S, 'y') == get_field_descr(c0, S, 'y')
  63. assert get_field_descr(c0, S, 'y') != get_field_descr(c1, S, 'y')
  64. for tsc in [False, True]:
  65. c2 = GcCache(tsc)
  66. descr_x = get_field_descr(c2, S, 'x')
  67. descr_y = get_field_descr(c2, S, 'y')
  68. descr_z = get_field_descr(c2, S, 'z')
  69. descr_f = get_field_descr(c2, S, 'f')
  70. descr_s = get_field_descr(c2, S, 's')
  71. assert isinstance(descr_x, FieldDescr)
  72. assert descr_x.name == 'S.x'
  73. assert descr_y.name == 'S.y'
  74. assert descr_z.name == 'S.z'
  75. assert descr_f.name == 'S.f'
  76. assert descr_s.name == 'S.s'
  77. if not tsc:
  78. assert descr_x.offset < descr_y.offset < descr_z.offset
  79. assert descr_x.sort_key() < descr_y.sort_key() < descr_z.sort_key()
  80. assert descr_x.field_size == rffi.sizeof(lltype.Char)
  81. assert descr_y.field_size == rffi.sizeof(lltype.Ptr(T))
  82. assert descr_z.field_size == rffi.sizeof(lltype.Ptr(U))
  83. assert descr_f.field_size == rffi.sizeof(lltype.Float)
  84. assert descr_s.field_size == rffi.sizeof(lltype.SingleFloat)
  85. else:
  86. assert isinstance(descr_x.offset, Symbolic)
  87. assert isinstance(descr_y.offset, Symbolic)
  88. assert isinstance(descr_z.offset, Symbolic)
  89. assert isinstance(descr_f.offset, Symbolic)
  90. assert isinstance(descr_s.offset, Symbolic)
  91. assert isinstance(descr_x.field_size, Symbolic)
  92. assert isinstance(descr_y.field_size, Symbolic)
  93. assert isinstance(descr_z.field_size, Symbolic)
  94. assert isinstance(descr_f.field_size, Symbolic)
  95. assert isinstance(descr_s.field_size, Symbolic)
  96. assert descr_x.flag == FLAG_UNSIGNED
  97. assert descr_y.flag == FLAG_POINTER
  98. assert descr_z.flag == FLAG_UNSIGNED
  99. assert descr_f.flag == FLAG_FLOAT
  100. assert descr_s.flag == FLAG_UNSIGNED
  101. def test_get_field_descr_sign():
  102. for RESTYPE, signed in [(rffi.SIGNEDCHAR, True), (rffi.UCHAR, False),
  103. (rffi.SHORT, True), (rffi.USHORT, False),
  104. (rffi.INT, True), (rffi.UINT, False),
  105. (rffi.LONG, True), (rffi.ULONG, False)]:
  106. S = lltype.GcStruct('S', ('x', RESTYPE))
  107. for tsc in [False, True]:
  108. c2 = GcCache(tsc)
  109. descr_x = get_field_descr(c2, S, 'x')
  110. assert descr_x.flag == {False: FLAG_UNSIGNED,
  111. True: FLAG_SIGNED }[signed]
  112. def test_get_field_descr_longlong():
  113. if sys.maxint > 2147483647:
  114. py.test.skip("long long: for 32-bit only")
  115. c0 = GcCache(False)
  116. S = lltype.GcStruct('S', ('y', lltype.UnsignedLongLong))
  117. descr = get_field_descr(c0, S, 'y')
  118. assert descr.flag == FLAG_FLOAT
  119. assert descr.field_size == 8
  120. def test_get_array_descr():
  121. U = lltype.Struct('U')
  122. T = lltype.GcStruct('T')
  123. A1 = lltype.GcArray(lltype.Char)
  124. A2 = lltype.GcArray(lltype.Ptr(T))
  125. A3 = lltype.GcArray(lltype.Ptr(U))
  126. A4 = lltype.GcArray(lltype.Float)
  127. A5 = lltype.GcArray(lltype.Struct('x', ('v', lltype.Signed),
  128. ('k', lltype.Signed)))
  129. A6 = lltype.GcArray(lltype.SingleFloat)
  130. #
  131. c0 = GcCache(False)
  132. descr1 = get_array_descr(c0, A1)
  133. descr2 = get_array_descr(c0, A2)
  134. descr3 = get_array_descr(c0, A3)
  135. descr4 = get_array_descr(c0, A4)
  136. descr5 = get_array_descr(c0, A5)
  137. descr6 = get_array_descr(c0, A6)
  138. assert isinstance(descr1, ArrayDescr)
  139. assert descr1 == get_array_descr(c0, lltype.GcArray(lltype.Char))
  140. assert descr1.flag == FLAG_UNSIGNED
  141. assert descr2.flag == FLAG_POINTER
  142. assert descr3.flag == FLAG_UNSIGNED
  143. assert descr4.flag == FLAG_FLOAT
  144. assert descr5.flag == FLAG_STRUCT
  145. assert descr6.flag == FLAG_UNSIGNED
  146. #
  147. def get_alignment(code):
  148. # Retrieve default alignment for the compiler/platform
  149. return struct.calcsize(lltype.SignedFmt + code) - struct.calcsize(code)
  150. assert descr1.basesize == get_alignment('c')
  151. assert descr2.basesize == get_alignment('p')
  152. assert descr3.basesize == get_alignment('p')
  153. assert descr4.basesize == get_alignment('d')
  154. assert descr5.basesize == get_alignment('f')
  155. assert descr1.lendescr.offset == 0
  156. assert descr2.lendescr.offset == 0
  157. assert descr3.lendescr.offset == 0
  158. assert descr4.lendescr.offset == 0
  159. assert descr5.lendescr.offset == 0
  160. assert descr1.itemsize == rffi.sizeof(lltype.Char)
  161. assert descr2.itemsize == rffi.sizeof(lltype.Ptr(T))
  162. assert descr3.itemsize == rffi.sizeof(lltype.Ptr(U))
  163. assert descr4.itemsize == rffi.sizeof(lltype.Float)
  164. assert descr5.itemsize == rffi.sizeof(lltype.Signed) * 2
  165. assert descr6.itemsize == rffi.sizeof(lltype.SingleFloat)
  166. #
  167. CA = rffi.CArray(lltype.Signed)
  168. descr = get_array_descr(c0, CA)
  169. assert descr.flag == FLAG_SIGNED
  170. assert descr.basesize == 0
  171. assert descr.lendescr is None
  172. CA = rffi.CArray(lltype.Ptr(lltype.GcStruct('S')))
  173. descr = get_array_descr(c0, CA)
  174. assert descr.flag == FLAG_POINTER
  175. assert descr.basesize == 0
  176. assert descr.lendescr is None
  177. CA = rffi.CArray(lltype.Ptr(lltype.Struct('S')))
  178. descr = get_array_descr(c0, CA)
  179. assert descr.flag == FLAG_UNSIGNED
  180. assert descr.basesize == 0
  181. assert descr.lendescr is None
  182. CA = rffi.CArray(lltype.Float)
  183. descr = get_array_descr(c0, CA)
  184. assert descr.flag == FLAG_FLOAT
  185. assert descr.basesize == 0
  186. assert descr.lendescr is None
  187. CA = rffi.CArray(rffi.FLOAT)
  188. descr = get_array_descr(c0, CA)
  189. assert descr.flag == FLAG_UNSIGNED
  190. assert descr.basesize == 0
  191. assert descr.itemsize == rffi.sizeof(lltype.SingleFloat)
  192. assert descr.lendescr is None
  193. def test_get_array_descr_sign():
  194. for RESTYPE, signed in [(rffi.SIGNEDCHAR, True), (rffi.UCHAR, False),
  195. (rffi.SHORT, True), (rffi.USHORT, False),
  196. (rffi.INT, True), (rffi.UINT, False),
  197. (rffi.LONG, True), (rffi.ULONG, False)]:
  198. A = lltype.GcArray(RESTYPE)
  199. for tsc in [False, True]:
  200. c2 = GcCache(tsc)
  201. arraydescr = get_array_descr(c2, A)
  202. assert arraydescr.flag == {False: FLAG_UNSIGNED,
  203. True: FLAG_SIGNED }[signed]
  204. #
  205. RA = rffi.CArray(RESTYPE)
  206. for tsc in [False, True]:
  207. c2 = GcCache(tsc)
  208. arraydescr = get_array_descr(c2, RA)
  209. assert arraydescr.flag == {False: FLAG_UNSIGNED,
  210. True: FLAG_SIGNED }[signed]
  211. def test_get_array_descr_str():
  212. c0 = GcCache(False)
  213. descr1 = get_array_descr(c0, rstr.STR)
  214. assert descr1.itemsize == rffi.sizeof(lltype.Char)
  215. assert descr1.flag == FLAG_UNSIGNED
  216. def test_get_call_descr_not_translated():
  217. c0 = GcCache(False)
  218. descr1 = get_call_descr(c0, [lltype.Char, lltype.Signed], lltype.Char)
  219. assert descr1.get_result_size() == rffi.sizeof(lltype.Char)
  220. assert descr1.get_result_type() == history.INT
  221. assert descr1.arg_classes == "ii"
  222. #
  223. T = lltype.GcStruct('T')
  224. descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T))
  225. assert descr2.get_result_size() == rffi.sizeof(lltype.Ptr(T))
  226. assert descr2.get_result_type() == history.REF
  227. assert descr2.arg_classes == "r"
  228. #
  229. U = lltype.GcStruct('U', ('x', lltype.Signed))
  230. assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U))
  231. #
  232. V = lltype.Struct('V', ('x', lltype.Signed))
  233. assert (get_call_descr(c0, [], lltype.Ptr(V)).get_result_type() ==
  234. history.INT)
  235. #
  236. assert (get_call_descr(c0, [], lltype.Void).get_result_type() ==
  237. history.VOID)
  238. #
  239. descr4 = get_call_descr(c0, [lltype.Float, lltype.Float], lltype.Float)
  240. assert descr4.get_result_size() == rffi.sizeof(lltype.Float)
  241. assert descr4.get_result_type() == history.FLOAT
  242. assert descr4.arg_classes == "ff"
  243. #
  244. descr5 = get_call_descr(c0, [lltype.SingleFloat], lltype.SingleFloat)
  245. assert descr5.get_result_size() == rffi.sizeof(lltype.SingleFloat)
  246. assert descr5.get_result_type() == "S"
  247. assert descr5.arg_classes == "S"
  248. def test_get_call_descr_not_translated_longlong():
  249. if sys.maxint > 2147483647:
  250. py.test.skip("long long: for 32-bit only")
  251. c0 = GcCache(False)
  252. #
  253. descr5 = get_call_descr(c0, [lltype.SignedLongLong], lltype.Signed)
  254. assert descr5.get_result_size() == 4
  255. assert descr5.get_result_type() == history.INT
  256. assert descr5.arg_classes == "L"
  257. #
  258. descr6 = get_call_descr(c0, [lltype.Signed], lltype.SignedLongLong)
  259. assert descr6.get_result_size() == 8
  260. assert descr6.get_result_type() == "L"
  261. assert descr6.arg_classes == "i"
  262. def test_get_call_descr_translated():
  263. c1 = GcCache(True)
  264. T = lltype.GcStruct('T')
  265. U = lltype.GcStruct('U', ('x', lltype.Signed))
  266. descr3 = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U))
  267. assert isinstance(descr3.get_result_size(), Symbolic)
  268. assert descr3.get_result_type() == history.REF
  269. assert descr3.arg_classes == "r"
  270. #
  271. descr4 = get_call_descr(c1, [lltype.Float, lltype.Float], lltype.Float)
  272. assert isinstance(descr4.get_result_size(), Symbolic)
  273. assert descr4.get_result_type() == history.FLOAT
  274. assert descr4.arg_classes == "ff"
  275. #
  276. descr5 = get_call_descr(c1, [lltype.SingleFloat], lltype.SingleFloat)
  277. assert isinstance(descr5.get_result_size(), Symbolic)
  278. assert descr5.get_result_type() == "S"
  279. assert descr5.arg_classes == "S"
  280. def test_call_descr_extra_info():
  281. c1 = GcCache(True)
  282. T = lltype.GcStruct('T')
  283. U = lltype.GcStruct('U', ('x', lltype.Signed))
  284. descr1 = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U), "hello")
  285. extrainfo = descr1.get_extra_info()
  286. assert extrainfo == "hello"
  287. descr2 = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U), "hello")
  288. assert descr1 is descr2
  289. descr3 = get_call_descr(c1, [lltype.Ptr(T)], lltype.Ptr(U))
  290. extrainfo = descr3.get_extra_info()
  291. assert extrainfo is None
  292. def test_get_call_descr_sign():
  293. for RESTYPE, signed in [(rffi.SIGNEDCHAR, True), (rffi.UCHAR, False),
  294. (rffi.SHORT, True), (rffi.USHORT, False),
  295. (rffi.INT, True), (rffi.UINT, False),
  296. (rffi.LONG, True), (rffi.ULONG, False)]:
  297. for tsc in [False, True]:
  298. c2 = GcCache(tsc)
  299. descr1 = get_call_descr(c2, [], RESTYPE)
  300. assert descr1.is_result_signed() == signed
  301. def test_repr_of_descr():
  302. def repr_of_descr(descr):
  303. s = descr.repr_of_descr()
  304. assert ',' not in s # makes the life easier for pypy.tool.jitlogparser
  305. return s
  306. c0 = GcCache(False)
  307. T = lltype.GcStruct('T')
  308. S = lltype.GcStruct('S', ('x', lltype.Char),
  309. ('y', lltype.Ptr(T)),
  310. ('z', lltype.Ptr(T)))
  311. descr1 = get_size_descr(c0, S)
  312. s = symbolic.get_size(S, False)
  313. assert repr_of_descr(descr1) == '<SizeDescr %d>' % s
  314. #
  315. descr2 = get_field_descr(c0, S, 'y')
  316. o, _ = symbolic.get_field_token(S, 'y', False)
  317. assert repr_of_descr(descr2) == '<FieldP S.y %d>' % o
  318. #
  319. descr2i = get_field_descr(c0, S, 'x')
  320. o, _ = symbolic.get_field_token(S, 'x', False)
  321. assert repr_of_descr(descr2i) == '<FieldU S.x %d>' % o
  322. #
  323. descr3 = get_array_descr(c0, lltype.GcArray(lltype.Ptr(S)))
  324. o = symbolic.get_size(lltype.Ptr(S), False)
  325. assert repr_of_descr(descr3) == '<ArrayP %d>' % o
  326. #
  327. descr3i = get_array_descr(c0, lltype.GcArray(lltype.Char))
  328. assert repr_of_descr(descr3i) == '<ArrayU 1>'
  329. #
  330. descr4 = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Ptr(S))
  331. assert repr_of_descr(descr4) == '<Callr %d ir>' % o
  332. #
  333. descr4i = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Char)
  334. assert repr_of_descr(descr4i) == '<Calli 1 ir>'
  335. #
  336. descr4f = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Float)
  337. assert repr_of_descr(descr4f) == '<Callf 8 ir>'
  338. #
  339. descr5f = get_call_descr(c0, [lltype.Char], lltype.SingleFloat)
  340. assert repr_of_descr(descr5f) == '<CallS 4 i>'
  341. def test_call_stubs_1():
  342. c0 = GcCache(False)
  343. ARGS = [lltype.Char, lltype.Signed]
  344. RES = lltype.Char
  345. descr1 = get_call_descr(c0, ARGS, RES)
  346. def f(a, b):
  347. return 'c'
  348. fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f)
  349. res = descr1.call_stub_i(rffi.cast(lltype.Signed, fnptr),
  350. [1, 2], None, None)
  351. assert res == ord('c')
  352. def test_call_stubs_2():
  353. c0 = GcCache(False)
  354. ARRAY = lltype.GcArray(lltype.Signed)
  355. ARGS = [lltype.Float, lltype.Ptr(ARRAY)]
  356. RES = lltype.Float
  357. def f2(a, b):
  358. return float(b[0]) + a
  359. fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f2)
  360. descr2 = get_call_descr(c0, ARGS, RES)
  361. a = lltype.malloc(ARRAY, 3)
  362. opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a)
  363. a[0] = 1
  364. res = descr2.call_stub_f(rffi.cast(lltype.Signed, fnptr),
  365. [], [opaquea], [longlong.getfloatstorage(3.5)])
  366. assert longlong.getrealfloat(res) == 4.5
  367. def test_call_stubs_single_float():
  368. from rpython.rlib.longlong2float import uint2singlefloat, singlefloat2uint
  369. from rpython.rlib.rarithmetic import r_singlefloat, intmask
  370. #
  371. c0 = GcCache(False)
  372. ARGS = [lltype.SingleFloat, lltype.SingleFloat, lltype.SingleFloat]
  373. RES = lltype.SingleFloat
  374. def f(a, b, c):
  375. a = float(a)
  376. b = float(b)
  377. c = float(c)
  378. x = a - (b / c)
  379. return r_singlefloat(x)
  380. fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f)
  381. descr2 = get_call_descr(c0, ARGS, RES)
  382. a = intmask(singlefloat2uint(r_singlefloat(-10.0)))
  383. b = intmask(singlefloat2uint(r_singlefloat(3.0)))
  384. c = intmask(singlefloat2uint(r_singlefloat(2.0)))
  385. res = descr2.call_stub_i(rffi.cast(lltype.Signed, fnptr),
  386. [a, b, c], [], [])
  387. assert float(uint2singlefloat(rffi.r_uint(res))) == -11.5
  388. def test_field_arraylen_descr():
  389. c0 = GcCache(True)
  390. A1 = lltype.GcArray(lltype.Signed)
  391. fielddescr = get_field_arraylen_descr(c0, A1)
  392. assert isinstance(fielddescr, FieldDescr)
  393. ofs = fielddescr.offset
  394. assert repr(ofs) == '< ArrayLengthOffset <GcArray of Signed > >'
  395. #
  396. fielddescr = get_field_arraylen_descr(c0, rstr.STR)
  397. ofs = fielddescr.offset
  398. assert repr(ofs) == ("< <FieldOffset <GcStruct rpy_string { hash, chars }>"
  399. " 'chars'> + < ArrayLengthOffset"
  400. " <Array of Char > > >")
  401. # caching:
  402. assert fielddescr is get_field_arraylen_descr(c0, rstr.STR)
  403. def test_bytearray_descr():
  404. c0 = GcCache(False)
  405. descr = get_array_descr(c0, rstr.STR) # for bytearray
  406. # note that we get a basesize that has 1 extra byte for the final null char
  407. # (only for STR)
  408. assert descr.flag == FLAG_UNSIGNED
  409. assert descr.basesize == struct.calcsize("PP") + 1 # hash, length, extra
  410. assert descr.lendescr.offset == struct.calcsize("P") # hash
  411. assert not descr.is_array_of_pointers()
  412. def test_descr_integer_bounded():
  413. descr = FieldDescr('descr', 0, symbolic.SIZEOF_CHAR, FLAG_SIGNED)
  414. assert descr.is_integer_bounded()
  415. descr = FieldDescr('descr', 0, symbolic.WORD, FLAG_UNSIGNED)
  416. assert not descr.is_integer_bounded()
  417. descr = FieldDescr('descr', 0, symbolic.SIZEOF_FLOAT, FLAG_FLOAT)
  418. assert not descr.is_integer_bounded()
  419. def test_descr_get_integer_bounds():
  420. descr = FieldDescr('decr', 0, 1, FLAG_UNSIGNED)
  421. assert descr.get_integer_min() == 0
  422. assert descr.get_integer_max() == 255
  423. descr = FieldDescr('descr', 0, 1, FLAG_SIGNED)
  424. assert descr.get_integer_min() == -128
  425. assert descr.get_integer_max() == 127
  426. def test_size_descr_stack_overflow_bug():
  427. c0 = GcCache(False)
  428. S = lltype.GcForwardReference()
  429. P = lltype.Ptr(S)
  430. fields = [('x%d' % i, P) for i in range(1500)]
  431. S.become(lltype.GcStruct('S', *fields))
  432. get_size_descr(c0, S)