def gen_malloc_frame(self, frame_info, frame, size_box): descrs = self.gc_ll_descr.getframedescrs(self.cpu) if self.gc_ll_descr.kind == 'boehm': op0 = ResOperation(rop.GETFIELD_RAW, [history.ConstInt(frame_info)], size_box, descr=descrs.jfi_frame_depth) self.newops.append(op0) op1 = ResOperation(rop.NEW_ARRAY, [size_box], frame, descr=descrs.arraydescr) self.handle_new_array(descrs.arraydescr, op1) else: # we read size in bytes here, not the length op0 = ResOperation(rop.GETFIELD_RAW, [history.ConstInt(frame_info)], size_box, descr=descrs.jfi_frame_size) self.newops.append(op0) self.gen_malloc_nursery_varsize_frame(size_box, frame) self.gen_initialize_tid(frame, descrs.arraydescr.tid) length_box = history.BoxInt() # we need to explicitely zero all the gc fields, because # of the unusal malloc pattern extra_ops = [ ResOperation(rop.GETFIELD_RAW, [history.ConstInt(frame_info)], length_box, descr=descrs.jfi_frame_depth), ResOperation(rop.SETFIELD_GC, [frame, self.c_zero], None, descr=descrs.jf_extra_stack_depth), ResOperation(rop.SETFIELD_GC, [frame, self.c_null], None, descr=descrs.jf_savedata), ResOperation(rop.SETFIELD_GC, [frame, self.c_null], None, descr=descrs.jf_force_descr), ResOperation(rop.SETFIELD_GC, [frame, self.c_null], None, descr=descrs.jf_descr), ResOperation(rop.SETFIELD_GC, [frame, self.c_null], None, descr=descrs.jf_guard_exc), ResOperation(rop.SETFIELD_GC, [frame, self.c_null], None, descr=descrs.jf_forward), ] self.newops += extra_ops self.gen_initialize_len(frame, length_box, descrs.arraydescr.lendescr)
def __init__(self, warmrunnerdesc): self.warmrunnerdesc = warmrunnerdesc self.cpu = warmrunnerdesc.cpu # we make the low-level type of an RPython class directly self.JIT_VIRTUAL_REF = lltype.GcStruct( 'JitVirtualRef', ('super', rclass.OBJECT), ('virtual_token', llmemory.GCREF), ('forced', rclass.OBJECTPTR)) self.jit_virtual_ref_vtable = lltype.malloc(rclass.OBJECT_VTABLE, zero=True, flavor='raw', immortal=True) self.jit_virtual_ref_vtable.name = rclass.alloc_array_name( 'jit_virtual_ref') # build some constants adr = llmemory.cast_ptr_to_adr(self.jit_virtual_ref_vtable) adr = heaptracker.adr2int(adr) self.jit_virtual_ref_const_class = history.ConstInt(adr) fielddescrof = self.cpu.fielddescrof self.descr_virtual_token = fielddescrof(self.JIT_VIRTUAL_REF, 'virtual_token') self.descr_forced = fielddescrof(self.JIT_VIRTUAL_REF, 'forced') # # record the type JIT_VIRTUAL_REF explicitly in the rtyper, too if hasattr(self.warmrunnerdesc, 'rtyper'): # <-- for tests self.warmrunnerdesc.rtyper.set_type_for_typeptr( self.jit_virtual_ref_vtable, self.JIT_VIRTUAL_REF)
def wrap(cpu, value, in_const_box=False): if isinstance(lltype.typeOf(value), lltype.Ptr): if lltype.typeOf(value).TO._gckind == 'gc': value = lltype.cast_opaque_ptr(llmemory.GCREF, value) if in_const_box: return history.ConstPtr(value) else: return history.BoxPtr(value) else: adr = llmemory.cast_ptr_to_adr(value) value = heaptracker.adr2int(adr) # fall through to the end of the function elif (isinstance(value, float) or longlong.is_longlong(lltype.typeOf(value))): if isinstance(value, float): value = longlong.getfloatstorage(value) else: value = rffi.cast(lltype.SignedLongLong, value) if in_const_box: return history.ConstFloat(value) else: return history.BoxFloat(value) elif isinstance(value, str) or isinstance(value, unicode): assert len(value) == 1 # must be a character value = ord(value) elif lltype.typeOf(value) is lltype.SingleFloat: value = longlong.singlefloat2int(value) else: value = intmask(value) if in_const_box: return history.ConstInt(value) else: return history.BoxInt(value)
def handle_call_assembler(self, op): descrs = self.gc_ll_descr.getframedescrs(self.cpu) loop_token = op.getdescr() assert isinstance(loop_token, history.JitCellToken) jfi = loop_token.compiled_loop_token.frame_info llfi = heaptracker.adr2int(llmemory.cast_ptr_to_adr(jfi)) frame = self.gen_malloc_frame(llfi) self.emit_setfield(frame, history.ConstInt(llfi), descr=descrs.jf_frame_info) arglist = op.getarglist() index_list = loop_token.compiled_loop_token._ll_initial_locs for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) assert self.cpu.JITFRAME_FIXED_SIZE & 1 == 0 _, itemsize, _ = self.cpu.unpack_arraydescr_size(descr) array_offset = index_list[i] # index, already measured in bytes # emit GC_STORE _, basesize, _ = unpack_arraydescr(descr) offset = basesize + array_offset args = [frame, ConstInt(offset), arg, ConstInt(itemsize)] self.emit_op(ResOperation(rop.GC_STORE, args)) descr = op.getdescr() assert isinstance(descr, JitCellToken) jd = descr.outermost_jitdriver_sd args = [frame] if jd and jd.index_of_virtualizable >= 0: args = [frame, arglist[jd.index_of_virtualizable]] else: args = [frame] call_asm = ResOperation(op.getopnum(), args, descr=op.getdescr()) self.replace_op_with(self.get_box_replacement(op), call_asm) self.emit_op(call_asm)
def handle_call_assembler(self, op): descrs = self.gc_ll_descr.getframedescrs(self.cpu) loop_token = op.getdescr() assert isinstance(loop_token, history.JitCellToken) jfi = loop_token.compiled_loop_token.frame_info llfi = heaptracker.adr2int(llmemory.cast_ptr_to_adr(jfi)) size_box = history.BoxInt() frame = history.BoxPtr() self.gen_malloc_frame(llfi, frame, size_box) op2 = ResOperation(rop.SETFIELD_GC, [frame, history.ConstInt(llfi)], None, descr=descrs.jf_frame_info) self.newops.append(op2) arglist = op.getarglist() index_list = loop_token.compiled_loop_token._ll_initial_locs for i, arg in enumerate(arglist): descr = self.cpu.getarraydescr_for_frame(arg.type) assert self.cpu.JITFRAME_FIXED_SIZE & 1 == 0 _, itemsize, _ = self.cpu.unpack_arraydescr_size(descr) index = index_list[i] // itemsize # index is in bytes self.newops.append( ResOperation(rop.SETARRAYITEM_GC, [frame, ConstInt(index), arg], None, descr)) descr = op.getdescr() assert isinstance(descr, JitCellToken) jd = descr.outermost_jitdriver_sd args = [frame] if jd and jd.index_of_virtualizable >= 0: args = [frame, arglist[jd.index_of_virtualizable]] else: args = [frame] self.newops.append( ResOperation(rop.CALL_ASSEMBLER, args, op.result, op.getdescr()))
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 = jitdriver_sd.propagate_exc_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, 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) # # record the target of a temporary callback to the interpreter jl.tmp_callback(jitcell_token) # nb_red_args = jitdriver_sd.num_red_args assert len(redargtypes) == nb_red_args inputargs = [] for kind in redargtypes: if kind == history.INT: box = InputArgInt() elif kind == history.REF: box = InputArgRef() elif kind == history.FLOAT: box = InputArgFloat() else: raise AssertionError inputargs.append(box) k = jitdriver_sd.portal_runner_adr funcbox = history.ConstInt(adr2int(k)) callargs = [funcbox] + greenboxes + inputargs # jd = jitdriver_sd opnum = OpHelpers.call_for_descr(jd.portal_calldescr) call_op = ResOperation(opnum, callargs, descr=jd.portal_calldescr) if call_op.type != 'v' is not None: finishargs = [call_op] else: finishargs = [] # faildescr = jitdriver_sd.propagate_exc_descr operations = [ call_op, ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=faildescr), ResOperation(rop.FINISH, finishargs, 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
class MyMIFrame: jitcode = JitCode("test") jitcode.setup( "\xFF" # illegal instruction "\x00\x00\x01\x02" # int_add/ii>i "\x01\x02", # int_return/i [], num_regs_i=3, num_regs_r=0, num_regs_f=0) jitcode.jitdriver_sd = "foo" # not none pc = 1 registers_i = [resoperation.InputArgInt(40), history.ConstInt(2), None]
class MyMIFrame: jitcode = JitCode("test") jitcode.setup( "\xFF" # illegal instruction "\x00\x00\x01\x02" # int_add/ii>i "\x01\x02", # int_return/i [], num_regs_i=3, num_regs_r=0, num_regs_f=0) jitcode.is_portal = True pc = 1 registers_i = [history.BoxInt(40), history.ConstInt(2), None]
def wrap(cpu, value, in_const_box=False): if isinstance(lltype.typeOf(value), lltype.Ptr): if lltype.typeOf(value).TO._gckind == 'gc': value = lltype.cast_opaque_ptr(llmemory.GCREF, value) if in_const_box: return history.ConstPtr(value) else: res = history.RefFrontendOp(0) res.setref_base(value) return res else: value = ptr2int(value) # fall through to the end of the function elif (isinstance(value, float) or longlong.is_longlong(lltype.typeOf(value))): if isinstance(value, float): value = longlong.getfloatstorage(value) else: value = rffi.cast(lltype.SignedLongLong, value) if in_const_box: return history.ConstFloat(value) else: res = history.FloatFrontendOp(0) res.setfloatstorage(value) return res elif isinstance(value, str) or isinstance(value, unicode): assert len(value) == 1 # must be a character value = ord(value) elif lltype.typeOf(value) is lltype.SingleFloat: value = longlong.singlefloat2int(value) else: value = intmask(value) if in_const_box: return history.ConstInt(value) else: res = history.IntFrontendOp(0) res.setint(value) return res
def get_exception_box(self, etype): return history.ConstInt(etype)
def cls_of_box(self, box): PTR = lltype.Ptr(rclass.OBJECT) obj = lltype.cast_opaque_ptr(PTR, box.getref_base()) cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(heaptracker.adr2int(cls))
def cls_of_box(self, box): obj = box.getref(lltype.Ptr(rclass.OBJECT)) cls = llmemory.cast_ptr_to_adr(obj.typeptr) return history.ConstInt(heaptracker.adr2int(cls))