def get_token_for_call(self, cpu): if self.loop_token is not None: return self.loop_token args = [BoxInt()] + self.instantiate_arg_classes() if self.get_result_size(cpu.translate_support_code) == 0: result = None result_list = [] else: if self.returns_a_pointer(): result = BoxPtr() elif self.returns_a_float(): result = BoxFloat() else: result = BoxInt() result_list = [result] operations = [ ResOperation(rop.CALL, args[:], result, self), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=BasicFailDescr()), ResOperation(rop.FINISH, result_list, None, descr=BasicFailDescr()) ] operations[1].fail_args = [] loop_token = LoopToken() # note: the 'args' that we pass below is not the same object as the # 'args[:]' that was passed above to ResOperation, because we want # the argument to ResOperation to be non-resizable, but the argument # to compile_loop to be resizable. cpu.compile_loop(args, operations, loop_token) self.loop_token = loop_token return loop_token
def get_token_for_call(self, cpu): if self.loop_token is not None: return self.loop_token args = [BoxInt()] + self.instantiate_arg_classes() if self.get_result_size(cpu.translate_support_code) == 0: result = None result_list = [] else: if self.returns_a_pointer(): result = BoxPtr() elif self.returns_a_float(): result = BoxFloat() else: result = BoxInt() result_list = [result] operations = [ ResOperation(rop.CALL, args, result, self), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=BasicFailDescr()), ResOperation(rop.FINISH, result_list, None, descr=BasicFailDescr())] operations[1].fail_args = [] loop_token = LoopToken() cpu.compile_loop(args, operations, loop_token) self.loop_token = loop_token return loop_token
def test_overflow_mc(self): from pypy.jit.backend.x86.assembler import MachineCodeBlockWrapper orig_size = MachineCodeBlockWrapper.MC_SIZE MachineCodeBlockWrapper.MC_SIZE = 1024 old_mc = self.cpu.assembler.mc old_mc2 = self.cpu.assembler.mc2 self.cpu.assembler.mc = None try: ops = [] base_v = BoxInt() v = base_v for i in range(1024): next_v = BoxInt() ops.append(ResOperation(rop.INT_ADD, [v, ConstInt(1)], next_v)) v = next_v ops.append( ResOperation(rop.FINISH, [v], None, descr=BasicFailDescr())) looptoken = LoopToken() self.cpu.compile_loop([base_v], ops, looptoken) assert self.cpu.assembler.mc != old_mc # overflowed self.cpu.set_future_value_int(0, base_v.value) self.cpu.execute_token(looptoken) assert self.cpu.get_latest_value_int(0) == 1024 finally: MachineCodeBlockWrapper.MC_SIZE = orig_size self.cpu.assembler.mc = old_mc self.cpu.assembler.mc2 = old_mc2
def produce_into(self, builder, r): op, passing = self.gen_guard(builder, r) builder.loop.operations.append(op) op.descr = BasicFailDescr() op.fail_args = builder.subset_of_intvars(r) if not passing: builder.should_fail_by = op builder.guard_op = op
def test_stuff_followed_by_guard(self): boxes = [(BoxInt(1), BoxInt(0)), (BoxInt(0), BoxInt(1)), (BoxInt(1), BoxInt(1)), (BoxInt(-1), BoxInt(1)), (BoxInt(1), BoxInt(-1)), (ConstInt(1), BoxInt(0)), (ConstInt(0), BoxInt(1)), (ConstInt(1), BoxInt(1)), (ConstInt(-1), BoxInt(1)), (ConstInt(1), BoxInt(-1)), (BoxInt(1), ConstInt(0)), (BoxInt(0), ConstInt(1)), (BoxInt(1), ConstInt(1)), (BoxInt(-1), ConstInt(1)), (BoxInt(1), ConstInt(-1))] guards = [rop.GUARD_FALSE, rop.GUARD_TRUE] all = [rop.INT_EQ, rop.INT_NE, rop.INT_LE, rop.INT_LT, rop.INT_GT, rop.INT_GE, rop.UINT_GT, rop.UINT_LT, rop.UINT_LE, rop.UINT_GE] for a, b in boxes: for guard in guards: for op in all: res = BoxInt() i1 = BoxInt(1) ops = [ ResOperation(rop.SAME_AS, [ConstInt(1)], i1), ResOperation(op, [a, b], res), ResOperation(guard, [res], None, descr=BasicFailDescr()), ResOperation(rop.FINISH, [ConstInt(0)], None, descr=BasicFailDescr()), ] ops[-2].setfailargs([i1]) inputargs = [i for i in (a, b) if isinstance(i, Box)] looptoken = JitCellToken() self.cpu.compile_loop(inputargs, ops, looptoken) inputvalues = [box.value for box in inputargs] self.cpu.execute_token(looptoken, *inputvalues) result = self.cpu.get_latest_value_int(0) expected = execute(self.cpu, None, op, None, a, b).value if guard == rop.GUARD_FALSE: assert result == expected else: assert result != expected
def exc_handling(guard_op): # operations need to start with correct GUARD_EXCEPTION if guard_op._exc_box is None: op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None) else: op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box], BoxPtr()) op.descr = BasicFailDescr() op.fail_args = [] return op
def test_nullity_with_guard(self): allops = [rop.OONONNULL, rop.OOISNULL, rop.INT_IS_TRUE] guards = [rop.GUARD_TRUE, rop.GUARD_FALSE] p = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(lltype.GcStruct('x'))) nullptr = lltype.nullptr(llmemory.GCREF.TO) f = BoxInt() for op in allops: for guard in guards: if op == rop.INT_IS_TRUE: bp = BoxInt(1) n = BoxInt(0) else: bp = BoxPtr(p) n = BoxPtr(nullptr) for b in (bp, n): i1 = BoxInt(1) ops = [ ResOperation(rop.SAME_AS, [ConstInt(1)], i1), ResOperation(op, [b], f), ResOperation(guard, [f], None, descr=BasicFailDescr()), ResOperation(rop.FINISH, [ConstInt(0)], None, descr=BasicFailDescr()), ] ops[-2].fail_args = [i1] looptoken = LoopToken() self.cpu.compile_loop([b], ops, looptoken) if op == rop.INT_IS_TRUE: self.cpu.set_future_value_int(0, b.value) else: self.cpu.set_future_value_ref(0, b.value) r = self.cpu.execute_token(looptoken) result = self.cpu.get_latest_value_int(0) if guard == rop.GUARD_FALSE: assert result == execute(self.cpu, op, None, b).value else: assert result != execute(self.cpu, op, None, b).value
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), descr=BasicFailDescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op)
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) subset, f = self.non_raising_func_code(builder, r) if len(subset) == 0: RES = lltype.Void else: RES = lltype.Signed TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT) self.put(builder, args, descr) op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=BasicFailDescr()) op.fail_args = fail_subset builder.loop.operations.append(op)
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) if builder.fakemetainterp._got_exc: # overflow detected assert isinstance(builder.fakemetainterp._got_exc, OverflowError) op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including # the result, and then remove it from builder.intvars. fail_subset = builder.subset_of_intvars(r) builder.intvars[:] = original_intvars else: op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) op.setdescr(BasicFailDescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op)
def produce_into(self, builder, r): subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT) self.put(builder, args, descr) assert builder.cpu.get_exception() builder.cpu.clear_exception() op = ResOperation(rop.GUARD_NO_EXCEPTION, [], BoxPtr(), descr=BasicFailDescr()) op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op.fail_args = builder.subset_of_intvars(r) builder.should_fail_by = op builder.guard_op = op builder.loop.operations.append(op)
def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) original_intvars = builder.intvars[:] super(AbstractOvfOperation, self).produce_into(builder, r) if builder.cpu._overflow_flag: # overflow detected del builder.cpu._overflow_flag op = ResOperation(rop.GUARD_OVERFLOW, [], None) # the overflowed result should not be used any more, but can # be used on the failure path: recompute fail_subset including # the result, and then remove it from builder.intvars. fail_subset = builder.subset_of_intvars(r) builder.intvars[:] = original_intvars else: op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None) op.descr = BasicFailDescr() op.fail_args = fail_subset builder.loop.operations.append(op)
def test_guard_descr(self): namespace = {'fdescr': BasicFailDescr()} inp = ''' [i0] guard_true(i0, descr=fdescr) [i0] ''' loop = pure_parse(inp, namespace=namespace) logger = Logger(self.make_metainterp_sd(), guard_number=True) output = logger.log_loop(loop) assert output.splitlines()[-1] == "guard_true(i0, descr=<Guard0>) [i0]" pure_parse(output) logger = Logger(self.make_metainterp_sd(), guard_number=False) output = logger.log_loop(loop) lastline = output.splitlines()[-1] assert lastline.startswith("guard_true(i0, descr=<") assert not lastline.startswith("guard_true(i0, descr=<Guard")
def test_guard(self): namespace = {'fdescr': BasicFailDescr(4)} inp = ''' [i0] guard_true(i0, descr=fdescr) [i0] ''' loop = pure_parse(inp, namespace=namespace) logger = Logger(self.ts, guard_number=True) output = logger.log_loop(loop) assert output.splitlines()[-1] == "guard_true(i0, descr=<Guard4>) [i0]" pure_parse(output) def boom(): raise Exception namespace['fdescr'].get_index = boom logger = Logger(self.ts, guard_number=False) output = logger.log_loop(loop) assert output.splitlines()[-1].startswith("guard_true(i0, descr=<")
def generate_ops(self, builder, r, loop, startvars, needs_a_label=False): block_length = pytest.config.option.block_length istart = 0 for i in range(block_length): istart = len(loop.operations) try: op = r.choice(builder.OPERATIONS) op.filter(builder) op.produce_into(builder, r) except CannotProduceOperation: pass if builder.should_fail_by is not None: break if needs_a_label and r.random() < 0.2: self.insert_label(loop, istart, r) needs_a_label = False if needs_a_label: self.insert_label(loop, istart, r) endvars = [] used_later = {} for op in loop.operations: for v in op.getarglist(): used_later[v] = True for v in startvars: if v not in used_later: endvars.append(v) r.shuffle(endvars) loop.operations.append( ResOperation(rop.FINISH, endvars, None, descr=BasicFailDescr())) if builder.should_fail_by: self.should_fail_by = builder.should_fail_by self.guard_op = builder.guard_op else: self.should_fail_by = loop.operations[-1] self.guard_op = None self.prebuilt_ptr_consts.extend(builder.prebuilt_ptr_consts) endvars = self.get_fail_args() self.expected = {} for v in endvars: self.expected[v] = v.value if pytest.config.option.output: builder.print_loop()
def test_bug_rshift(): v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() inputargs = [v1] operations = [ ResOperation(rop.INT_ADD, [v1, v1], v2), ResOperation(rop.INT_INVERT, [v2], v3), ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4), ResOperation(rop.FINISH, [v4, v3], None, descr=BasicFailDescr()), ] cpu = CPU(None, None) looptoken = LoopToken() cpu.compile_loop(inputargs, operations, looptoken) cpu.set_future_value_int(0, 9) cpu.execute_token(looptoken) assert cpu.get_latest_value_int(0) == (9 >> 3) assert cpu.get_latest_value_int(1) == (~18)
def produce_into(self, builder, r): subset, f = self.non_raising_func_code(builder, r) if len(subset) == 0: RES = lltype.Void else: RES = lltype.Signed TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT) self.put(builder, args, descr) _, vtableptr = builder.get_random_structure_type_and_vtable(r) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), descr=BasicFailDescr()) op.fail_args = builder.subset_of_intvars(r) op._exc_box = None builder.should_fail_by = op builder.guard_op = op builder.loop.operations.append(op)
def produce_into(self, builder, r): subset, f, exc = self.raising_func_code(builder, r) TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) while True: _, vtableptr = builder.get_random_structure_type_and_vtable(r) if vtableptr != exc: break other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr(), descr=BasicFailDescr()) op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op.setfailargs(builder.subset_of_intvars(r)) builder.should_fail_by = op builder.guard_op = op builder.loop.operations.append(op)
def test_bug_int_is_true_1(): v1 = BoxInt() v2 = BoxInt() v3 = BoxInt() v4 = BoxInt() tmp5 = BoxInt() inputargs = [v1] operations = [ ResOperation(rop.INT_MUL, [v1, v1], v2), ResOperation(rop.INT_MUL, [v2, v1], v3), ResOperation(rop.INT_IS_TRUE, [v2], tmp5), ResOperation(rop.BOOL_NOT, [tmp5], v4), ResOperation(rop.FINISH, [v4, v3, tmp5], None, descr=BasicFailDescr()), ] cpu = CPU(None, None) looptoken = LoopToken() cpu.compile_loop(inputargs, operations, looptoken) cpu.set_future_value_int(0, -10) cpu.execute_token(looptoken) assert cpu.get_latest_value_int(0) == 0 assert cpu.get_latest_value_int(1) == -1000 assert cpu.get_latest_value_int(2) == 1
def generate_ops(self, builder, r, loop, startvars): block_length = demo_conftest.option.block_length for i in range(block_length): try: op = r.choice(builder.OPERATIONS) op.filter(builder) op.produce_into(builder, r) except CannotProduceOperation: pass if builder.should_fail_by is not None: break endvars = [] used_later = {} for op in loop.operations: for v in op.args: used_later[v] = True for v in startvars: if v not in used_later: endvars.append(v) r.shuffle(endvars) loop.operations.append( ResOperation(rop.FINISH, endvars, None, descr=BasicFailDescr())) if builder.should_fail_by: self.should_fail_by = builder.should_fail_by self.guard_op = builder.guard_op else: self.should_fail_by = loop.operations[-1] self.guard_op = None self.prebuilt_ptr_consts.extend(builder.prebuilt_ptr_consts) endvars = self.get_fail_args() self.expected = {} for v in endvars: self.expected[v] = v.value if demo_conftest.option.output: builder.print_loop()
def test_bug_1(): 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() v20 = BoxInt() v21 = BoxInt() v22 = BoxInt() v23 = BoxInt() v24 = BoxInt() v25 = BoxInt() v26 = BoxInt() v27 = BoxInt() v28 = BoxInt() v29 = BoxInt() v30 = BoxInt() v31 = BoxInt() v32 = BoxInt() v33 = BoxInt() v34 = BoxInt() v35 = BoxInt() v36 = BoxInt() v37 = BoxInt() v38 = BoxInt() v39 = BoxInt() v40 = BoxInt() tmp41 = BoxInt() tmp42 = BoxInt() tmp43 = BoxInt() tmp44 = BoxInt() tmp45 = BoxInt() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.UINT_LT, [v6, ConstInt(0)], v11), ResOperation(rop.INT_AND, [v3, ConstInt(31)], tmp41), ResOperation(rop.INT_RSHIFT, [v3, tmp41], v12), ResOperation(rop.INT_NEG, [v2], v13), ResOperation(rop.INT_ADD, [v11, v7], v14), ResOperation(rop.INT_OR, [v3, v2], v15), ResOperation(rop.INT_OR, [v12, v12], v16), ResOperation(rop.INT_NE, [v2, v5], v17), ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp42), ResOperation(rop.UINT_RSHIFT, [v14, tmp42], v18), ResOperation(rop.INT_AND, [v14, ConstInt(31)], tmp43), ResOperation(rop.INT_LSHIFT, [ConstInt(7), tmp43], v19), ResOperation(rop.INT_NEG, [v19], v20), ResOperation(rop.INT_MOD, [v3, ConstInt(1)], v21), ResOperation(rop.UINT_GE, [v15, v1], v22), ResOperation(rop.INT_AND, [v16, ConstInt(31)], tmp44), ResOperation(rop.INT_LSHIFT, [v8, tmp44], v23), ResOperation(rop.INT_IS_TRUE, [v17], v24), ResOperation(rop.INT_AND, [v5, ConstInt(31)], tmp45), ResOperation(rop.INT_LSHIFT, [v14, tmp45], v25), ResOperation(rop.INT_LSHIFT, [v5, ConstInt(17)], v26), ResOperation(rop.INT_EQ, [v9, v15], v27), ResOperation(rop.INT_GE, [ConstInt(0), v6], v28), ResOperation(rop.INT_NEG, [v15], v29), ResOperation(rop.INT_NEG, [v22], v30), ResOperation(rop.INT_ADD, [v7, v16], v31), ResOperation(rop.UINT_LT, [v19, v19], v32), ResOperation(rop.INT_ADD, [v2, ConstInt(1)], v33), ResOperation(rop.INT_NEG, [v5], v34), ResOperation(rop.INT_ADD, [v17, v24], v35), ResOperation(rop.UINT_LT, [ConstInt(2), v16], v36), ResOperation(rop.INT_NEG, [v9], v37), ResOperation(rop.INT_GT, [v4, v11], v38), ResOperation(rop.INT_LT, [v27, v22], v39), ResOperation(rop.INT_NEG, [v27], v40), ResOperation(rop.FINISH, [v40, v10, v36, v26, v13, v30, v21, v33, v18, v25, v31, v32, v28, v29, v35, v38, v20, v39, v34, v23, v37], None, descr=BasicFailDescr()), ] cpu = CPU(None, None) looptoken = LoopToken() cpu.compile_loop(inputargs, operations, looptoken) cpu.set_future_value_int(0, 17) cpu.set_future_value_int(1, -20) cpu.set_future_value_int(2, -6) cpu.set_future_value_int(3, 6) cpu.set_future_value_int(4, 1) cpu.set_future_value_int(5, 13) cpu.set_future_value_int(6, 13) cpu.set_future_value_int(7, 9) cpu.set_future_value_int(8, 49) cpu.set_future_value_int(9, 8) cpu.execute_token(looptoken) assert cpu.get_latest_value_int(0) == 0 assert cpu.get_latest_value_int(1) == 8 assert cpu.get_latest_value_int(2) == 1 assert cpu.get_latest_value_int(3) == 131072 assert cpu.get_latest_value_int(4) == 20 assert cpu.get_latest_value_int(5) == -1 assert cpu.get_latest_value_int(6) == 0 assert cpu.get_latest_value_int(7) == -19 assert cpu.get_latest_value_int(8) == 6 assert cpu.get_latest_value_int(9) == 26 assert cpu.get_latest_value_int(10) == 12 assert cpu.get_latest_value_int(11) == 0 assert cpu.get_latest_value_int(12) == 0 assert cpu.get_latest_value_int(13) == 2 assert cpu.get_latest_value_int(14) == 2 assert cpu.get_latest_value_int(15) == 1 assert cpu.get_latest_value_int(16) == -57344 assert cpu.get_latest_value_int(17) == 1 assert cpu.get_latest_value_int(18) == -1 assert cpu.get_latest_value_int(19) == -2147483648 assert cpu.get_latest_value_int(20) == -49
def default_fail_descr(fail_args=None): return BasicFailDescr()
class BaseTestRegalloc(object): cpu = CPU(None, None) 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 = cpu.get_zero_division_error() 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) fdescr1 = BasicFailDescr(1) fdescr2 = BasicFailDescr(2) fdescr3 = BasicFailDescr(3) namespace = locals().copy() type_system = 'lltype' def parse(self, s, boxkinds=None): return parse(s, self.cpu, self.namespace, type_system=self.type_system, boxkinds=boxkinds) def interpret(self, ops, args, run=True): loop = self.parse(ops) self.cpu.compile_loop(loop.inputargs, loop.operations, loop.token) for i, arg in enumerate(args): if isinstance(arg, int): self.cpu.set_future_value_int(i, arg) elif isinstance(arg, float): self.cpu.set_future_value_float(i, arg) else: assert isinstance(lltype.typeOf(arg), lltype.Ptr) llgcref = lltype.cast_opaque_ptr(llmemory.GCREF, arg) self.cpu.set_future_value_ref(i, llgcref) if run: self.cpu.execute_token(loop.token) return loop def getint(self, index): return self.cpu.get_latest_value_int(index) def getfloat(self, index): return self.cpu.get_latest_value_float(index) def getints(self, end): return [ self.cpu.get_latest_value_int(index) for index in range(0, end) ] def getfloats(self, end): return [ self.cpu.get_latest_value_float(index) for index in range(0, end) ] def getptr(self, index, T): gcref = self.cpu.get_latest_value_ref(index) return lltype.cast_opaque_ptr(T, gcref) def attach_bridge(self, ops, loop, guard_op_index, looptoken=None, **kwds): if looptoken is not None: self.namespace = self.namespace.copy() self.namespace['looptoken'] = looptoken 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.fail_args]) faildescr = guard_op.descr self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations) return bridge def run(self, loop): return self.cpu.execute_token(loop.token)
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 = cpu.get_zero_division_error() 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._x86_loop_code = 0 self.targettoken2._x86_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() type_system = 'lltype' def parse(self, s, boxkinds=None): return parse(s, self.cpu, self.namespace, type_system=self.type_system, boxkinds=boxkinds) def interpret(self, ops, args, run=True): loop = self.parse(ops) 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.cpu.execute_token(looptoken, *arguments) return loop def prepare_loop(self, ops): loop = self.parse(ops) regalloc = RegAlloc(self.cpu.assembler, False) regalloc.prepare_loop(loop.inputargs, loop.operations, loop.original_jitcell_token, []) return regalloc def getint(self, index): return self.cpu.get_latest_value_int(index) def getfloat(self, index): return self.cpu.get_latest_value_float(index) def getints(self, end): return [self.cpu.get_latest_value_int(index) for index in range(0, end)] def getfloats(self, end): return [longlong.getrealfloat(self.cpu.get_latest_value_float(index)) for index in range(0, end)] def getptr(self, index, T): gcref = self.cpu.get_latest_value_ref(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): return self.cpu.execute_token(loop._jitcelltoken, *arguments)
def test_calling_convention(self, monkeypatch): if WORD != 4: py.test.skip("32-bit only test") from pypy.jit.backend.x86.regloc import eax, edx from pypy.jit.backend.x86 import codebuf from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.rlib.libffi import types, clibffi had_stdcall = hasattr(clibffi, 'FFI_STDCALL') if not had_stdcall: # not running on Windows, but we can still test monkeypatch.setattr(clibffi, 'FFI_STDCALL', 12345, raising=False) # for ffi in [clibffi.FFI_DEFAULT_ABI, clibffi.FFI_STDCALL]: cpu = self.cpu mc = codebuf.MachineCodeBlockWrapper() mc.MOV_rs(eax.value, 4) # argument 1 mc.MOV_rs(edx.value, 40) # argument 10 mc.SUB_rr(eax.value, edx.value) # return arg1 - arg10 if ffi == clibffi.FFI_DEFAULT_ABI: mc.RET() else: mc.RET16_i(40) rawstart = mc.materialize(cpu.asmmemmgr, []) # calldescr = cpu.calldescrof_dynamic([types.slong] * 10, types.slong, EffectInfo.MOST_GENERAL, ffi_flags=-1) calldescr.get_call_conv = lambda: ffi # <==== hack # ^^^ we patch get_call_conv() so that the test also makes sense # on Linux, because clibffi.get_call_conv() would always # return FFI_DEFAULT_ABI on non-Windows platforms. funcbox = ConstInt(rawstart) i1 = BoxInt() i2 = BoxInt() i3 = BoxInt() i4 = BoxInt() i5 = BoxInt() i6 = BoxInt() c = ConstInt(-1) faildescr = BasicFailDescr(1) # we must call it repeatedly: if the stack pointer gets increased # by 40 bytes by the STDCALL call, and if we don't expect it, # then we are going to get our stack emptied unexpectedly by # several repeated calls ops = [ ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1, c, c, c, c, c, c, c, c, i2], i3, descr=calldescr), ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1, c, c, c, c, c, c, c, c, i2], i4, descr=calldescr), ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1, c, c, c, c, c, c, c, c, i2], i5, descr=calldescr), ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), ResOperation(rop.CALL_RELEASE_GIL, [funcbox, i1, c, c, c, c, c, c, c, c, i2], i6, descr=calldescr), ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), ResOperation(rop.FINISH, [i3, i4, i5, i6], None, descr=BasicFailDescr(0)) ] ops[1].setfailargs([]) ops[3].setfailargs([]) ops[5].setfailargs([]) ops[7].setfailargs([]) looptoken = JitCellToken() self.cpu.compile_loop([i1, i2], ops, looptoken) fail = self.cpu.execute_token(looptoken, 123450, 123408) assert fail.identifier == 0 assert self.cpu.get_latest_value_int(0) == 42 assert self.cpu.get_latest_value_int(1) == 42 assert self.cpu.get_latest_value_int(2) == 42 assert self.cpu.get_latest_value_int(3) == 42
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 = BoxInt() i1 = BoxInt() i2 = BoxInt() 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], 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._x86_loop_code assert loopsize >= 40 # randomish number i1b = BoxInt() i3 = BoxInt() 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], 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 fail = self.cpu.execute_token(looptoken, 2) assert fail.identifier == 2 res = self.cpu.get_latest_value_int(0) assert res == 20
def test_call_alignment_call_assembler(self): from pypy.rlib.libffi import types cpu = self.cpu if not cpu.supports_floats: py.test.skip('requires floats') fdescr3 = BasicFailDescr(3) fdescr4 = BasicFailDescr(4) def assembler_helper(failindex, virtualizable): assert 0, 'should not be called, but was with failindex (%d)' % failindex return 13 FUNCPTR = lltype.Ptr( lltype.FuncType([lltype.Signed, llmemory.GCREF], lltype.Signed)) class FakeJitDriverSD: index_of_virtualizable = -1 _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper) assembler_helper_adr = llmemory.cast_ptr_to_adr( _assembler_helper_ptr) floats = [0.7, 5.8, 0.1, 0.3, 0.9, -2.34, -3.45, -4.56] ints = [7, 11, 23, 42, -42, 1111, 95, 1] for case in range(256): float_count = 0 int_count = 0 args = [] called_ops = '' total_index = -1 for i in range(8): if case & (1 << i): args.append('f%d' % float_count) else: args.append('i%d' % int_count) called_ops += 'f%d = cast_int_to_float(i%d)\n' % ( float_count, int_count) int_count += 1 if total_index == -1: total_index = float_count float_count += 1 else: called_ops += 'f%d = float_add(f%d, f%d)\n' % ( float_count + 1, total_index, float_count) total_index = float_count + 1 float_count += 2 arguments = ', '.join(args) called_ops = '[%s]\n' % arguments + called_ops called_ops += 'finish(f%d, descr=fdescr3)\n' % total_index # compile called loop called_loop = parse(called_ops, namespace=locals()) called_looptoken = JitCellToken() called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD() done_number = self.cpu.get_fail_descr_number( called_loop.operations[-1].getdescr()) self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken) argvals, expected_result = self._prepare_args(args, floats, ints) res = cpu.execute_token(called_looptoken, *argvals) assert res.identifier == 3 t = longlong.getrealfloat(cpu.get_latest_value_float(0)) assert abs(t - expected_result) < 0.0001 ARGS = [] RES = lltype.Float for x in args: if x[0] == 'f': ARGS.append(lltype.Float) else: ARGS.append(lltype.Signed) FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof( lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES, EffectInfo.MOST_GENERAL) ops = ''' [%s] f99 = call_assembler(%s, descr=called_looptoken) guard_not_forced()[] finish(f99, descr=fdescr4) ''' % (arguments, arguments) loop = parse(ops, namespace=locals()) # we want to take the fast path self.cpu.done_with_this_frame_float_v = done_number try: othertoken = JitCellToken() self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken) # prepare call to called_loop argvals, _ = self._prepare_args(args, floats, ints) res = cpu.execute_token(othertoken, *argvals) x = longlong.getrealfloat(cpu.get_latest_value_float(0)) assert res.identifier == 4 assert abs(x - expected_result) < 0.0001 finally: del self.cpu.done_with_this_frame_float_v
def make_fail_descr(cls): descr = BasicFailDescr(cls.failnumbering) cls.failnumbering += 1 return descr
def test_bug_0(): 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() v20 = BoxInt() v21 = BoxInt() v22 = BoxInt() v23 = BoxInt() v24 = BoxInt() v25 = BoxInt() v26 = BoxInt() v27 = BoxInt() v28 = BoxInt() v29 = BoxInt() v30 = BoxInt() v31 = BoxInt() v32 = BoxInt() v33 = BoxInt() v34 = BoxInt() v35 = BoxInt() v36 = BoxInt() v37 = BoxInt() v38 = BoxInt() v39 = BoxInt() v40 = BoxInt() tmp41 = BoxInt() tmp42 = BoxInt() tmp43 = BoxInt() tmp44 = BoxInt() tmp45 = BoxInt() tmp46 = BoxInt() inputargs = [v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] operations = [ ResOperation(rop.UINT_GT, [v3, ConstInt(-48)], v11), ResOperation(rop.INT_XOR, [v8, v1], v12), ResOperation(rop.INT_GT, [v6, ConstInt(-9)], v13), ResOperation(rop.INT_LE, [v13, v2], v14), ResOperation(rop.INT_LE, [v11, v5], v15), ResOperation(rop.UINT_GE, [v13, v13], v16), ResOperation(rop.INT_OR, [v9, ConstInt(-23)], v17), ResOperation(rop.INT_LT, [v10, v13], v18), ResOperation(rop.INT_OR, [v15, v5], v19), ResOperation(rop.INT_XOR, [v17, ConstInt(54)], v20), ResOperation(rop.INT_MUL, [v8, v10], v21), ResOperation(rop.INT_OR, [v3, v9], v22), ResOperation(rop.INT_AND, [v11, ConstInt(-4)], tmp41), ResOperation(rop.INT_OR, [tmp41, ConstInt(1)], tmp42), ResOperation(rop.INT_MOD, [v12, tmp42], v23), ResOperation(rop.INT_IS_TRUE, [v6], v24), ResOperation(rop.UINT_RSHIFT, [v15, ConstInt(6)], v25), ResOperation(rop.INT_OR, [ConstInt(-4), v25], v26), ResOperation(rop.INT_INVERT, [v8], v27), ResOperation(rop.INT_SUB, [ConstInt(-113), v11], v28), ResOperation(rop.INT_NEG, [v7], v29), ResOperation(rop.INT_NEG, [v24], v30), ResOperation(rop.INT_FLOORDIV, [v3, ConstInt(53)], v31), ResOperation(rop.INT_MUL, [v28, v27], v32), ResOperation(rop.INT_AND, [v18, ConstInt(-4)], tmp43), ResOperation(rop.INT_OR, [tmp43, ConstInt(1)], tmp44), ResOperation(rop.INT_MOD, [v26, tmp44], v33), ResOperation(rop.INT_OR, [v27, v19], v34), ResOperation(rop.UINT_LT, [v13, ConstInt(1)], v35), ResOperation(rop.INT_AND, [v21, ConstInt(31)], tmp45), ResOperation(rop.INT_RSHIFT, [v21, tmp45], v36), ResOperation(rop.INT_AND, [v20, ConstInt(31)], tmp46), ResOperation(rop.UINT_RSHIFT, [v4, tmp46], v37), ResOperation(rop.UINT_GT, [v33, ConstInt(-11)], v38), ResOperation(rop.INT_NEG, [v7], v39), ResOperation(rop.INT_GT, [v24, v32], v40), ResOperation(rop.FINISH, [v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38], None, descr=BasicFailDescr()), ] cpu = CPU(None, None) looptoken = LoopToken() cpu.compile_loop(inputargs, operations, looptoken) cpu.set_future_value_int(0, -13) cpu.set_future_value_int(1, 10) cpu.set_future_value_int(2, 10) cpu.set_future_value_int(3, 8) cpu.set_future_value_int(4, -8) cpu.set_future_value_int(5, -16) cpu.set_future_value_int(6, -18) cpu.set_future_value_int(7, 46) cpu.set_future_value_int(8, -12) cpu.set_future_value_int(9, 26) cpu.execute_token(looptoken) assert cpu.get_latest_value_int(0) == 0 assert cpu.get_latest_value_int(1) == 0 assert cpu.get_latest_value_int(2) == 0 assert cpu.get_latest_value_int(3) == 0 assert cpu.get_latest_value_int(4) == 1 assert cpu.get_latest_value_int(5) == -7 assert cpu.get_latest_value_int(6) == 1 assert cpu.get_latest_value_int(7) == 0 assert cpu.get_latest_value_int(8) == -2 assert cpu.get_latest_value_int(9) == 18 assert cpu.get_latest_value_int(10) == 1 assert cpu.get_latest_value_int(11) == 18 assert cpu.get_latest_value_int(12) == -1 assert cpu.get_latest_value_int(13) == 0