class CustomBaseTestRegalloc(BaseTestRegalloc): cpu = CPU(None, None) cpu.setup_once() def raising_func(i): if i: raise LLException(zero_division_error, zero_division_value) FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) raising_fptr = llhelper(FPTR, raising_func) def f(a): return 23 FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) f_fptr = llhelper(FPTR, f) f_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT, EffectInfo.MOST_GENERAL) zero_division_tp, zero_division_value = get_zero_division_error(cpu) zd_addr = cpu.cast_int_to_adr(zero_division_tp) zero_division_error = llmemory.cast_adr_to_ptr( zd_addr, lltype.Ptr(rclass.OBJECT_VTABLE)) raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT, EffectInfo.MOST_GENERAL) targettoken = TargetToken() targettoken2 = TargetToken() fdescr1 = BasicFailDescr(1) fdescr2 = BasicFailDescr(2) fdescr3 = BasicFailDescr(3) def setup_method(self, meth): self.targettoken._ll_loop_code = 0 self.targettoken2._ll_loop_code = 0 def f1(x): return x + 1 def f2(x, y): return x * y def f10(*args): assert len(args) == 10 return sum(args) F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 2, lltype.Signed)) F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 10, lltype.Signed)) f1ptr = llhelper(F1PTR, f1) f2ptr = llhelper(F2PTR, f2) f10ptr = llhelper(F10PTR, f10) f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT, EffectInfo.MOST_GENERAL) f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT, EffectInfo.MOST_GENERAL) f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL) namespace = locals().copy()
def compile_simple_loop(metainterp, greenkey, trace, runtime_args, enable_opts, cut_at): from rpython.jit.metainterp.optimizeopt import optimize_trace jitdriver_sd = metainterp.jitdriver_sd metainterp_sd = metainterp.staticdata jitcell_token = make_jitcell_token(jitdriver_sd) call_pure_results = metainterp.call_pure_results data = SimpleCompileData(trace, call_pure_results=call_pure_results, enable_opts=enable_opts) try: loop_info, ops = optimize_trace(metainterp_sd, jitdriver_sd, data, metainterp.box_names_memo) except InvalidLoop: trace.cut_at(cut_at) return None loop = create_empty_loop(metainterp) loop.original_jitcell_token = jitcell_token loop.inputargs = loop_info.inputargs if loop_info.quasi_immutable_deps: loop.quasi_immutable_deps = loop_info.quasi_immutable_deps jump_op = ops[-1] target_token = TargetToken(jitcell_token) target_token.original_jitcell_token = jitcell_token label = ResOperation(rop.LABEL, loop_info.inputargs[:], descr=target_token) jump_op.setdescr(target_token) loop.operations = [label] + ops if not we_are_translated(): loop.check_consistency() jitcell_token.target_tokens = [target_token] send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop", runtime_args, metainterp.box_names_memo) record_loop_or_bridge(metainterp_sd, loop) return target_token
def parse_loop(self, ops, add_label=True): loop = self.parse(ops) loop.operations = filter( lambda op: op.getopnum() != rop.DEBUG_MERGE_POINT, loop.operations) token = JitCellToken() if add_label: label = ResOperation(rop.LABEL, loop.inputargs, descr=TargetToken(token)) else: label = loop.operations[0] label.setdescr(TargetToken(token)) jump = loop.operations[-1] loop = VectorLoop(label, loop.operations[0:-1], jump) loop.jump.setdescr(token) class Optimizer(object): metainterp_sd = FakeMetaInterpStaticData(self.cpu) jitdriver_sd = FakeJitDriverStaticData() opt = Optimizer() opt.jitdriver_sd.vec = True for op in loop.operations: if op.is_guard() and not op.getdescr(): descr = invent_fail_descr_for_op(op.getopnum(), opt) op.setdescr(descr) return loop
def optimize(self, ops, bridge_ops, expected, expected_loop=None, inline_short_preamble=True, jump_values=None, bridge_values=None): loop = self.parse(ops) info = self.unroll_and_optimize(loop, None, jump_values=jump_values) jitcell_token = compile.make_jitcell_token(None) mid_label_descr = TargetToken(jitcell_token) mid_label_descr.short_preamble = info.short_preamble mid_label_descr.virtual_state = info.virtual_state start_label_descr = TargetToken(jitcell_token) jitcell_token.target_tokens = [mid_label_descr, start_label_descr] loop.operations[0].setdescr(mid_label_descr) loop.operations[-1].setdescr(mid_label_descr) info.preamble.operations[0].setdescr(start_label_descr) guards = [op for op in loop.operations if op.is_guard()] assert len(guards) == 1, "more than one guard in the loop" bridge = self.parse(bridge_ops) bridge.operations[-1].setdescr(jitcell_token) self.add_guard_future_condition(bridge) trace = oparser.convert_loop_to_trace( bridge, FakeMetaInterpStaticData(self.cpu)) data = compile.BridgeCompileData( trace, self.convert_values(bridge.operations[-1].getarglist(), bridge_values), None, enable_opts=self.enable_opts, inline_short_preamble=inline_short_preamble) bridge_info, ops = self._do_optimize_loop(data) loop.check_consistency(check_descr=False) info.preamble.check_consistency(check_descr=False) bridge.operations = ([ResOperation(rop.LABEL, bridge_info.inputargs)] + ops) bridge.inputargs = bridge_info.inputargs bridge.check_consistency(check_descr=False) expected = self.parse(expected) self.assert_equal(bridge, convert_old_style_to_targets(expected, jump=True)) jump_bridge = bridge.operations[-1] jump_d = jump_bridge.getdescr() jump_args = jump_bridge.getarglist() if loop.operations[0].getdescr() is jump_d: # jump to loop label_args = loop.operations[0].getarglist() else: assert info.preamble.operations[0].getdescr() is jump_d label_args = info.preamble.operations[0].getarglist() assert len(jump_args) == len(label_args) for a, b in zip(jump_args, label_args): assert a.type == b.type
def optimize(self, ops, bridge_ops, expected, expected_loop=None, inline_short_preamble=True, jump_values=None, bridge_values=None): loop = self.parse(ops, postprocess=self.postprocess) self.set_values(loop.operations, jump_values) if expected_loop is not None: xxx exp_loop = self.parse(expected_loop, postprocess=self.postprocess) self.assert_equal(loop, convert_old_style_to_targets(exp_loop)) info = self.unroll_and_optimize(loop, None) jitcell_token = compile.make_jitcell_token(None) mid_label_descr = TargetToken(jitcell_token) mid_label_descr.short_preamble = info.short_preamble mid_label_descr.virtual_state = info.virtual_state start_label_descr = TargetToken(jitcell_token) jitcell_token.target_tokens = [mid_label_descr, start_label_descr] loop.operations[0].setdescr(mid_label_descr) loop.operations[-1].setdescr(mid_label_descr) info.preamble.operations[0].setdescr(start_label_descr) guards = [op for op in loop.operations if op.is_guard()] assert len(guards) == 1, "more than one guard in the loop" bridge = self.parse(bridge_ops, postprocess=self.postprocess) self.set_values(bridge.operations, bridge_values) start_label = ResOperation(rop.LABEL, bridge.inputargs) bridge.operations[-1].setdescr(jitcell_token) self.add_guard_future_condition(bridge) data = compile.BridgeCompileData(start_label, bridge.operations, enable_opts=self.enable_opts, inline_short_preamble=inline_short_preamble) bridge_info, ops = self._do_optimize_loop(data) loop.check_consistency(check_descr=False) info.preamble.check_consistency(check_descr=False) bridge.operations = ([ResOperation(rop.LABEL, bridge_info.inputargs)] + ops) bridge.inputargs = bridge_info.inputargs bridge.check_consistency(check_descr=False) expected = self.parse(expected, postprocess=self.postprocess) self.assert_equal(bridge, convert_old_style_to_targets(expected, jump=True)) jump_bridge = bridge.operations[-1] jump_d = jump_bridge.getdescr() jump_args = jump_bridge.getarglist() if loop.operations[0].getdescr() is jump_d: # jump to loop label_args = loop.operations[0].getarglist() else: assert info.preamble.operations[0].getdescr() is jump_d label_args = info.preamble.operations[0].getarglist() assert len(jump_args) == len(label_args) for a, b in zip(jump_args, label_args): assert a.type == b.type
def test_result_is_spilled(self): cpu = self.cpu inp = [InputArgInt(i) for i in range(1, 15)] looptoken = JitCellToken() targettoken = TargetToken() operations = [ ResOperation(rop.LABEL, inp, descr=targettoken), ResOperation(rop.INT_ADD, [inp[0], inp[1]]), ResOperation(rop.INT_ADD, [inp[2], inp[3]]), ResOperation(rop.INT_ADD, [inp[4], inp[5]]), ResOperation(rop.INT_ADD, [inp[6], inp[7]]), ResOperation(rop.INT_ADD, [inp[8], inp[9]]), ResOperation(rop.INT_ADD, [inp[10], inp[11]]), ResOperation(rop.INT_ADD, [inp[12], inp[13]]), ResOperation(rop.INT_ADD, [inp[0], inp[1]]), ResOperation(rop.INT_ADD, [inp[2], inp[3]]), ResOperation(rop.INT_ADD, [inp[4], inp[5]]), ResOperation(rop.INT_ADD, [inp[6], inp[7]]), ResOperation(rop.INT_ADD, [inp[8], inp[9]]), ResOperation(rop.INT_ADD, [inp[10], inp[11]]), ResOperation(rop.INT_ADD, [inp[12], inp[13]]), ResOperation(rop.GUARD_FALSE, [inp[1]], descr=BasicFailDescr(1)), ResOperation(rop.FINISH, [inp[1]], descr=BasicFinalDescr(1)), ] operations[-2].setfailargs(operations[1:15]) cpu.compile_loop(inp, operations, looptoken) args = [i for i in range(1, 15)] deadframe = self.cpu.execute_token(looptoken, *args) output = [ self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15) ] expected = [3, 7, 11, 15, 19, 23, 27, 3, 7, 11, 15, 19, 23, 27] assert output == expected
def test_compile_more_than_32k(self): # the guard_true needs a "b.cond" jumping forward more than 32 kb looptoken = JitCellToken() targettoken = TargetToken() ops = [ '[i0]', 'label(i0, descr=targettoken)', 'i1 = int_le(i0, 9)', 'guard_true(i1, descr=faildescr) [i0]', ] NUM = 8193 iprevious = 'i0' for i in range(NUM): inext = 'i%d' % (i + 2, ) ops.append('%s = int_add(%s, 1)' % (inext, iprevious)) iprevious = inext ops.append('jump(%s, descr=targettoken)' % (iprevious, )) loop = parse('\n'.join(ops), namespace={ 'targettoken': targettoken, 'faildescr': BasicFailDescr(5) }) self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, -42) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 5 res = self.cpu.get_int_value(deadframe, 0) assert res == -42 + NUM
def test_unicodesetitem_really_needs_temploc(self): u_box = self.alloc_unicode(u"abcdsdasdsaddefg") targettoken = TargetToken() finaldescr = BasicFinalDescr(1) loop = parse(''' [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, p10] label(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, p10, descr=targettoken) unicodesetitem(p10, i6, 123) i11 = int_add(i0, i1) i12 = int_add(i11, i2) i13 = int_add(i12, i3) i14 = int_add(i13, i4) i15 = int_add(i14, i5) i16 = int_add(i15, i6) i17 = int_add(i16, i7) i18 = int_add(i17, i8) i19 = int_add(i18, i9) finish(i19, descr=finaldescr) ''', namespace={ 'targettoken': targettoken, 'finaldescr': finaldescr }) looptoken = JitCellToken() args = [(i + 1) for i in range(10)] + [u_box.getref_base()] self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) deadframe = self.cpu.execute_token(looptoken, *args) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 1 res = self.cpu.get_int_value(deadframe, 0) assert res == sum(args[:10])
def finalize_short_preamble(self, label_op, virtual_state): sb = self.short_preamble_producer self.optimizer._clean_optimization_info(sb.short_inputargs) short_preamble = sb.build_short_preamble() jitcelltoken = label_op.getdescr() assert isinstance(jitcelltoken, JitCellToken) if jitcelltoken.target_tokens is None: jitcelltoken.target_tokens = [] target_token = TargetToken(jitcelltoken, original_jitcell_token=jitcelltoken) target_token.original_jitcell_token = jitcelltoken target_token.virtual_state = virtual_state target_token.short_preamble = short_preamble jitcelltoken.target_tokens.append(target_token) self.short_preamble_producer = ExtendedShortPreambleBuilder( target_token, sb) label_op.initarglist(label_op.getarglist() + sb.used_boxes) return target_token
def test_debugger_on(self): from rpython.tool.logparser import parse_log_file, extract_category from rpython.rlib import debug targettoken, preambletoken = TargetToken(), TargetToken() loop = """ [i0] label(i0, descr=preambletoken) debug_merge_point('xyz', 0, 0) i1 = int_add(i0, 1) i2 = int_ge(i1, 10) guard_false(i2) [] label(i1, descr=targettoken) debug_merge_point('xyz', 0, 0) i11 = int_add(i1, 1) i12 = int_ge(i11, 10) guard_false(i12) [] jump(i11, descr=targettoken) """ ops = parse(loop, namespace={ 'targettoken': targettoken, 'preambletoken': preambletoken }) debug._log = dlog = debug.DebugLog() try: self.cpu.assembler.set_debug(True) looptoken = JitCellToken() self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) self.cpu.execute_token(looptoken, 0) # check debugging info struct = self.cpu.assembler.get_loop_run_counters(0) assert struct.i == 1 struct = self.cpu.assembler.get_loop_run_counters(1) assert struct.i == 1 struct = self.cpu.assembler.get_loop_run_counters(2) assert struct.i == 9 self.cpu.finish_once() finally: debug._log = None l0 = ('debug_print', 'entry -1:1') l1 = ('debug_print', preambletoken.repr_of_descr() + ':1') l2 = ('debug_print', targettoken.repr_of_descr() + ':9') assert ('jit-backend-counts', [l0, l1, l2]) in dlog
def test_debugger_on(self): py.test.skip("I don't care for now") from rpython.rlib import debug targettoken, preambletoken = TargetToken(), TargetToken() loop = """ [i0] label(i0, descr=preambletoken) debug_merge_point('xyz', 0) i1 = int_add(i0, 1) i2 = int_ge(i1, 10) guard_false(i2) [] label(i1, descr=targettoken) debug_merge_point('xyz', 0) i11 = int_add(i1, 1) i12 = int_ge(i11, 10) guard_false(i12) [] jump(i11, descr=targettoken) """ ops = parse(loop, namespace={'targettoken': targettoken, 'preambletoken': preambletoken}) debug._log = dlog = debug.DebugLog() try: self.cpu.assembler.set_debug(True) looptoken = JitCellToken() self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken) self.cpu.execute_token(looptoken, 0) # check debugging info struct = self.cpu.assembler.loop_run_counters[0] assert struct.i == 1 struct = self.cpu.assembler.loop_run_counters[1] assert struct.i == 1 struct = self.cpu.assembler.loop_run_counters[2] assert struct.i == 9 self.cpu.finish_once() finally: debug._log = None l0 = ('debug_print', 'entry -1:1') l1 = ('debug_print', preambletoken.repr_of_descr() + ':1') l2 = ('debug_print', targettoken.repr_of_descr() + ':9') assert ('jit-backend-counts', [l0, l1, l2]) in dlog
def finaloplist(self, jitcell_token=None, reset_label_token=True, label=False): oplist = [] if jitcell_token: if reset_label_token: token = TargetToken(jitcell_token) token.original_jitcell_token = jitcell_token jitcell_token.target_tokens.append(token) self.label.setdescr(token) else: token = self.jump.getdescr() assert isinstance(token, TargetToken) if self.prefix_label: token = TargetToken(jitcell_token) token.original_jitcell_token = jitcell_token jitcell_token.target_tokens.append(token) self.prefix_label.setdescr(token) self.jump.setdescr(token) if reset_label_token: self.jump.setdescr(token) if self.prefix_label: oplist = self.prefix + [self.prefix_label] elif self.prefix: oplist = self.prefix if label: oplist = [self.label] + oplist return oplist + self.operations + [self.jump]
def unroll_and_optimize(self, loop, call_pure_results=None): self.add_guard_future_condition(loop) operations = loop.operations jumpop = operations[-1] assert jumpop.getopnum() == rop.JUMP inputargs = loop.inputargs jump_args = jumpop.getarglist()[:] operations = operations[:-1] cloned_operations = [op.clone() for op in operations] preamble = TreeLoop('preamble') preamble.inputargs = inputargs token = JitCellToken() preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \ operations + \ [ResOperation(rop.LABEL, jump_args, None, descr=token)] start_state = self._do_optimize_loop(preamble, call_pure_results, export_state=True) assert preamble.operations[-1].getopnum() == rop.LABEL inliner = Inliner(inputargs, jump_args) loop.operations = [preamble.operations[-1]] + \ [inliner.inline_op(op, clone=False) for op in cloned_operations] + \ [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args], None, descr=token)] #[inliner.inline_op(jumpop)] assert loop.operations[-1].getopnum() == rop.JUMP assert loop.operations[0].getopnum() == rop.LABEL loop.inputargs = loop.operations[0].getarglist() self._do_optimize_loop(loop, call_pure_results, start_state, export_state=False) extra_same_as = [] while loop.operations[0].getopnum() != rop.LABEL: extra_same_as.append(loop.operations[0]) del loop.operations[0] # Hack to prevent random order of same_as ops extra_same_as.sort( key=lambda op: str(preamble.operations).find(str(op.getarg(0)))) for op in extra_same_as: preamble.operations.insert(-1, op) return preamble
def insert_label(self, loop, position, r): assert not hasattr(loop, '_targettoken') for i in range(position): op = loop.operations[i] if (not rop.has_no_side_effect(op.opnum) or op.type not in (INT, FLOAT)): position = i break # cannot move the LABEL later randompos = r.randrange(0, len(self.startvars) + 1) self.startvars.insert(randompos, op) loop._targettoken = TargetToken() loop.operations.insert( position, ResOperation(rop.LABEL, self.startvars, loop._targettoken))
def insert_label(self, loop, position, r): assert not hasattr(loop, '_targettoken') for i in range(position): op = loop.operations[i] if (not op.has_no_side_effect() or not isinstance(op.result, (BoxInt, BoxFloat))): position = i break # cannot move the LABEL later randompos = r.randrange(0, len(self.startvars) + 1) self.startvars.insert(randompos, op.result) loop._targettoken = TargetToken() loop.operations.insert( position, ResOperation(rop.LABEL, self.startvars, None, loop._targettoken))
def test_label_float_in_reg_and_on_stack(self): targettoken = TargetToken() ops = """ [i0, f3] i2 = same_as_i(i0) # but forced to be in a register force_spill(i2) force_spill(f3) f4 = float_add(f3, 5.0) label(f3, f4, descr=targettoken) force_spill(f3) f5 = same_as_f(f3) # but forced to be in a register finish(f5) """ faildescr = BasicFailDescr(2) loop = parse(ops, self.cpu, namespace=locals()) looptoken = JitCellToken() info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ops2 = """ [i0, f1] i1 = same_as_i(i0) f2 = same_as_f(f1) f3 = float_add(f1, 10.0) force_spill(f3) force_spill(i1) f4 = float_add(f3, f1) jump(f3, f4, descr=targettoken) """ loop2 = parse(ops2, self.cpu, namespace=locals()) looptoken2 = JitCellToken() info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2) deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) assert res == -13.5 # deadframe = self.cpu.execute_token(looptoken2, -9, longlong.getfloatstorage(-13.5)) res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0)) assert res == -3.5
def test_ops_offset(self): from rpython.rlib import debug looptoken = JitCellToken() targettoken = TargetToken() loop = parse(""" [i0] label(i0, descr=targettoken) i1 = int_add(i0, 1) i2 = int_le(i1, 9) jump(i1, descr=targettoken) """, namespace=locals()) debug._log = dlog = debug.DebugLog() info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) ops_offset = info.ops_offset debug._log = None # assert ops_offset is looptoken._x86_ops_offset # 2*increment_debug_counter + ops + None assert len(ops_offset) == 2 + len(loop.operations) + 1 assert (ops_offset[loop.operations[0]] <= ops_offset[loop.operations[1]] <= ops_offset[loop.operations[2]] <= ops_offset[None])
def test_ops_offset(self): from rpython.rlib import debug i0 = BoxInt() i1 = BoxInt() i2 = BoxInt() looptoken = JitCellToken() targettoken = TargetToken() operations = [ ResOperation(rop.LABEL, [i0], None, descr=targettoken), ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2), ResOperation(rop.JUMP, [i1], None, descr=targettoken), ] inputargs = [i0] debug._log = dlog = debug.DebugLog() info = self.cpu.compile_loop(inputargs, operations, looptoken) ops_offset = info.ops_offset debug._log = None # assert ops_offset is looptoken._x86_ops_offset # 2*increment_debug_counter + ops + None assert len(ops_offset) == 2 + len(operations) + 1 assert (ops_offset[operations[0]] <= ops_offset[operations[1]] <= ops_offset[operations[2]] <= ops_offset[None])
def propagate_all_forward(self, starting_state, export_state=True): self.optimizer.exporting_state = export_state loop = self.optimizer.loop self.optimizer.clear_newoperations() start_label = loop.operations[0] if start_label.getopnum() == rop.LABEL: loop.operations = loop.operations[1:] # We need to emit the label op before import_state() as emitting it # will clear heap caches self.optimizer.send_extra_operation(start_label) else: start_label = None patchguardop = None if len(loop.operations) > 1: patchguardop = loop.operations[-2] if patchguardop.getopnum() != rop.GUARD_FUTURE_CONDITION: patchguardop = None jumpop = loop.operations[-1] if jumpop.getopnum() == rop.JUMP or jumpop.getopnum() == rop.LABEL: loop.operations = loop.operations[:-1] else: jumpop = None self.import_state(start_label, starting_state) self.optimizer.propagate_all_forward(clear=False) if not jumpop: return cell_token = jumpop.getdescr() assert isinstance(cell_token, JitCellToken) stop_label = ResOperation(rop.LABEL, jumpop.getarglist(), None, TargetToken(cell_token)) if jumpop.getopnum() == rop.JUMP: if self.jump_to_already_compiled_trace(jumpop, patchguardop): # Found a compiled trace to jump to if self.short: # Construct our short preamble assert start_label self.close_bridge(start_label) return if start_label and self.jump_to_start_label(start_label, stop_label): # Initial label matches, jump to it jumpop = ResOperation(rop.JUMP, stop_label.getarglist(), None, descr=start_label.getdescr()) if self.short: # Construct our short preamble self.close_loop(start_label, jumpop, patchguardop) else: self.optimizer.send_extra_operation(jumpop) return if cell_token.target_tokens: limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit if cell_token.retraced_count < limit: cell_token.retraced_count += 1 debug_print('Retracing (%d/%d)' % (cell_token.retraced_count, limit)) else: debug_print("Retrace count reached, jumping to preamble") assert cell_token.target_tokens[0].virtual_state is None jumpop = jumpop.clone() jumpop.setdescr(cell_token.target_tokens[0]) self.optimizer.send_extra_operation(jumpop) return # Found nothing to jump to, emit a label instead if self.short: # Construct our short preamble assert start_label self.close_bridge(start_label) self.optimizer.flush() if export_state: KillHugeIntBounds(self.optimizer).apply() loop.operations = self.optimizer.get_newoperations() if export_state: jd_sd = self.optimizer.jitdriver_sd try: threshold = jd_sd.warmstate.disable_unrolling_threshold except AttributeError: # tests only threshold = sys.maxint if len(loop.operations) > threshold: if loop.operations[0].getopnum() == rop.LABEL: # abandoning unrolling, too long new_descr = stop_label.getdescr() if loop.operations[0].getopnum() == rop.LABEL: new_descr = loop.operations[0].getdescr() stop_label = stop_label.copy_and_change(rop.JUMP, descr=new_descr) self.optimizer.send_extra_operation(stop_label) loop.operations = self.optimizer.get_newoperations() return None final_state = self.export_state(stop_label) else: final_state = None loop.operations.append(stop_label) return final_state
class TestFullRegallocFakeCPU(object): # XXX copy-paste from test_regalloc_integration cpu = CPU(None, None) cpu.setup_once() targettoken = TargetToken() targettoken2 = TargetToken() fdescr1 = BasicFailDescr(1) fdescr2 = BasicFailDescr(2) fdescr3 = BasicFailDescr(3) def setup_method(self, meth): self.targettoken._ll_loop_code = 0 self.targettoken2._ll_loop_code = 0 def f1(x): return x+1 def f2(x, y): return x*y def f10(*args): assert len(args) == 10 return sum(args) F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*2, lltype.Signed)) F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed]*10, lltype.Signed)) f1ptr = llhelper(F1PTR, f1) f2ptr = llhelper(F2PTR, f2) f10ptr = llhelper(F10PTR, f10) f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT, EffectInfo.MOST_GENERAL) f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT, EffectInfo.MOST_GENERAL) f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL) namespace = locals().copy() def parse(self, s, boxkinds=None, namespace=None): return parse(s, self.cpu, namespace or self.namespace, boxkinds=boxkinds) def allocate(self, s, inputarg_locs=None): loop = self.parse(s) self.loop = loop regalloc = FakeRegalloc() regalloc.fake_prepare_loop(loop.inputargs, loop.operations, loop.original_jitcell_token, inputarg_locs) self.regalloc = regalloc return regalloc.fake_allocate(loop) def test_simple(self): ops = ''' [i0] label(i0, descr=targettoken) i1 = int_add(i0, 1) i2 = int_lt(i1, 20) guard_true(i2) [i1] jump(i1, descr=targettoken) ''' emitted = self.allocate(ops) fp0 = FakeFramePos(0, INT) assert emitted == [ ("label", [fp0]), ("move", r0, fp0), ("int_add", r0, [1]), ("int_lt", r8, [r0, 20]), ("guard_true", r8, [r0]), ("move", fp0, r0), ("jump", [fp0]), ] def test_call(self): ops = ''' [i0] i1 = int_mul(i0, 2) i2 = call_i(ConstClass(f1ptr), i1, descr=f1_calldescr) guard_false(i2) [] ''' emitted = self.allocate(ops) fp0 = FakeFramePos(0, INT) assert emitted == [ ("move", r1, fp0), ("int_mul", r1, [2]), ("call_i", r0, [r1]), ("guard_false", r0, []), ] def test_call_2(self): ops = ''' [i0, i1] i2 = int_mul(i0, 2) i3 = int_add(i1, 1) i4 = call_i(ConstClass(f1ptr), i2, descr=f1_calldescr) guard_false(i4) [i3] ''' emitted = self.allocate(ops) fp0 = FakeFramePos(0, INT) fp1 = FakeFramePos(1, INT) assert emitted == [ ("move", r1, fp0), ("int_mul", r1, [2]), ("move", r4, fp1), # r4 gets picked since it's callee-saved ("int_add", r4, [1]), ("call_i", r0, [r1]), ("guard_false", r0, [r4]), ] def test_coalescing(self): ops = ''' [i0] i1 = int_mul(i0, 5) i5 = int_is_true(i1) guard_true(i5) [] i2 = int_mul(i0, 2) i3 = int_add(i2, 1) # i2 and i3 need to be coalesced i4 = call_i(ConstClass(f1ptr), i3, descr=f1_calldescr) guard_false(i4) [] ''' emitted = self.allocate(ops) fp0 = FakeFramePos(0, INT) assert emitted == [ ('move', r1, fp0), ('int_mul', r1, [5]), ('int_is_true', r8, [r1]), ('guard_true', r8, []), ('move', r1, fp0), ('int_mul', r1, [2]), ('int_add', r1, [1]), ('call_i', r0, [r1]), ('guard_false', r0, []) ] def test_specify_inputarg_locs(self): ops = ''' [i0] i1 = int_mul(i0, 5) i5 = int_is_true(i1) guard_true(i5) [] ''' emitted = self.allocate(ops, [r0]) assert emitted == [ ('int_mul', r0, [5]), ('int_is_true', r8, [r0]), ('guard_true', r8, []) ] def test_coalescing_first_var_already_in_different_reg(self): ops = ''' [i0] i2 = int_mul(i0, 2) i3 = int_add(i2, 1) # i2 and i3 need to be coalesced i4 = call_i(ConstClass(f1ptr), i3, descr=f1_calldescr) guard_false(i4) [i0] ''' emitted = self.allocate(ops, [r5]) assert emitted == [ ('move', r1, r5), ('int_mul', r1, [2]), ('int_add', r1, [1]), ('call_i', r0, [r1]), ('guard_false', r0, [r5]) ] def test_call_spill_furthest_use(self): # here, i2 should be spilled, because its use is farther away ops = ''' [i0, i1, i2, i3, i4, i5, i6] i8 = call_i(ConstClass(f2ptr), i0, i1, descr=f2_calldescr) escape_i(i3) escape_i(i2) guard_false(i8) [i2, i3, i4, i5, i6] ''' emitted = self.allocate(ops, [r1, r2, r0, r3, r4, r5, r6]) fp0 = FakeFramePos(0, INT) assert emitted == [ ('move', fp0, r0), ('move', r7, r3), ('call_i', r0, [r1, r2]), ('escape_i', r1, [r7]), ('escape_i', r1, [fp0]), ('guard_false', r0, [fp0, r7, r4, r5, r6]) ] @py.test.mark.skip("messy - later") def test_call_spill(self): # i0 dies, i1 is the argument, the other fight for caller-saved regs # all_regs = [r0, r1, r2, r3, r4, r5, r6, r7] # save_around_call_regs = [r0, r1, r2, r3] ops = ''' [i0, i1, i2, i3, i4, i5, i6] i8 = call_i(ConstClass(f2ptr), i1, i0, descr=f2_calldescr) guard_false(i8) [i2, i3, i4, i5, i6] ''' emitted = self.allocate(ops, [r5, r1, r0, r2, r3, r6, r7]) assert emitted == ["???"] def test_jump_hinting(self): ops = ''' [i0, i1] i2 = escape_i() i3 = escape_i() label(i2, i3, descr=targettoken) i4 = escape_i() i5 = escape_i() jump(i4, i5, descr=targettoken) ''' emitted = self.allocate(ops) assert emitted == [ ('escape_i', r0, []), ('escape_i', r1, []), ('label', [r0, r1]), ('escape_i', r0, []), ('escape_i', r1, []), ('jump', [r0, r1]) ]
def run_unpack(self, unpack, vector_type, assignments, float=True): vars = {'v': 0, 'f': 0, 'i': 0} def newvar(type): c = vars[type] vars[type] = c + 1 if type == 'v': return type + str(c) + vector_type return type + str(c) targettoken = TargetToken() finaldescr = BasicFinalDescr(1) args = [] args_values = [] pack = [] suffix = 'f' if float else 'i' for var, vals in assignments.items(): v = newvar('v') pack.append('%s = vec_%s()' % (v, suffix)) for i, val in enumerate(vals): args_values.append(val) f = newvar(suffix) args.append(f) count = 1 # create a new variable vo = v v = newvar('v') pack.append('%s = vec_pack_%s(%s, %s, %d, %d)' % \ (v, suffix, vo, f, i, count)) vars['x'] = v packs = '\n '.join(pack) resvar = suffix + '{' + suffix + '}' # format the resoperations, take care that the lhs of = # is formated later with a new variable name unpackops = unpack if isinstance(unpack, str): unpackops = [unpack] unpacksf = [] for up in unpackops: lhs, rhs = up.split("=") rhsf = rhs.format(**vars) newvar('i') newvar('f') newvar('v') lhsf = lhs.format(**vars) unpacksf.append(lhsf + '=' + rhsf) unpacks = '\n '.join(unpacksf) source = ''' [{args}] label({args}, descr=targettoken) {packs} {unpacks} finish({resvar}, descr=finaldescr) '''.format(args=','.join(args), packs=packs, unpacks=unpacks, resvar=resvar.format(**vars)) print(source) return self._compile_and_run(source, args_values, float, ns={ 'targettoken': targettoken, 'finaldescr': finaldescr })
def test_compile_bridge_check_profile_info(self): py.test.skip("does not work, reinvestigate") class FakeProfileAgent(object): def __init__(self): self.functions = [] def native_code_written(self, name, address, size): self.functions.append((name, address, size)) self.cpu.profile_agent = agent = FakeProfileAgent() i0 = InputArgInt() i1 = InputArgInt() i2 = InputArgInt() targettoken = TargetToken() faildescr1 = BasicFailDescr(1) faildescr2 = BasicFailDescr(2) looptoken = JitCellToken() looptoken.number = 17 class FakeString(object): def __init__(self, val): self.val = val def _get_str(self): return self.val operations = [ ResOperation(rop.LABEL, [i0], None, descr=targettoken), ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("hello"), 0, 0], None), ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1), ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2), ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1), ResOperation(rop.JUMP, [i1], None, descr=targettoken), ] inputargs = [i0] operations[-2].setfailargs([i1]) self.cpu.compile_loop(inputargs, operations, looptoken) name, loopaddress, loopsize = agent.functions[0] assert name == "Loop # 17: hello (loop counter 0)" assert loopaddress <= looptoken._ll_loop_code assert loopsize >= 40 # randomish number i1b = InputArgInt() i3 = InputArgInt() bridge = [ ResOperation(rop.INT_LE, [i1b, ConstInt(19)], i3), ResOperation(rop.GUARD_TRUE, [i3], None, descr=faildescr2), ResOperation(rop.DEBUG_MERGE_POINT, [FakeString("bye"), 0, 0], None), ResOperation(rop.JUMP, [i1b], None, descr=targettoken), ] bridge[1].setfailargs([i1b]) self.cpu.compile_bridge(faildescr1, [i1b], bridge, looptoken) name, address, size = agent.functions[1] assert name == "Bridge # 0: bye (loop counter 1)" # Would be exactly ==, but there are some guard failure recovery # stubs in-between assert address >= loopaddress + loopsize assert size >= 10 # randomish number deadframe = self.cpu.execute_token(looptoken, 2) fail = self.cpu.get_latest_descr(deadframe) assert fail.identifier == 2 res = self.cpu.get_int_value(deadframe, 0) assert res == 20
class BaseTestRegalloc(object): cpu = CPU(None, None) cpu.setup_once() def raising_func(i): if i: raise LLException(zero_division_error, zero_division_value) FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void)) raising_fptr = llhelper(FPTR, raising_func) zero_division_tp, zero_division_value = get_zero_division_error(cpu) zd_addr = cpu.cast_int_to_adr(zero_division_tp) zero_division_error = llmemory.cast_adr_to_ptr( zd_addr, lltype.Ptr(rclass.OBJECT_VTABLE)) raising_calldescr = cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT, EffectInfo.MOST_GENERAL) targettoken = TargetToken() targettoken2 = TargetToken() fdescr1 = BasicFailDescr(1) fdescr2 = BasicFailDescr(2) fdescr3 = BasicFailDescr(3) def setup_method(self, meth): self.targettoken._ll_loop_code = 0 self.targettoken2._ll_loop_code = 0 def f1(x): return x + 1 def f2(x, y): return x * y def f10(*args): assert len(args) == 10 return sum(args) F1PTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)) F2PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 2, lltype.Signed)) F10PTR = lltype.Ptr(lltype.FuncType([lltype.Signed] * 10, lltype.Signed)) f1ptr = llhelper(F1PTR, f1) f2ptr = llhelper(F2PTR, f2) f10ptr = llhelper(F10PTR, f10) f1_calldescr = cpu.calldescrof(F1PTR.TO, F1PTR.TO.ARGS, F1PTR.TO.RESULT, EffectInfo.MOST_GENERAL) f2_calldescr = cpu.calldescrof(F2PTR.TO, F2PTR.TO.ARGS, F2PTR.TO.RESULT, EffectInfo.MOST_GENERAL) f10_calldescr = cpu.calldescrof(F10PTR.TO, F10PTR.TO.ARGS, F10PTR.TO.RESULT, EffectInfo.MOST_GENERAL) namespace = locals().copy() def parse(self, s, boxkinds=None, namespace=None): return parse(s, self.cpu, namespace or self.namespace, boxkinds=boxkinds) def interpret(self, ops, args, run=True, namespace=None): loop = self.parse(ops, namespace=namespace) self.loop = loop looptoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) arguments = [] for arg in args: if isinstance(arg, int): arguments.append(arg) elif isinstance(arg, float): arg = longlong.getfloatstorage(arg) arguments.append(arg) else: assert isinstance(lltype.typeOf(arg), lltype.Ptr) llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) arguments.append(llgcref) loop._jitcelltoken = looptoken if run: self.deadframe = self.cpu.execute_token(looptoken, *arguments) return loop def prepare_loop(self, ops): loop = self.parse(ops) regalloc = self.cpu.build_regalloc() regalloc.prepare_loop(loop.inputargs, loop.operations, loop.original_jitcell_token, []) return regalloc def getint(self, index): return self.cpu.get_int_value(self.deadframe, index) def getfloat(self, index): return self.cpu.get_float_value(self.deadframe, index) def getints(self, end): return [ self.cpu.get_int_value(self.deadframe, index) for index in range(0, end) ] def getfloats(self, end): return [ longlong.getrealfloat( self.cpu.get_float_value(self.deadframe, index)) for index in range(0, end) ] def getptr(self, index, T): gcref = self.cpu.get_ref_value(self.deadframe, index) return lltype.cast_opaque_ptr(T, gcref) def attach_bridge(self, ops, loop, guard_op_index, **kwds): guard_op = loop.operations[guard_op_index] assert guard_op.is_guard() bridge = self.parse(ops, **kwds) assert ([box.type for box in bridge.inputargs ] == [box.type for box in guard_op.getfailargs()]) faildescr = guard_op.getdescr() self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations, loop._jitcelltoken) return bridge def run(self, loop, *arguments): self.deadframe = self.cpu.execute_token(loop._jitcelltoken, *arguments) return self.cpu.get_latest_descr(self.deadframe)
def compile_loop(metainterp, greenkey, start, inputargs, jumpargs, full_preamble_needed=True, try_disabling_unroll=False): """Try to compile a new procedure by closing the current history back to the first operation. """ from rpython.jit.metainterp.optimizeopt import optimize_trace metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd history = metainterp.history enable_opts = jitdriver_sd.warmstate.enable_opts if try_disabling_unroll: if 'unroll' not in enable_opts: return None enable_opts = enable_opts.copy() del enable_opts['unroll'] jitcell_token = make_jitcell_token(jitdriver_sd) part = create_empty_loop(metainterp) part.inputargs = inputargs[:] h_ops = history.operations label = ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(jitcell_token)) end_label = ResOperation(rop.LABEL, jumpargs, None, descr=jitcell_token) part.operations = [label] + h_ops[start:] + [end_label] try: start_state = optimize_trace(metainterp_sd, jitdriver_sd, part, enable_opts, export_state=True) except InvalidLoop: return None target_token = part.operations[0].getdescr() assert isinstance(target_token, TargetToken) all_target_tokens = [target_token] loop = create_empty_loop(metainterp) loop.inputargs = part.inputargs loop.operations = part.operations loop.quasi_immutable_deps = {} if part.quasi_immutable_deps: loop.quasi_immutable_deps.update(part.quasi_immutable_deps) if part.operations[-1].getopnum() == rop.LABEL: inliner = Inliner(inputargs, jumpargs) part.quasi_immutable_deps = None part.operations = [part.operations[-1]] + \ [inliner.inline_op(h_ops[i]) for i in range(start, len(h_ops))] + \ [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jumpargs], None, descr=jitcell_token)] target_token = part.operations[0].getdescr() assert isinstance(target_token, TargetToken) all_target_tokens.append(target_token) inputargs = jumpargs jumpargs = part.operations[-1].getarglist() try: optimize_trace(metainterp_sd, jitdriver_sd, part, enable_opts, start_state=start_state, export_state=False) except InvalidLoop: return None loop.operations = loop.operations[:-1] + part.operations if part.quasi_immutable_deps: loop.quasi_immutable_deps.update(part.quasi_immutable_deps) assert part.operations[-1].getopnum() != rop.LABEL if not loop.quasi_immutable_deps: loop.quasi_immutable_deps = None for box in loop.inputargs: assert isinstance(box, Box) loop.original_jitcell_token = jitcell_token for label in all_target_tokens: assert isinstance(label, TargetToken) if label.virtual_state and label.short_preamble: metainterp_sd.logger_ops.log_short_preamble([], label.short_preamble) jitcell_token.target_tokens = all_target_tokens propagate_original_jitcell_token(loop) send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop") record_loop_or_bridge(metainterp_sd, loop) return all_target_tokens[0]
def compile_loop(metainterp, greenkey, start, inputargs, jumpargs, full_preamble_needed=True, try_disabling_unroll=False): """Try to compile a new procedure by closing the current history back to the first operation. """ from rpython.jit.metainterp.optimizeopt import optimize_trace metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd history = metainterp.history trace = history.trace warmstate = jitdriver_sd.warmstate enable_opts = jitdriver_sd.warmstate.enable_opts if try_disabling_unroll: if 'unroll' not in enable_opts: return None enable_opts = enable_opts.copy() del enable_opts['unroll'] jitcell_token = make_jitcell_token(jitdriver_sd) cut_at = history.get_trace_position() history.record(rop.JUMP, jumpargs, None, descr=jitcell_token) if start != (0, 0, 0): trace = trace.cut_trace_from(start, inputargs) if 'unroll' not in enable_opts or not metainterp.cpu.supports_guard_gc_type: return compile_simple_loop(metainterp, greenkey, trace, jumpargs, enable_opts, cut_at) call_pure_results = metainterp.call_pure_results preamble_data = LoopCompileData(trace, jumpargs, call_pure_results=call_pure_results, enable_opts=enable_opts) try: start_state, preamble_ops = optimize_trace(metainterp_sd, jitdriver_sd, preamble_data, metainterp.box_names_memo) except InvalidLoop: history.cut(cut_at) return None metainterp_sd = metainterp.staticdata jitdriver_sd = metainterp.jitdriver_sd start_descr = TargetToken(jitcell_token, original_jitcell_token=jitcell_token) jitcell_token.target_tokens = [start_descr] loop_data = UnrolledLoopData(trace, jitcell_token, start_state, call_pure_results=call_pure_results, enable_opts=enable_opts) try: loop_info, loop_ops = optimize_trace(metainterp_sd, jitdriver_sd, loop_data, metainterp.box_names_memo) except InvalidLoop: history.cut(cut_at) return None if ((warmstate.vec and jitdriver_sd.vec) or warmstate.vec_all): from rpython.jit.metainterp.optimizeopt.vector import optimize_vector loop_info, loop_ops = optimize_vector(trace, metainterp_sd, jitdriver_sd, warmstate, loop_info, loop_ops, jitcell_token) # loop = create_empty_loop(metainterp) loop.original_jitcell_token = jitcell_token loop.inputargs = start_state.renamed_inputargs quasi_immutable_deps = {} if start_state.quasi_immutable_deps: quasi_immutable_deps.update(start_state.quasi_immutable_deps) if loop_info.quasi_immutable_deps: quasi_immutable_deps.update(loop_info.quasi_immutable_deps) if quasi_immutable_deps: loop.quasi_immutable_deps = quasi_immutable_deps start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs, descr=start_descr) label_token = loop_info.label_op.getdescr() assert isinstance(label_token, TargetToken) if label_token.short_preamble: metainterp_sd.logger_ops.log_short_preamble([], label_token.short_preamble, metainterp.box_names_memo) loop.operations = ([start_label] + preamble_ops + loop_info.extra_same_as + [loop_info.label_op] + loop_ops) if not we_are_translated(): loop.check_consistency() send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop", inputargs, metainterp.box_names_memo) record_loop_or_bridge(metainterp_sd, loop) loop_info.post_loop_compilation(loop, jitdriver_sd, metainterp, jitcell_token) return start_descr
class TestRegallocMoreRegisters(BaseTestRegalloc): cpu = BaseTestRegalloc.cpu targettoken = TargetToken() S = lltype.GcStruct('S', ('field', lltype.Char)) fielddescr = cpu.fielddescrof(S, 'field') A = lltype.GcArray(lltype.Char) arraydescr = cpu.arraydescrof(A) namespace = locals().copy() def test_int_is_true(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7] i10 = int_is_true(i0) i11 = int_is_true(i1) i12 = int_is_true(i2) i13 = int_is_true(i3) i14 = int_is_true(i4) i15 = int_is_true(i5) i16 = int_is_true(i6) i17 = int_is_true(i7) guard_true(i0) [i10, i11, i12, i13, i14, i15, i16, i17] finish() ''' self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333]) assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1] def test_comparison_ops(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6] i10 = int_lt(i0, i1) i11 = int_le(i2, i3) i12 = int_ge(i4, i5) i13 = int_eq(i5, i6) i14 = int_gt(i6, i2) i15 = int_ne(i2, i6) guard_true(i0) [i10, i11, i12, i13, i14, i15] finish() ''' self.interpret(ops, [0, 1, 2, 3, 4, 5, 6]) assert self.getints(6) == [1, 1, 0, 0, 1, 1] def test_strsetitem(self): ops = ''' [p0, i] strsetitem(p0, 1, i) finish() ''' llstr = rstr.mallocstr(10) self.interpret(ops, [llstr, ord('a')]) assert llstr.chars[1] == 'a' def test_setfield_char(self): ops = ''' [p0, i] setfield_gc(p0, i, descr=fielddescr) finish() ''' s = lltype.malloc(self.S) self.interpret(ops, [s, ord('a')]) assert s.field == 'a' def test_setarrayitem_gc(self): ops = ''' [p0, i] setarrayitem_gc(p0, 1, i, descr=arraydescr) finish() ''' s = lltype.malloc(self.A, 3) self.interpret(ops, [s, ord('a')]) assert s[1] == 'a'
class TestRegallocGcIntegration(BaseTestRegalloc): cpu = CPU(None, None) cpu.gc_ll_descr = GcLLDescr_boehm(None, None, None) cpu.setup_once() S = lltype.GcForwardReference() S.become(lltype.GcStruct('S', ('field', lltype.Ptr(S)), ('int', lltype.Signed))) fielddescr = cpu.fielddescrof(S, 'field') struct_ptr = lltype.malloc(S) struct_ref = lltype.cast_opaque_ptr(llmemory.GCREF, struct_ptr) child_ptr = lltype.nullptr(S) struct_ptr.field = child_ptr intdescr = cpu.fielddescrof(S, 'int') ptr0 = struct_ref targettoken = TargetToken() targettoken2 = TargetToken() namespace = locals().copy() def test_basic(self): ops = ''' [p0] p1 = getfield_gc_r(p0, descr=fielddescr) finish(p1) ''' self.interpret(ops, [self.struct_ptr]) assert not self.getptr(0, lltype.Ptr(self.S)) def test_guard(self): ops = ''' [i0, p0, i1, p1] p3 = getfield_gc_r(p0, descr=fielddescr) guard_true(i0) [p0, i1, p1, p3] ''' s1 = lltype.malloc(self.S) s2 = lltype.malloc(self.S) s1.field = s2 self.interpret(ops, [0, s1, 1, s2]) frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, self.deadframe) # p0 and p3 should be in registers, p1 not so much assert self.getptr(0, lltype.Ptr(self.S)) == s1 # the gcmap should contain three things, p0, p1 and p3 # p3 stays in a register # while p0 and p1 are on the frame b = getmap(frame) nos = [len(b) - 1 - i.start() for i in re.finditer('1', b)] nos.reverse() if self.cpu.backend_name.startswith('x86'): if self.cpu.IS_64_BIT: assert nos == [0, 1, 31] else: assert nos == [0, 1, 25] elif self.cpu.backend_name.startswith('arm'): assert nos == [0, 1, 47] elif self.cpu.backend_name.startswith('ppc64'): assert nos == [0, 1, 33] elif self.cpu.backend_name.startswith('zarch'): assert nos == [0, 1, 29] else: raise Exception("write the data here") assert frame.jf_frame[nos[0]] assert frame.jf_frame[nos[1]] assert frame.jf_frame[nos[2]] def test_rewrite_constptr(self): ops = ''' [] p1 = getfield_gc_r(ConstPtr(struct_ref), descr=fielddescr) finish(p1) ''' self.interpret(ops, []) assert not self.getptr(0, lltype.Ptr(self.S)) def test_bug_0(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7, i8] label(i0, i1, i2, i3, i4, i5, i6, i7, i8, descr=targettoken) guard_value(i2, 1) [i2, i3, i4, i5, i6, i7, i0, i1, i8] guard_class(i4, 138998336) [i4, i5, i6, i7, i0, i1, i8] i11 = getfield_gc_i(i4, descr=intdescr) guard_nonnull(i11) [i4, i5, i6, i7, i0, i1, i11, i8] i13 = getfield_gc_i(i11, descr=intdescr) guard_isnull(i13) [i4, i5, i6, i7, i0, i1, i11, i8] i15 = getfield_gc_i(i4, descr=intdescr) i17 = int_lt(i15, 0) guard_false(i17) [i4, i5, i6, i7, i0, i1, i11, i15, i8] i18 = getfield_gc_i(i11, descr=intdescr) i19 = int_ge(i15, i18) guard_false(i19) [i4, i5, i6, i7, i0, i1, i11, i15, i8] i20 = int_lt(i15, 0) guard_false(i20) [i4, i5, i6, i7, i0, i1, i11, i15, i8] i21 = getfield_gc_i(i11, descr=intdescr) i22 = getfield_gc_i(i11, descr=intdescr) i23 = int_mul(i15, i22) i24 = int_add(i21, i23) i25 = getfield_gc_i(i4, descr=intdescr) i27 = int_add(i25, 1) setfield_gc(i4, i27, descr=intdescr) i29 = getfield_raw_i(144839744, descr=intdescr) i31 = int_and(i29, -2141192192) i32 = int_is_true(i31) guard_false(i32) [i4, i6, i7, i0, i1, i24] i33 = getfield_gc_i(i0, descr=intdescr) guard_value(i33, ConstPtr(ptr0)) [i4, i6, i7, i0, i1, i33, i24] jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24, descr=targettoken) ''' self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False)
class TestRegallocMoreRegisters(CustomBaseTestRegalloc): cpu = CustomBaseTestRegalloc.cpu targettoken = TargetToken() S = lltype.GcStruct('S', ('field', lltype.Char)) fielddescr = cpu.fielddescrof(S, 'field') A = lltype.GcArray(lltype.Char) I = lltype.GcArray(lltype.Signed) arraydescr = cpu.arraydescrof(A) arraydescr_i = cpu.arraydescrof(I) namespace = locals().copy() def test_int_is_true(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6, i7] i10 = int_is_true(i0) i11 = int_is_true(i1) i12 = int_is_true(i2) i13 = int_is_true(i3) i14 = int_is_true(i4) i15 = int_is_true(i5) i16 = int_is_true(i6) i17 = int_is_true(i7) guard_true(i0) [i10, i11, i12, i13, i14, i15, i16, i17] ''' self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333]) assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1] def test_comparison_ops(self): ops = ''' [i0, i1, i2, i3, i4, i5, i6] i10 = int_lt(i0, i1) i11 = int_le(i2, i3) i12 = int_ge(i4, i5) i13 = int_eq(i5, i6) i14 = int_gt(i6, i2) i15 = int_ne(i2, i6) guard_true(i15) [i10, i11, i12, i13, i14, i15] ''' self.interpret(ops, [0, 1, 2, 3, 4, 5, 6]) assert self.getints(6) == [1, 1, 0, 0, 1, 1] def test_strsetitem(self): ops = ''' [p0, i] strsetitem(p0, 1, i) finish() ''' llstr = rstr.mallocstr(10) self.interpret(ops, [llstr, ord('a')]) assert llstr.chars[1] == 'a' def test_setfield_char(self): ops = ''' [p0, i] setfield_gc(p0, i, descr=fielddescr) finish() ''' s = lltype.malloc(self.S) self.interpret(ops, [s, ord('a')]) assert s.field == 'a' def test_setarrayitem_gc(self): ops = ''' [p0, i] setarrayitem_gc(p0, 1, i, descr=arraydescr) finish() ''' s = lltype.malloc(self.A, 3) self.interpret(ops, [s, ord('a')]) assert s[1] == 'a' def test_setarrayitem2_gc(self): ops = ''' [p0, i, i1] setarrayitem_gc(p0, i1, i, descr=arraydescr) finish() ''' s = lltype.malloc(self.A, 3) self.interpret(ops, [s, ord('a'), 1]) assert s[1] == 'a' def test_setarrayitem3_gc(self): ops = ''' [p0, i0, i1] setarrayitem_gc(p0, i1, i0, descr=arraydescr_i) finish() ''' s = lltype.malloc(self.I, 3) self.interpret(ops, [s, 1234567890, 1]) assert s[1] == 1234567890 def test_setarrayitem4_gc(self): ops = ''' [p0, i0] setarrayitem_gc(p0, 1, i0, descr=arraydescr_i) finish() ''' s = lltype.malloc(self.I, 3) self.interpret(ops, [s, 1234567890]) assert s[1] == 1234567890 def test_division_optimized(self): ops = ''' [i7, i6] label(i7, i6, descr=targettoken) i18 = int_floordiv(i7, i6) i19 = int_xor(i7, i6) i21 = int_lt(i19, 0) i22 = int_mod(i7, i6) i23 = int_is_true(i22) i24 = int_eq(i6, 4) guard_false(i24) [i18] jump(i18, i6, descr=targettoken) ''' self.interpret(ops, [10, 4]) assert self.getint(0) == 2
def test_bug_2(): cpu = CPU(None, None) cpu.setup_once() S4 = lltype.Struct('Sx', ("f0", lltype.Char), ("f1", lltype.Signed), ("f2", lltype.Signed), ("f3", lltype.Signed)) S5 = lltype.GcArray(S4) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() tmp11 = BoxInt() tmp12 = BoxPtr() faildescr0 = BasicFailDescr() tmp13 = BoxPtr() faildescr1 = BasicFailDescr() finishdescr2 = BasicFinalDescr() const_ptr14 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.STR, 1))) const_ptr15 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.UNICODE, 489))) const_ptr16 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.UNICODE, 16))) const_ptr17 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S5, 299))) inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] xtp, func, funcdescr = getexception(cpu, 3) xtp2, func2, func2descr = getexception(cpu, 2) operations = [ ResOperation(rop.STRGETITEM, [const_ptr14, ConstInt(0)], tmp11), ResOperation(rop.LABEL, [v1, v2, tmp11, v3, v4, v5, v6, v7, v8, v9, v10], None, TargetToken()), ResOperation(rop.UNICODESETITEM, [const_ptr15, v4, ConstInt(22)], None), ResOperation(rop.CALL, [ConstInt(func), v2, v1, v9], None, descr=funcdescr), ResOperation(rop.GUARD_EXCEPTION, [ConstInt(xtp)], tmp12, descr=faildescr0), ResOperation( rop.UNICODESETITEM, [const_ptr16, ConstInt(13), ConstInt(9)], None), ResOperation(rop.SETINTERIORFIELD_GC, [const_ptr17, v3, v7], None, cpu.interiorfielddescrof(S5, 'f3')), ResOperation(rop.CALL, [ConstInt(func2), v7, v10], None, descr=func2descr), ResOperation(rop.GUARD_NO_EXCEPTION, [], tmp13, descr=faildescr1), ResOperation(rop.FINISH, [], None, descr=finishdescr2), ] operations[4].setfailargs([v4, v8, v10, v2, v9, v7, v6, v1]) operations[8].setfailargs([v3, v9, v2, v6, v4]) looptoken = JitCellToken() cpu.compile_loop(inputargs, operations, looptoken) loop_args = [1, -39, 46, 21, 16, 6, -4611686018427387905, 12, 14, 2] frame = cpu.execute_token(looptoken, *loop_args) assert cpu.get_int_value(frame, 0) == 46 assert cpu.get_int_value(frame, 1) == 14 assert cpu.get_int_value(frame, 2) == -39 assert cpu.get_int_value(frame, 3) == 6 assert cpu.get_int_value(frame, 4) == 21 S4 = lltype.GcStruct('Sx', ("parent", rclass.OBJECT), ("f0", lltype.Signed)) S5 = lltype.GcStruct('Sx', ("f0", lltype.Signed)) S6 = lltype.GcArray(lltype.Signed) S7 = lltype.GcStruct('Sx', ("parent", rclass.OBJECT), ("f0", lltype.Char)) S8 = lltype.Struct('Sx', ("f0", lltype.Char), ("f1", lltype.Signed), ("f2", lltype.Signed), ("f3", lltype.Signed)) S9 = lltype.GcArray(S8) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() v16 = BoxInt() v17 = BoxInt() v18 = BoxInt() v19 = BoxInt() p20 = BoxPtr() tmp21 = BoxPtr() faildescr3 = BasicFailDescr() tmp22 = BoxPtr() faildescr4 = BasicFailDescr() tmp23 = BoxInt() tmp24 = BoxInt() tmp25 = BoxInt() tmp26 = BoxInt() tmp27 = BoxInt() tmp28 = BoxInt() tmp29 = BoxInt() faildescr5 = BasicFailDescr() tmp30 = BoxPtr() faildescr6 = BasicFailDescr() finishdescr7 = BasicFinalDescr() const_ptr31 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S4))) const_ptr32 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.STR, 46))) const_ptr33 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S5))) const_ptr34 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.UNICODE, 26))) const_ptr35 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.UNICODE, 15))) const_ptr36 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S7))) const_ptr37 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.STR, 484))) const_ptr38 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S9, 299))) inputargs = [v1, v2, v3, v4, v5] func3, func3descr = getnoexception(cpu, 5) xtp3, func4, func4descr = getexception(cpu, 10) operations = [ ResOperation(rop.GUARD_EXCEPTION, [ConstInt(xtp2)], tmp21, descr=faildescr3), ResOperation(rop.INT_IS_ZERO, [v4], v6), ResOperation(rop.INT_NE, [v6, ConstInt(13)], v7), ResOperation(rop.GETFIELD_GC, [const_ptr31], v8, cpu.fielddescrof(S4, 'f0')), ResOperation(rop.STRSETITEM, [const_ptr32, v6, ConstInt(0)], None), ResOperation(rop.NEWSTR, [ConstInt(5)], tmp22), ResOperation(rop.STRSETITEM, [tmp22, ConstInt(0), ConstInt(42)], None), ResOperation(rop.STRSETITEM, [tmp22, ConstInt(1), ConstInt(42)], None), ResOperation(rop.STRSETITEM, [tmp22, ConstInt(2), ConstInt(20)], None), ResOperation(rop.STRSETITEM, [tmp22, ConstInt(3), ConstInt(48)], None), ResOperation(rop.STRSETITEM, [tmp22, ConstInt(4), ConstInt(6)], None), ResOperation(rop.GETFIELD_GC, [const_ptr33], v9, cpu.fielddescrof(S5, 'f0')), ResOperation(rop.UNICODESETITEM, [const_ptr34, ConstInt(24), ConstInt(65533)], None), ResOperation(rop.GETFIELD_GC, [const_ptr31], v10, cpu.fielddescrof(S4, 'f0')), ResOperation(rop.INT_NE, [v10, ConstInt(25)], v11), ResOperation(rop.CALL, [ConstInt(func3), v5, v1, v8, v3, v2], v12, descr=func3descr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr4), ResOperation(rop.UNICODELEN, [const_ptr35], tmp23), ResOperation(rop.NEW_ARRAY, [v2], p20, cpu.arraydescrof(S6)), ResOperation(rop.GETFIELD_GC, [const_ptr36], v13, cpu.fielddescrof(S7, 'f0')), ResOperation(rop.INT_OR, [v8, ConstInt(2)], tmp24), ResOperation(rop.INT_FLOORDIV, [ConstInt(8), tmp24], v14), ResOperation(rop.GETARRAYITEM_GC, [p20, ConstInt(3)], v15, cpu.arraydescrof(S6)), ResOperation( rop.COPYSTRCONTENT, [tmp22, const_ptr37, ConstInt(1), ConstInt(163), ConstInt(0)], None), ResOperation(rop.COPYUNICODECONTENT, [const_ptr35, const_ptr34, ConstInt(13), ConstInt(0), v6], None), ResOperation(rop.STRGETITEM, [tmp22, v6], tmp25), ResOperation(rop.STRGETITEM, [tmp22, ConstInt(0)], tmp26), ResOperation(rop.GETINTERIORFIELD_GC, [const_ptr38, v13], v16, cpu.interiorfielddescrof(S9, 'f0')), ResOperation(rop.INT_GE, [v4, v5], v17), ResOperation(rop.INT_OR, [v13, ConstInt(2)], tmp27), ResOperation(rop.INT_FLOORDIV, [ConstInt(12), tmp27], v18), ResOperation(rop.INT_AND, [v1, ConstInt(-4)], tmp28), ResOperation(rop.INT_OR, [tmp28, ConstInt(2)], tmp29), ResOperation(rop.INT_FLOORDIV, [v15, tmp29], v19), ResOperation(rop.GUARD_FALSE, [v17], None, descr=faildescr5), ResOperation(rop.UNICODESETITEM, [const_ptr34, ConstInt(20), ConstInt(65522)], None), ResOperation( rop.CALL, [ConstInt(func4), v3, v9, v10, v8, v11, v5, v13, v14, v15, v6], None, descr=func4descr), ResOperation(rop.GUARD_NO_EXCEPTION, [], tmp30, descr=faildescr6), ResOperation(rop.FINISH, [], None, descr=finishdescr7), ] operations[0].setfailargs([]) operations[16].setfailargs([v5, v9]) operations[34].setfailargs([]) operations[37].setfailargs([v12, v19, v10, v7, v4, v8, v18, v15, v9]) cpu.compile_bridge(faildescr1, inputargs, operations, looptoken) frame = cpu.execute_token(looptoken, *loop_args) #assert cpu.get_int_value(frame, 0) == -9223372036854775766 assert cpu.get_int_value(frame, 1) == 0 #assert cpu.get_int_value(frame, 2) == -9223372036854775808 assert cpu.get_int_value(frame, 3) == 1 assert cpu.get_int_value(frame, 4) == 6 #assert cpu.get_int_value(frame, 5) == -9223372036854775808 assert cpu.get_int_value(frame, 6) == 0 assert cpu.get_int_value(frame, 7) == 0 #assert cpu.get_int_value(frame, 8) == 26 S4 = lltype.GcStruct('Sx', ("parent", rclass.OBJECT), ("f0", lltype.Signed), ("f1", lltype.Signed)) S5 = lltype.GcStruct('Sx', ("parent", rclass.OBJECT), ("f0", lltype.Signed)) S6 = lltype.GcStruct('Sx', ("f0", lltype.Signed), ("f1", rffi.UCHAR)) v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() v5 = BoxInt() v6 = BoxInt() v7 = BoxInt() v8 = BoxInt() v9 = BoxInt() v10 = BoxInt() v11 = BoxInt() v12 = BoxInt() v13 = BoxInt() v14 = BoxInt() v15 = BoxInt() v16 = BoxInt() v17 = BoxInt() v18 = BoxInt() tmp19 = BoxPtr() faildescr8 = BasicFailDescr() tmp20 = BoxInt() tmp21 = BoxInt() tmp22 = BoxInt() tmp23 = BoxInt() faildescr9 = BasicFailDescr() tmp24 = BoxInt() tmp25 = BoxInt() tmp26 = BoxInt() tmp27 = BoxPtr() tmp28 = BoxPtr() faildescr10 = BasicFailDescr() finishdescr11 = BasicFinalDescr() const_ptr29 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S4))) const_ptr30 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.UNICODE, 26))) const_ptr31 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.UNICODE, 1))) const_ptr32 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S5))) const_ptr33 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S6))) const_ptr34 = ConstPtr( lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(rstr.STR, 26))) inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9] operations = [ ResOperation(rop.GUARD_EXCEPTION, [ConstInt(xtp3)], tmp19, descr=faildescr8), ResOperation(rop.SETFIELD_GC, [const_ptr29, v7], None, cpu.fielddescrof(S4, 'f0')), ResOperation(rop.UNICODEGETITEM, [const_ptr30, ConstInt(21)], tmp20), ResOperation(rop.UNICODEGETITEM, [const_ptr30, ConstInt(10)], tmp21), ResOperation(rop.UINT_RSHIFT, [v9, ConstInt(40)], v10), ResOperation(rop.UNICODEGETITEM, [const_ptr30, ConstInt(25)], tmp22), ResOperation(rop.INT_NE, [ConstInt(-8), v9], v11), ResOperation(rop.INT_MUL_OVF, [v3, ConstInt(-4)], tmp23), ResOperation(rop.GUARD_OVERFLOW, [], None, descr=faildescr9), ResOperation(rop.UNICODESETITEM, [const_ptr31, ConstInt(0), ConstInt(50175)], None), ResOperation(rop.UINT_GT, [v8, ConstInt(-6)], v12), ResOperation(rop.GETFIELD_GC, [const_ptr32], v13, cpu.fielddescrof(S5, 'f0')), ResOperation(rop.INT_AND, [ConstInt(8), v8], v14), ResOperation(rop.INT_INVERT, [v1], v15), ResOperation(rop.SETFIELD_GC, [const_ptr33, ConstInt(3)], None, cpu.fielddescrof(S6, 'f1')), ResOperation(rop.INT_GE, [v14, v6], v16), ResOperation(rop.INT_AND, [v5, ConstInt(-4)], tmp24), ResOperation(rop.INT_OR, [tmp24, ConstInt(2)], tmp25), ResOperation(rop.INT_FLOORDIV, [v9, tmp25], v17), ResOperation(rop.STRLEN, [const_ptr34], tmp26), ResOperation(rop.NEWSTR, [ConstInt(7)], tmp27), ResOperation(rop.STRSETITEM, [tmp27, ConstInt(0), ConstInt(21)], None), ResOperation(rop.STRSETITEM, [tmp27, ConstInt(1), ConstInt(79)], None), ResOperation(rop.STRSETITEM, [tmp27, ConstInt(2), ConstInt(7)], None), ResOperation(rop.STRSETITEM, [tmp27, ConstInt(3), ConstInt(2)], None), ResOperation(rop.STRSETITEM, [tmp27, ConstInt(4), ConstInt(229)], None), ResOperation(rop.STRSETITEM, [tmp27, ConstInt(5), ConstInt(233)], None), ResOperation(rop.STRSETITEM, [tmp27, ConstInt(6), ConstInt(208)], None), ResOperation(rop.INT_LT, [ConstInt(-31), v10], v18), ResOperation(rop.SAME_AS, [ConstPtr(lltype.nullptr(llmemory.GCREF.TO))], tmp28), ResOperation(rop.GUARD_NONNULL_CLASS, [tmp28, ConstInt(xtp2)], None, descr=faildescr10), ResOperation(rop.FINISH, [v4], None, descr=finishdescr11), ] operations[0].setfailargs([]) operations[8].setfailargs([tmp23, v5, v3, v11, v6]) operations[30].setfailargs([v6]) cpu.compile_bridge(faildescr6, inputargs, operations, looptoken) frame = cpu.execute_token(looptoken, *loop_args) #assert cpu.get_int_value(frame, 0) == -9223372036854775808 v1 = BoxInt() v2 = BoxInt() p3 = BoxPtr() tmp4 = BoxInt() tmp5 = BoxPtr() faildescr12 = BasicFailDescr() finishdescr13 = BasicFinalDescr() inputargs = [v1] _, func5, func5descr = getexception(cpu, 0) vt = getvtable(cpu, S4) operations = [ ResOperation(rop.INT_AND, [v1, ConstInt(63)], tmp4), ResOperation(rop.INT_LSHIFT, [ConstInt(10), tmp4], v2), ResOperation(rop.NEW_WITH_VTABLE, [ConstInt(vt)], p3), ResOperation(rop.CALL, [ConstInt(func5)], None, descr=func5descr), ResOperation(rop.GUARD_EXCEPTION, [ConstInt(xtp2)], tmp5, descr=faildescr12), ResOperation(rop.FINISH, [], None, descr=finishdescr13), ] operations[4].setfailargs([v2]) cpu.compile_bridge(faildescr10, inputargs, operations, looptoken) frame = cpu.execute_token(looptoken, *loop_args)