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

/rpython/jit/metainterp/test/test_blackhole.py

https://bitbucket.org/pypy/pypy/
Python | 241 lines | 219 code | 17 blank | 5 comment | 12 complexity | 4fb48b6b42f2066ba22800b7d91c1304 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. from rpython.rlib.jit import JitDriver
  3. from rpython.jit.metainterp.test.support import LLJitMixin
  4. from rpython.jit.metainterp.blackhole import BlackholeInterpBuilder
  5. from rpython.jit.metainterp.blackhole import BlackholeInterpreter
  6. from rpython.jit.metainterp.blackhole import convert_and_run_from_pyjitpl
  7. from rpython.jit.metainterp import history, pyjitpl, jitexc, resoperation
  8. from rpython.jit.codewriter.assembler import JitCode
  9. from rpython.rtyper.lltypesystem import lltype, llmemory
  10. from rpython.rtyper.llinterp import LLException
  11. class FakeCodeWriter:
  12. pass
  13. class FakeAssembler:
  14. pass
  15. class FakeCPU:
  16. def bh_call_i(self, func, args_i, args_r, args_f, calldescr):
  17. assert func == 321
  18. assert calldescr == "<calldescr>"
  19. if args_i[0] < 0:
  20. raise LLException("etype", "evalue")
  21. return args_i[0] * 2
  22. def getblackholeinterp(insns, descrs=[]):
  23. cw = FakeCodeWriter()
  24. cw.cpu = FakeCPU()
  25. cw.assembler = FakeAssembler()
  26. cw.assembler.insns = insns
  27. cw.assembler.descrs = descrs
  28. builder = BlackholeInterpBuilder(cw)
  29. return builder.acquire_interp()
  30. def test_simple():
  31. jitcode = JitCode("test")
  32. jitcode.setup("\x00\x00\x01\x02"
  33. "\x01\x02",
  34. [])
  35. blackholeinterp = getblackholeinterp({'int_add/ii>i': 0,
  36. 'int_return/i': 1})
  37. blackholeinterp.setposition(jitcode, 0)
  38. blackholeinterp.setarg_i(0, 40)
  39. blackholeinterp.setarg_i(1, 2)
  40. blackholeinterp.run()
  41. assert blackholeinterp._final_result_anytype() == 42
  42. def test_simple_const():
  43. jitcode = JitCode("test")
  44. jitcode.setup("\x00\x30\x01\x02"
  45. "\x01\x02",
  46. [])
  47. blackholeinterp = getblackholeinterp({'int_sub/ci>i': 0,
  48. 'int_return/i': 1})
  49. blackholeinterp.setposition(jitcode, 0)
  50. blackholeinterp.setarg_i(1, 6)
  51. blackholeinterp.run()
  52. assert blackholeinterp._final_result_anytype() == 42
  53. def test_simple_bigconst():
  54. jitcode = JitCode("test")
  55. jitcode.setup("\x00\xFD\x01\x02"
  56. "\x01\x02",
  57. [666, 666, 10042, 666])
  58. blackholeinterp = getblackholeinterp({'int_sub/ii>i': 0,
  59. 'int_return/i': 1})
  60. blackholeinterp.setposition(jitcode, 0)
  61. blackholeinterp.setarg_i(1, 10000)
  62. blackholeinterp.run()
  63. assert blackholeinterp._final_result_anytype() == 42
  64. def test_simple_loop():
  65. jitcode = JitCode("test")
  66. jitcode.setup("\x00\x16\x02\x10\x00" # L1: goto_if_not_int_gt %i0, 2, L2
  67. "\x01\x17\x16\x17" # int_add %i1, %i0, %i1
  68. "\x02\x16\x01\x16" # int_sub %i0, $1, %i0
  69. "\x03\x00\x00" # goto L1
  70. "\x04\x17", # L2: int_return %i1
  71. [])
  72. blackholeinterp = getblackholeinterp({'goto_if_not_int_gt/icL': 0,
  73. 'int_add/ii>i': 1,
  74. 'int_sub/ic>i': 2,
  75. 'goto/L': 3,
  76. 'int_return/i': 4})
  77. blackholeinterp.setposition(jitcode, 0)
  78. blackholeinterp.setarg_i(0x16, 6) # %i0
  79. blackholeinterp.setarg_i(0x17, 100) # %i1
  80. blackholeinterp.run()
  81. assert blackholeinterp._final_result_anytype() == 100+6+5+4+3
  82. def test_simple_exception():
  83. jitcode = JitCode("test")
  84. jitcode.setup( # residual_call_ir_i $<* fn g>, I[%i9], R[], <Descr> %i8
  85. "\x01\xFF\x01\x09\x00\x00\x00\x08"
  86. "\x00\x0D\x00" # catch_exception L1
  87. "\x02\x08" # int_return %i8
  88. "\x03\x2A", # L1: int_return $42
  89. [321]) # <-- address of the function g
  90. blackholeinterp = getblackholeinterp({'catch_exception/L': 0,
  91. 'residual_call_ir_i/iIRd>i': 1,
  92. 'int_return/i': 2,
  93. 'int_return/c': 3},
  94. ["<calldescr>"])
  95. #
  96. blackholeinterp.setposition(jitcode, 0)
  97. blackholeinterp.setarg_i(0x9, 100)
  98. blackholeinterp.run()
  99. assert blackholeinterp._final_result_anytype() == 200
  100. #
  101. blackholeinterp.setposition(jitcode, 0)
  102. blackholeinterp.setarg_i(0x9, -100)
  103. blackholeinterp.run()
  104. assert blackholeinterp._final_result_anytype() == 42
  105. def test_convert_and_run_from_pyjitpl():
  106. class MyMIFrame:
  107. jitcode = JitCode("test")
  108. jitcode.setup("\xFF" # illegal instruction
  109. "\x00\x00\x01\x02" # int_add/ii>i
  110. "\x01\x02", # int_return/i
  111. [],
  112. num_regs_i=3, num_regs_r=0, num_regs_f=0)
  113. jitcode.jitdriver_sd = "foo" # not none
  114. pc = 1
  115. registers_i = [resoperation.InputArgInt(40), history.ConstInt(2), None]
  116. class MyMetaInterp:
  117. class staticdata:
  118. result_type = 'int'
  119. class profiler:
  120. @staticmethod
  121. def start_blackhole(): pass
  122. @staticmethod
  123. def end_blackhole(): pass
  124. last_exc_value = None
  125. framestack = [MyMIFrame()]
  126. MyMetaInterp.staticdata.blackholeinterpbuilder = getblackholeinterp(
  127. {'int_add/ii>i': 0, 'int_return/i': 1}).builder
  128. MyMetaInterp.staticdata.blackholeinterpbuilder.metainterp_sd = \
  129. MyMetaInterp.staticdata
  130. #
  131. d = py.test.raises(jitexc.DoneWithThisFrameInt,
  132. convert_and_run_from_pyjitpl, MyMetaInterp())
  133. assert d.value.result == 42
  134. class TestBlackhole(LLJitMixin):
  135. def test_blackholeinterp_cache_basic(self):
  136. class FakeJitcode:
  137. def num_regs_r(self):
  138. return 0
  139. interp1 = getblackholeinterp({})
  140. interp1.jitcode = FakeJitcode()
  141. builder = interp1.builder
  142. interp2 = builder.acquire_interp()
  143. builder.release_interp(interp1)
  144. interp3 = builder.acquire_interp()
  145. assert builder.num_interpreters == 2
  146. def test_blackholeinterp_cache_normal(self):
  147. myjitdriver = JitDriver(greens = [], reds = ['x', 'y'])
  148. def choices(x):
  149. if x == 0: # <- this is the test that eventually succeeds,
  150. return 0 # requiring a blackhole interp in a call stack
  151. return 34871 # of two functions (hence num_interpreters==2)
  152. def f(x):
  153. y = 0
  154. cont = 1
  155. while cont:
  156. myjitdriver.can_enter_jit(x=x, y=y)
  157. myjitdriver.jit_merge_point(x=x, y=y)
  158. cont = choices(x)
  159. y += cont
  160. x -= 1
  161. return y
  162. #
  163. seen = []
  164. def my_copy_constants(self, *args):
  165. seen.append(1)
  166. return org_copy_constants(self, *args)
  167. org_copy_constants = BlackholeInterpreter.copy_constants
  168. BlackholeInterpreter.copy_constants = my_copy_constants
  169. try:
  170. res = self.meta_interp(f, [7], repeat=7)
  171. finally:
  172. BlackholeInterpreter.copy_constants = org_copy_constants
  173. #
  174. assert res == sum([choices(x) for x in range(1, 8)])
  175. builder = pyjitpl._warmrunnerdesc.metainterp_sd.blackholeinterpbuilder
  176. assert builder.num_interpreters == 2
  177. assert len(seen) == 2 * 3
  178. def test_blackholeinterp_cache_exc(self):
  179. myjitdriver = JitDriver(greens = [], reds = ['x', 'y'])
  180. class FooError(Exception):
  181. def __init__(self, num):
  182. self.num = num
  183. def choices(x):
  184. if x == 0:
  185. raise FooError(0)
  186. raise FooError(34871)
  187. def f(x):
  188. y = 0
  189. while True:
  190. myjitdriver.can_enter_jit(x=x, y=y)
  191. myjitdriver.jit_merge_point(x=x, y=y)
  192. try:
  193. choices(x)
  194. except FooError as e:
  195. if e.num == 0:
  196. break
  197. y += e.num
  198. x -= 1
  199. return y
  200. res = self.meta_interp(f, [7], repeat=7)
  201. assert res == sum([py.test.raises(FooError, choices, x).value.num
  202. for x in range(1, 8)])
  203. builder = pyjitpl._warmrunnerdesc.metainterp_sd.blackholeinterpbuilder
  204. assert builder.num_interpreters == 2
  205. def test_bad_shift():
  206. py.test.raises(ValueError, BlackholeInterpreter.bhimpl_int_lshift.im_func, 7, 100)
  207. py.test.raises(ValueError, BlackholeInterpreter.bhimpl_int_rshift.im_func, 7, 100)
  208. py.test.raises(ValueError, BlackholeInterpreter.bhimpl_uint_rshift.im_func, 7, 100)
  209. py.test.raises(ValueError, BlackholeInterpreter.bhimpl_int_lshift.im_func, 7, -1)
  210. py.test.raises(ValueError, BlackholeInterpreter.bhimpl_int_rshift.im_func, 7, -1)
  211. py.test.raises(ValueError, BlackholeInterpreter.bhimpl_uint_rshift.im_func, 7, -1)
  212. assert BlackholeInterpreter.bhimpl_int_lshift.im_func(100, 3) == 100<<3
  213. assert BlackholeInterpreter.bhimpl_int_rshift.im_func(100, 3) == 100>>3
  214. assert BlackholeInterpreter.bhimpl_uint_rshift.im_func(100, 3) == 100>>3
  215. def test_debug_fatalerror():
  216. from rpython.rtyper.lltypesystem import lltype, llmemory, rstr
  217. from rpython.rtyper.llinterp import LLFatalError
  218. msg = rstr.mallocstr(1)
  219. msg.chars[0] = "!"
  220. msg = lltype.cast_opaque_ptr(llmemory.GCREF, msg)
  221. e = py.test.raises(LLFatalError,
  222. BlackholeInterpreter.bhimpl_debug_fatalerror.im_func,
  223. msg)
  224. assert str(e.value) == '!'