PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/pypy/pypy/
Python | 277 lines | 235 code | 30 blank | 12 comment | 12 complexity | e17586a6fce768b2383cdda114a61e71 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import sys
  2. from rpython.rtyper.lltypesystem import lltype, llmemory, rstr
  3. from rpython.rtyper.lltypesystem.lloperation import llop
  4. from rpython.rtyper.annlowlevel import llhelper
  5. from rpython.jit.backend.llsupport import jitframe, gc, descr
  6. from rpython.jit.backend.llsupport import symbolic
  7. from rpython.jit.metainterp.gc import get_description
  8. from rpython.jit.metainterp.history import ConstPtr
  9. from rpython.jit.metainterp.resoperation import get_deep_immutable_oplist, rop,\
  10. ResOperation, InputArgRef
  11. from rpython.rlib.rarithmetic import is_valid_int, r_uint
  12. def test_boehm():
  13. gc_ll_descr = gc.GcLLDescr_boehm(None, None, None)
  14. #
  15. record = []
  16. prev_malloc_fn_ptr = gc_ll_descr.malloc_fn_ptr
  17. def my_malloc_fn_ptr(size):
  18. p = prev_malloc_fn_ptr(size)
  19. record.append((size, p))
  20. return p
  21. gc_ll_descr.malloc_fn_ptr = my_malloc_fn_ptr
  22. #
  23. # ---------- gc_malloc ----------
  24. S = lltype.GcStruct('S', ('x', lltype.Signed))
  25. sizedescr = descr.get_size_descr(gc_ll_descr, S)
  26. p = gc_ll_descr.gc_malloc(sizedescr)
  27. assert record == [(sizedescr.size, p)]
  28. del record[:]
  29. # ---------- gc_malloc_array ----------
  30. A = lltype.GcArray(lltype.Signed)
  31. arraydescr = descr.get_array_descr(gc_ll_descr, A)
  32. p = gc_ll_descr.gc_malloc_array(10, arraydescr)
  33. assert record == [(arraydescr.basesize +
  34. 10 * arraydescr.itemsize, p)]
  35. del record[:]
  36. # ---------- gc_malloc_str ----------
  37. p = gc_ll_descr.gc_malloc_str(10)
  38. basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR, False)
  39. assert record == [(basesize + 10 * itemsize, p)]
  40. del record[:]
  41. # ---------- gc_malloc_unicode ----------
  42. p = gc_ll_descr.gc_malloc_unicode(10)
  43. basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
  44. False)
  45. assert record == [(basesize + 10 * itemsize, p)]
  46. del record[:]
  47. # ____________________________________________________________
  48. class FakeLLOp(object):
  49. def __init__(self):
  50. self.record = []
  51. def _malloc(self, type_id, size):
  52. tid = llop.combine_ushort(lltype.Signed, type_id, 0)
  53. x = llmemory.raw_malloc(self.gcheaderbuilder.size_gc_header + size)
  54. x += self.gcheaderbuilder.size_gc_header
  55. return x, tid
  56. def do_malloc_fixedsize(self, RESTYPE, type_id, size,
  57. has_finalizer, has_light_finalizer,
  58. contains_weakptr):
  59. assert not contains_weakptr
  60. assert not has_finalizer
  61. assert not has_light_finalizer
  62. p, tid = self._malloc(type_id, size)
  63. p = llmemory.cast_adr_to_ptr(p, RESTYPE)
  64. self.record.append(("fixedsize", repr(size), tid, p))
  65. return p
  66. do_malloc_fixedsize_clear = do_malloc_fixedsize
  67. def do_malloc_varsize(self, RESTYPE, type_id, length, size,
  68. itemsize, offset_to_length):
  69. p, tid = self._malloc(type_id, size + itemsize * length)
  70. (p + offset_to_length).signed[0] = length
  71. p = llmemory.cast_adr_to_ptr(p, RESTYPE)
  72. self.record.append(("varsize", tid, length,
  73. repr(size), repr(itemsize),
  74. repr(offset_to_length), p))
  75. return p
  76. do_malloc_varsize_clear = do_malloc_varsize
  77. def _write_barrier_failing_case(self, adr_struct):
  78. self.record.append(('barrier', adr_struct))
  79. def get_write_barrier_failing_case(self, FPTRTYPE):
  80. return llhelper(FPTRTYPE, self._write_barrier_failing_case)
  81. _have_wb_from_array = False
  82. def _write_barrier_from_array_failing_case(self, adr_struct, v_index):
  83. self.record.append(('barrier_from_array', adr_struct, v_index))
  84. def get_write_barrier_from_array_failing_case(self, FPTRTYPE):
  85. if self._have_wb_from_array:
  86. return llhelper(FPTRTYPE,
  87. self._write_barrier_from_array_failing_case)
  88. else:
  89. return lltype.nullptr(FPTRTYPE.TO)
  90. class TestFramework(object):
  91. gc = 'minimark'
  92. def setup_method(self, meth):
  93. class config_(object):
  94. class translation(object):
  95. gc = self.gc
  96. gcrootfinder = 'asmgcc'
  97. gctransformer = 'framework'
  98. gcremovetypeptr = False
  99. class FakeTranslator(object):
  100. config = config_
  101. class FakeCPU(object):
  102. def cast_adr_to_int(self, adr):
  103. if not adr:
  104. return 0
  105. try:
  106. ptr = llmemory.cast_adr_to_ptr(adr, gc_ll_descr.WB_FUNCPTR)
  107. assert ptr._obj._callable == \
  108. llop1._write_barrier_failing_case
  109. return 42
  110. except lltype.InvalidCast:
  111. ptr = llmemory.cast_adr_to_ptr(
  112. adr, gc_ll_descr.WB_ARRAY_FUNCPTR)
  113. assert ptr._obj._callable == \
  114. llop1._write_barrier_from_array_failing_case
  115. return 43
  116. gcdescr = get_description(config_)
  117. llop1 = FakeLLOp()
  118. gc_ll_descr = gc.GcLLDescr_framework(gcdescr, FakeTranslator(), None,
  119. llop1)
  120. gc_ll_descr.initialize()
  121. llop1.gcheaderbuilder = gc_ll_descr.gcheaderbuilder
  122. self.llop1 = llop1
  123. self.gc_ll_descr = gc_ll_descr
  124. self.fake_cpu = FakeCPU()
  125. def test_gc_malloc(self):
  126. S = lltype.GcStruct('S', ('x', lltype.Signed))
  127. sizedescr = descr.get_size_descr(self.gc_ll_descr, S)
  128. p = self.gc_ll_descr.gc_malloc(sizedescr)
  129. assert lltype.typeOf(p) == llmemory.GCREF
  130. assert self.llop1.record == [("fixedsize", repr(sizedescr.size),
  131. sizedescr.tid, p)]
  132. def test_gc_malloc_array(self):
  133. A = lltype.GcArray(lltype.Signed)
  134. arraydescr = descr.get_array_descr(self.gc_ll_descr, A)
  135. p = self.gc_ll_descr.gc_malloc_array(10, arraydescr)
  136. assert self.llop1.record == [("varsize", arraydescr.tid, 10,
  137. repr(arraydescr.basesize),
  138. repr(arraydescr.itemsize),
  139. repr(arraydescr.lendescr.offset),
  140. p)]
  141. def test_gc_malloc_str(self):
  142. p = self.gc_ll_descr.gc_malloc_str(10)
  143. type_id = self.gc_ll_descr.layoutbuilder.get_type_id(rstr.STR)
  144. tid = llop.combine_ushort(lltype.Signed, type_id, 0)
  145. basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
  146. True)
  147. assert self.llop1.record == [("varsize", tid, 10,
  148. repr(basesize), repr(itemsize),
  149. repr(ofs_length), p)]
  150. def test_gc_malloc_unicode(self):
  151. p = self.gc_ll_descr.gc_malloc_unicode(10)
  152. type_id = self.gc_ll_descr.layoutbuilder.get_type_id(rstr.UNICODE)
  153. tid = llop.combine_ushort(lltype.Signed, type_id, 0)
  154. basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
  155. True)
  156. assert self.llop1.record == [("varsize", tid, 10,
  157. repr(basesize), repr(itemsize),
  158. repr(ofs_length), p)]
  159. def test_gen_write_barrier(self):
  160. gc_ll_descr = self.gc_ll_descr
  161. llop1 = self.llop1
  162. #
  163. rewriter = gc.GcRewriterAssembler(gc_ll_descr, None)
  164. newops = rewriter._newops
  165. v_base = InputArgRef()
  166. rewriter.gen_write_barrier(v_base)
  167. assert llop1.record == []
  168. assert len(newops) == 1
  169. assert newops[0].getopnum() == rop.COND_CALL_GC_WB
  170. assert newops[0].getarg(0) == v_base
  171. wbdescr = newops[0].getdescr()
  172. assert is_valid_int(wbdescr.jit_wb_if_flag)
  173. assert is_valid_int(wbdescr.jit_wb_if_flag_byteofs)
  174. assert is_valid_int(wbdescr.jit_wb_if_flag_singlebyte)
  175. class TestFrameworkMiniMark(TestFramework):
  176. gc = 'minimark'
  177. def test_custom_tracer():
  178. def indexof(no):
  179. return (frame_adr + jitframe.getofs('jf_frame') +
  180. jitframe.BASEITEMOFS + jitframe.SIGN_SIZE * no)
  181. frame_info = lltype.malloc(jitframe.JITFRAMEINFO, zero=True, flavor='raw')
  182. frame = lltype.malloc(jitframe.JITFRAME, 200, zero=True)
  183. frame.jf_frame_info = frame_info
  184. frame.jf_gcmap = lltype.malloc(jitframe.GCMAP, 4, flavor='raw')
  185. if sys.maxint == 2**31 - 1:
  186. max = r_uint(2 ** 31)
  187. else:
  188. max = r_uint(2 ** 63)
  189. frame.jf_gcmap[0] = r_uint(1 | 2 | 8 | 32 | 128) | max
  190. frame.jf_gcmap[1] = r_uint(0)
  191. frame.jf_gcmap[2] = r_uint(2 | 16 | 32 | 128)
  192. frame.jf_gcmap[3] = r_uint(0)
  193. frame_adr = llmemory.cast_ptr_to_adr(frame)
  194. #
  195. all_addrs = []
  196. class FakeGC:
  197. def _trace_callback(self, callback, arg, addr):
  198. assert callback == "hello"
  199. assert arg == "world"
  200. all_addrs.append(addr)
  201. jitframe.jitframe_trace(FakeGC(), frame_adr, "hello", "world")
  202. #
  203. counter = 0
  204. for name in jitframe.JITFRAME._names:
  205. TP = getattr(jitframe.JITFRAME, name)
  206. if isinstance(TP, lltype.Ptr) and TP.TO._gckind == 'gc':
  207. assert all_addrs[counter] == frame_adr + jitframe.getofs(name)
  208. counter += 1
  209. assert counter == 5
  210. # gcpattern
  211. assert all_addrs[5] == indexof(0)
  212. assert all_addrs[6] == indexof(1)
  213. assert all_addrs[7] == indexof(3)
  214. assert all_addrs[8] == indexof(5)
  215. assert all_addrs[9] == indexof(7)
  216. if sys.maxint == 2**31 - 1:
  217. assert all_addrs[10] == indexof(31)
  218. assert all_addrs[11] == indexof(65)
  219. assert all_addrs[12] == indexof(68)
  220. assert all_addrs[13] == indexof(69)
  221. assert all_addrs[14] == indexof(71)
  222. else:
  223. assert all_addrs[10] == indexof(63)
  224. assert all_addrs[11] == indexof(129)
  225. assert all_addrs[12] == indexof(132)
  226. assert all_addrs[13] == indexof(133)
  227. assert all_addrs[14] == indexof(135)
  228. assert len(all_addrs) == 15
  229. lltype.free(frame_info, flavor='raw')
  230. lltype.free(frame.jf_gcmap, flavor='raw')
  231. def test_custom_tracer_2():
  232. frame_info = lltype.malloc(jitframe.JITFRAMEINFO, zero=True, flavor='raw')
  233. frame = lltype.malloc(jitframe.JITFRAME, 200, zero=True)
  234. frame.jf_frame_info = frame_info
  235. frame.jf_gcmap = lltype.malloc(jitframe.GCMAP, 3, flavor='raw')
  236. frame.jf_gcmap[0] = r_uint(18446744073441116160)
  237. frame.jf_gcmap[1] = r_uint(18446740775107559407)
  238. frame.jf_gcmap[2] = r_uint(3)
  239. frame_adr = llmemory.cast_ptr_to_adr(frame)
  240. class FakeGC:
  241. def _trace_callback(self, callback, arg, addr):
  242. assert callback == "hello"
  243. assert arg == "world"
  244. jitframe.jitframe_trace(FakeGC(), frame_adr, "hello", "world")
  245. # assert did not hang
  246. lltype.free(frame_info, flavor='raw')
  247. lltype.free(frame.jf_gcmap, flavor='raw')