def test_get_deep_immutable_oplist(): ops = [rop.ResOperation(rop.rop.INT_ADD, ['a', 'b'], 'c')] newops = rop.get_deep_immutable_oplist(ops) py.test.raises(TypeError, "newops.append('foobar')") py.test.raises(TypeError, "newops[0] = 'foobar'") py.test.raises(AssertionError, "newops[0].setarg(0, 'd')") py.test.raises(AssertionError, "newops[0].setdescr('foobar')")
def test_record_constptrs(self): class MyFakeCPU(object): def cast_adr_to_int(self, adr): assert adr == "some fake address" return 43 class MyFakeGCRefList(object): def get_address_of_gcref(self, s_gcref1): assert s_gcref1 == s_gcref return "some fake address" S = lltype.GcStruct('S') s = lltype.malloc(S) s_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, s) v_random_box = BoxPtr() v_result = BoxInt() operations = [ ResOperation(rop.PTR_EQ, [v_random_box, ConstPtr(s_gcref)], v_result), ] gc_ll_descr = self.gc_ll_descr gc_ll_descr.gcrefs = MyFakeGCRefList() gcrefs = [] operations = get_deep_immutable_oplist(operations) operations2 = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations, gcrefs) assert operations2 == operations assert gcrefs == [s_gcref]
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token): n = metainterp_sd.cpu.get_fail_descr_number(faildescr) if not we_are_translated(): show_procedures(metainterp_sd) seen = dict.fromkeys(inputargs) TreeLoop.check_consistency_of_branch(operations, seen) if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo( jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, "bridge", fail_descr_no=n ) hooks.before_compile_bridge(debug_info) else: hooks = None debug_info = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, n, ops_offset)
def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type): jitdriver_sd.on_compile(metainterp_sd.logger_ops, loop.token, loop.operations, type, greenkey) loopname = jitdriver_sd.warmstate.get_location_str(greenkey) globaldata = metainterp_sd.globaldata loop_token = loop.token loop_token.number = n = globaldata.loopnumbering globaldata.loopnumbering += 1 if not we_are_translated(): show_loop(metainterp_sd, loop) loop.check_consistency() operations = get_deep_immutable_oplist(loop.operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: ops_offset = metainterp_sd.cpu.compile_loop(loop.inputargs, operations, loop.token, name=loopname) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() metainterp_sd.stats.add_new_loop(loop) if not we_are_translated(): if type != "entry bridge": metainterp_sd.stats.compiled() else: loop._ignore_during_counting = True metainterp_sd.log("compiled new " + type) # metainterp_sd.logger_ops.log_loop(loop.inputargs, loop.operations, n, type, ops_offset) short = loop.token.short_preamble if short: metainterp_sd.logger_ops.log_short_preamble(short[-1].inputargs, short[-1].operations) # if metainterp_sd.warmrunnerdesc is not None: # for tests metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive(loop.token)
def test_rewrite_assembler_initialization_store_2(self): S = lltype.GcStruct('S', ('parent', OBJECT), ('x', lltype.Signed)) s_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True) wbdescr = self.gc_ll_descr.write_barrier_descr xdescr = get_field_descr(self.gc_ll_descr, S, 'x') ops = parse(""" [p1] p0 = new_with_vtable(ConstClass(s_vtable)) p3 = new_with_vtable(ConstClass(s_vtable)) setfield_gc(p0, p1, descr=xdescr) jump() """, namespace=locals()) expected = parse(""" [p1] p0 = new_with_vtable(ConstClass(s_vtable)) p3 = new_with_vtable(ConstClass(s_vtable)) cond_call_gc_wb(p0, p1, descr=wbdescr) setfield_raw(p0, p1, descr=xdescr) jump() """, namespace=locals()) operations = get_deep_immutable_oplist(ops.operations) operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu, operations, []) equaloplists(operations, expected.operations)
def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type): vinfo = jitdriver_sd.virtualizable_info if vinfo is not None: patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd) original_jitcell_token = loop.original_jitcell_token loopname = jitdriver_sd.warmstate.get_location_str(greenkey) globaldata = metainterp_sd.globaldata original_jitcell_token.number = n = globaldata.loopnumbering globaldata.loopnumbering += 1 if not we_are_translated(): show_procedures(metainterp_sd, loop) loop.check_consistency() if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_jitcell_token, loop.operations, type, greenkey) hooks.before_compile(debug_info) else: debug_info = None hooks = None operations = get_deep_immutable_oplist(loop.operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: asminfo = do_compile_loop(metainterp_sd, loop.inputargs, operations, original_jitcell_token, name=loopname) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile(debug_info) metainterp_sd.stats.add_new_loop(loop) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new " + type) # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_loop(loop.inputargs, loop.operations, n, type, ops_offset, name=loopname) # if metainterp_sd.warmrunnerdesc is not None: # for tests metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive( original_jitcell_token)
def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type): vinfo = jitdriver_sd.virtualizable_info if vinfo is not None: patch_new_loop_to_load_virtualizable_fields(loop, jitdriver_sd) original_jitcell_token = loop.original_jitcell_token loopname = jitdriver_sd.warmstate.get_location_str(greenkey) globaldata = metainterp_sd.globaldata original_jitcell_token.number = n = globaldata.loopnumbering globaldata.loopnumbering += 1 if not we_are_translated(): show_procedures(metainterp_sd, loop) loop.check_consistency() if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_jitcell_token, loop.operations, type, greenkey) hooks.before_compile(debug_info) else: debug_info = None hooks = None operations = get_deep_immutable_oplist(loop.operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: asminfo = metainterp_sd.cpu.compile_loop(loop.inputargs, operations, original_jitcell_token, name=loopname) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile(debug_info) metainterp_sd.stats.add_new_loop(loop) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new " + type) # loopname = jitdriver_sd.warmstate.get_location_str(greenkey) if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_loop(loop.inputargs, loop.operations, n, type, ops_offset, name=loopname) # if metainterp_sd.warmrunnerdesc is not None: # for tests metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive(original_jitcell_token)
def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redargtypes, memory_manager=None): """Make a LoopToken that corresponds to assembler code that just calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ jitcell_token = make_jitcell_token(jitdriver_sd) nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args inputargs = [] for kind in redargtypes: if kind == history.INT: box = BoxInt() elif kind == history.REF: box = BoxPtr() elif kind == history.FLOAT: box = BoxFloat() else: raise AssertionError inputargs.append(box) k = jitdriver_sd.portal_runner_adr funcbox = history.ConstInt(heaptracker.adr2int(k)) callargs = [funcbox] + greenboxes + inputargs # result_type = jitdriver_sd.result_type if result_type == history.INT: result = BoxInt() elif result_type == history.REF: result = BoxPtr() elif result_type == history.FLOAT: result = BoxFloat() elif result_type == history.VOID: result = None else: assert 0, "bad result_type" if result is not None: finishargs = [result] else: finishargs = [] # jd = jitdriver_sd faildescr = PropagateExceptionDescr() operations = [ ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr), ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken) ] operations[1].setfailargs([]) operations = get_deep_immutable_oplist(operations) cpu.compile_loop(inputargs, operations, jitcell_token, log=False) if memory_manager is not None: # for tests memory_manager.keep_loop_alive(jitcell_token) return jitcell_token
def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redargtypes, memory_manager=None): """Make a LoopToken that corresponds to assembler code that just calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ jitcell_token = make_jitcell_token(jitdriver_sd) nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args inputargs = [] for kind in redargtypes: if kind == history.INT: box = BoxInt() elif kind == history.REF: box = BoxPtr() elif kind == history.FLOAT: box = BoxFloat() else: raise AssertionError inputargs.append(box) k = jitdriver_sd.portal_runner_adr funcbox = history.ConstInt(heaptracker.adr2int(k)) callargs = [funcbox] + greenboxes + inputargs # result_type = jitdriver_sd.result_type if result_type == history.INT: result = BoxInt() elif result_type == history.REF: result = BoxPtr() elif result_type == history.FLOAT: result = BoxFloat() elif result_type == history.VOID: result = None else: assert 0, "bad result_type" if result is not None: finishargs = [result] else: finishargs = [] # jd = jitdriver_sd faildescr = PropagateExceptionDescr() operations = [ ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr), ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken), ] operations[1].setfailargs([]) operations = get_deep_immutable_oplist(operations) cpu.compile_loop(inputargs, operations, jitcell_token, log=False) if memory_manager is not None: # for tests memory_manager.keep_loop_alive(jitcell_token) return jitcell_token
def test_rewrite_assembler_4(self): # check write barriers before SETARRAYITEM_GC, # if we have actually a write_barrier_from_array. self.llop1._have_wb_from_array = True for v_new_length in (None, ConstInt(5), ConstInt(5000), BoxInt()): v_base = BoxPtr() v_index = BoxInt() v_value = BoxPtr() array_descr = AbstractDescr() operations = [ ResOperation(rop.SETARRAYITEM_GC, [v_base, v_index, v_value], None, descr=array_descr), ] if v_new_length is not None: operations.insert(0, ResOperation(rop.NEW_ARRAY, [v_new_length], v_base, descr=array_descr)) # we need to insert another, unrelated NEW_ARRAY here # to prevent the initialization_store optimization operations.insert(1, ResOperation(rop.NEW_ARRAY, [ConstInt(12)], BoxPtr(), descr=array_descr)) gc_ll_descr = self.gc_ll_descr operations = get_deep_immutable_oplist(operations) operations = gc_ll_descr.rewrite_assembler(self.fake_cpu, operations, []) if v_new_length is not None: assert operations[0].getopnum() == rop.NEW_ARRAY assert operations[1].getopnum() == rop.NEW_ARRAY del operations[:2] assert len(operations) == 2 # if isinstance(v_new_length, ConstInt) and v_new_length.value < 130: assert operations[0].getopnum() == rop.COND_CALL_GC_WB assert operations[0].getarg(0) == v_base assert operations[0].getarg(1) == v_value else: assert operations[0].getopnum() == rop.COND_CALL_GC_WB_ARRAY assert operations[0].getarg(0) == v_base assert operations[0].getarg(1) == v_index assert operations[0].getarg(2) == v_value assert operations[0].result is None # assert operations[1].getopnum() == rop.SETARRAYITEM_RAW assert operations[1].getarg(0) == v_base assert operations[1].getarg(1) == v_index assert operations[1].getarg(2) == v_value assert operations[1].getdescr() == array_descr
def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redboxes, memory_manager=None): """Make a LoopToken that corresponds to assembler code that just calls back the interpreter. Used temporarily: a fully compiled version of the code may end up replacing it. """ # 'redboxes' is only used to know the types of red arguments. inputargs = [box.clonebox() for box in redboxes] loop_token = make_loop_token(len(inputargs), jitdriver_sd) # 'nb_red_args' might be smaller than len(redboxes), # because it doesn't include the virtualizable boxes. nb_red_args = jitdriver_sd.num_red_args k = jitdriver_sd.portal_runner_adr funcbox = history.ConstInt(heaptracker.adr2int(k)) callargs = [funcbox] + greenboxes + inputargs[:nb_red_args] # result_type = jitdriver_sd.result_type if result_type == history.INT: result = BoxInt() elif result_type == history.REF: result = BoxPtr() elif result_type == history.FLOAT: result = BoxFloat() elif result_type == history.VOID: result = None else: assert 0, "bad result_type" if result is not None: finishargs = [result] else: finishargs = [] # jd = jitdriver_sd faildescr = propagate_exception_descr operations = [ ResOperation(rop.CALL, callargs, result, descr=jd.portal_calldescr), ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr), ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken), ] operations[1].setfailargs([]) operations = get_deep_immutable_oplist(operations) cpu.compile_loop(inputargs, operations, loop_token, log=False) if memory_manager is not None: # for tests memory_manager.keep_loop_alive(loop_token) return loop_token
def test_rewrite_assembler_initialization_store_3(self): A = lltype.GcArray(lltype.Ptr(lltype.GcStruct('S'))) arraydescr = get_array_descr(self.gc_ll_descr, A) ops = parse(""" [p1] p0 = new_array(3, descr=arraydescr) setarrayitem_gc(p0, 0, p1, descr=arraydescr) jump() """, namespace=locals()) expected = parse(""" [p1] p0 = new_array(3, descr=arraydescr) setarrayitem_gc(p0, 0, p1, descr=arraydescr) jump() """, namespace=locals()) operations = get_deep_immutable_oplist(ops.operations) operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu, operations, []) equaloplists(operations, expected.operations)
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token): n = metainterp_sd.cpu.get_fail_descr_number(faildescr) if not we_are_translated(): show_procedures(metainterp_sd) seen = dict.fromkeys(inputargs) TreeLoop.check_consistency_of_branch(operations, seen) if metainterp_sd.warmrunnerdesc is not None: hooks = metainterp_sd.warmrunnerdesc.hooks debug_info = JitDebugInfo(jitdriver_sd, metainterp_sd.logger_ops, original_loop_token, operations, 'bridge', fail_descr_no=n) hooks.before_compile_bridge(debug_info) else: hooks = None debug_info = None operations = get_deep_immutable_oplist(operations) metainterp_sd.profiler.start_backend() debug_start("jit-backend") try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, original_loop_token) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if hooks is not None: debug_info.asminfo = asminfo hooks.after_compile_bridge(debug_info) if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # if asminfo is not None: ops_offset = asminfo.ops_offset else: ops_offset = None metainterp_sd.logger_ops.log_bridge(inputargs, operations, n, ops_offset)
def send_bridge_to_backend(jitdriver_sd, metainterp_sd, faildescr, inputargs, operations, original_loop_token): n = metainterp_sd.cpu.get_fail_descr_number(faildescr) jitdriver_sd.on_compile_bridge(metainterp_sd.logger_ops, original_loop_token, operations, n) if not we_are_translated(): show_loop(metainterp_sd) TreeLoop.check_consistency_of(inputargs, operations) metainterp_sd.profiler.start_backend() operations = get_deep_immutable_oplist(operations) debug_start("jit-backend") try: ops_offset = metainterp_sd.cpu.compile_bridge(faildescr, inputargs, operations, original_loop_token) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() if not we_are_translated(): metainterp_sd.stats.compiled() metainterp_sd.log("compiled new bridge") # metainterp_sd.logger_ops.log_bridge(inputargs, operations, n, ops_offset) # if metainterp_sd.warmrunnerdesc is not None: # for tests metainterp_sd.warmrunnerdesc.memory_manager.keep_loop_alive(original_loop_token)
def test_rewrite_assembler_2(self): # check write barriers before SETFIELD_GC v_base = BoxPtr() v_value = BoxPtr() field_descr = AbstractDescr() operations = [ ResOperation(rop.SETFIELD_GC, [v_base, v_value], None, descr=field_descr), ] gc_ll_descr = self.gc_ll_descr operations = get_deep_immutable_oplist(operations) operations = gc_ll_descr.rewrite_assembler(self.fake_cpu, operations, []) assert len(operations) == 2 # assert operations[0].getopnum() == rop.COND_CALL_GC_WB assert operations[0].getarg(0) == v_base assert operations[0].getarg(1) == v_value assert operations[0].result is None # assert operations[1].getopnum() == rop.SETFIELD_RAW assert operations[1].getarg(0) == v_base assert operations[1].getarg(1) == v_value assert operations[1].getdescr() == field_descr