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