Esempio n. 1
0
 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)
Esempio n. 2
0
 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)
Esempio n. 3
0
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)
Esempio n. 4
0
    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)
Esempio n. 5
0
 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()))
Esempio n. 6
0
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
Esempio n. 7
0
File: compile.py Progetto: Mu-L/pypy
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
Esempio n. 8
0
 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]
Esempio n. 9
0
 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]
Esempio n. 10
0
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
Esempio n. 11
0
 def get_exception_box(self, etype):
     return history.ConstInt(etype)
Esempio n. 12
0
 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))
Esempio n. 13
0
 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))