Пример #1
0
    def gct_fv_gc_coalloc(self, hop, coallocator, flags, TYPE, *args):
        if self.coalloc_clear_ptr is None:
            return self.gct_fv_gc_malloc(
                    hop, flags, TYPE, *args)
        op = hop.spaceop
        flavor = flags['flavor']
        assert not flags.get("nocollect", False)

        PTRTYPE = op.result.concretetype
        assert PTRTYPE.TO == TYPE
        type_id = self.get_type_id(TYPE)

        c_type_id = rmodel.inputconst(lltype.Signed, type_id)
        info = self.layoutbuilder.type_info_list[type_id]
        c_size = rmodel.inputconst(lltype.Signed, info.fixedsize)
        has_finalizer = bool(self.finalizer_funcptr_for_type(TYPE))
        assert not has_finalizer

        v_coallocator = gen_cast(hop.llops, llmemory.Address, coallocator)

        if not op.opname.endswith('_varsize'):
            malloc_ptr = self.coalloc_clear_ptr
            args = [self.c_const_gc, v_coallocator, c_type_id, c_size]
        else:
            v_length = op.args[-1]
            c_ofstolength = rmodel.inputconst(lltype.Signed, info.ofstolength)
            c_varitemsize = rmodel.inputconst(lltype.Signed, info.varitemsize)
            malloc_ptr = self.coalloc_varsize_clear_ptr
            args = [self.c_const_gc, v_coallocator, c_type_id, v_length, c_size,
                    c_varitemsize, c_ofstolength]
        livevars = self.push_roots(hop)
        v_result = hop.genop("direct_call", [malloc_ptr] + args,
                             resulttype=llmemory.GCREF)
        self.pop_roots(hop, livevars)
        return v_result
Пример #2
0
 def pop_roots(self, hop, livevars):
     if not livevars:
         return
     # mark the values as gc roots
     for var in livevars:
         v_adr = gen_cast(hop.llops, llmemory.Address, var)
         v_newaddr = hop.genop("direct_call", [c_asm_gcroot, v_adr], resulttype=llmemory.Address)
         hop.genop("gc_reload_possibly_moved", [v_newaddr, var])
Пример #3
0
 def specialize_call(self, hop):
     from pypy.rpython.rbuiltin import gen_cast
     hop.exception_cannot_occur()
     s_RESTYPE = hop.args_s[0]
     assert s_RESTYPE.is_constant()
     RESTYPE = s_RESTYPE.const
     v_arg = hop.inputarg(hop.args_r[1], arg=1)
     TYPE1 = v_arg.concretetype
     return gen_cast(hop.llops, RESTYPE, v_arg)
Пример #4
0
 def pop_roots(self, hop, livevars):
     if not livevars:
         return
     # mark the values as gc roots
     for var in livevars:
         v_adr = gen_cast(hop.llops, llmemory.Address, var)
         v_newaddr = hop.genop("direct_call", [c_asm_gcroot, v_adr],
                               resulttype=llmemory.Address)
         hop.genop("gc_reload_possibly_moved", [v_newaddr, var])
Пример #5
0
 def push_roots(self, hop, keep_current_args=False):
     livevars = self.get_livevars_for_roots(hop, keep_current_args)
     self.num_pushs += len(livevars)
     if not livevars:
         return []
     for k, var in enumerate(livevars):
         c_k = rmodel.inputconst(lltype.Signed, k)
         v_adr = gen_cast(hop.llops, llmemory.Address, var)
         hop.genop("llvm_store_gcroot", [c_k, v_adr])
     return livevars
Пример #6
0
 def cast_result(self, var):
     v_result = self.spaceop.result
     resulttype = getattr(v_result, 'concretetype', PyObjPtr)
     curtype = getattr(var, 'concretetype', PyObjPtr)
     if curtype == resulttype:
         self.genop('same_as', [var], resultvar=v_result)
     else:
         v_new = gen_cast(self.llops, resulttype, var)
         assert v_new != var
         self.llops[-1].result = v_result
Пример #7
0
 def push_roots(self, hop):
     if self.push_root_ptr is None:
         return
     livevars = [var for var in self.livevars if not var_ispyobj(var)]
     c_len = rmodel.inputconst(lltype.Signed, len(livevars) )
     base_addr = hop.genop("direct_call", [self.incr_stack_ptr, c_len ],
                           resulttype=llmemory.Address)
     for k,var in enumerate(livevars):
         c_k = rmodel.inputconst(lltype.Signed, k)
         v_adr = gen_cast(hop.llops, llmemory.Address, var)
         hop.genop("direct_call", [self.save_addr_ptr, base_addr, c_k, v_adr])
Пример #8
0
    def pop_alive_nopyobj(self, var, llops):
        PTRTYPE = var.concretetype
        v_adr = gen_cast(llops, llmemory.Address, var)

        dealloc_fptr = self.dynamic_deallocation_funcptr_for_type(PTRTYPE.TO)
        if dealloc_fptr is self.no_pointer_dealloc_ptr.value:
            # simple case
            llops.genop("direct_call", [self.decref_simple_ptr, v_adr])
        else:
            cdealloc_fptr = rmodel.inputconst(lltype.typeOf(dealloc_fptr), dealloc_fptr)
            llops.genop("direct_call", [self.decref_ptr, v_adr, cdealloc_fptr])
Пример #9
0
    def _generate_save_block(self, varsforcall, v_unwind_exception, saver):
        conc_types = tuple([v.concretetype for v in varsforcall])
        if conc_types in self.curr_graph_save_blocks:
            return self.curr_graph_save_blocks[conc_types]
        rtyper = self.translator.rtyper
        edata = rtyper.getexceptiondata()
        etype = edata.lltype_of_exception_type
        evalue = edata.lltype_of_exception_value
        inputargs = [copyvar(v) for v in varsforcall]
        v_unwind_exception = copyvar(v_unwind_exception)

        save_state_block = model.Block(inputargs + [v_unwind_exception])
        saveops = LowLevelOpList()
        
        v_exc = gen_cast(saveops, self.unwind_exception_type, v_unwind_exception)
        
        realvarsforcall = [v_exc]
        for v in inputargs:
            realvarsforcall.append(gen_cast(saveops, storage_type(v.concretetype), v))
        
        saveops.genop('direct_call',
                      [model.Constant(saver, lltype.typeOf(saver))] + realvarsforcall,
                      resulttype=lltype.Void)
        save_state_block.operations = saveops

        type_repr = rclass.get_type_repr(rtyper)
        c_unwindexception = model.Constant(
            type_repr.convert_const(code.UnwindException), etype)
        if not hasattr(self.curr_graph.exceptblock.inputargs[0], 'concretetype'):
            self.curr_graph.exceptblock.inputargs[0].concretetype = etype
        if not hasattr(self.curr_graph.exceptblock.inputargs[1], 'concretetype'):
            self.curr_graph.exceptblock.inputargs[1].concretetype = evalue
        save_state_block.closeblock(model.Link(
            [c_unwindexception, v_unwind_exception], 
            self.curr_graph.exceptblock))
        self.translator.rtyper._convert_link(
            save_state_block, save_state_block.exits[0])
        if SAVE_STATISTICS:
            self.stats.saveops += len(save_state_block.operations)
        self.curr_graph_save_blocks[conc_types] = save_state_block
        return save_state_block
Пример #10
0
    def pop_alive_nopyobj(self, var, llops):
        PTRTYPE = var.concretetype
        v_adr = gen_cast(llops, llmemory.Address, var)

        dealloc_fptr = self.dynamic_deallocation_funcptr_for_type(PTRTYPE.TO)
        if dealloc_fptr is self.no_pointer_dealloc_ptr.value:
            # simple case
            llops.genop("direct_call", [self.decref_simple_ptr, v_adr])
        else:
            cdealloc_fptr = rmodel.inputconst(
                lltype.typeOf(dealloc_fptr), dealloc_fptr)
            llops.genop("direct_call", [self.decref_ptr, v_adr, cdealloc_fptr])
Пример #11
0
 def pop_roots(self, hop, livevars):
     if not livevars:
         return
     # mark the values as gc roots
     for var in livevars:
         if 0:
             # uses direct support in genc - more compact code,
             # but it's probably not changing anything
             hop.genop("asm_gcroot", [var])
         else:
             v_adr = gen_cast(hop.llops, llmemory.Address, var)
             v_newaddr = hop.genop("direct_call", [c_asm_gcroot, v_adr],
                                   resulttype=llmemory.Address)
             hop.genop("gc_reload_possibly_moved", [v_newaddr, var])
Пример #12
0
 def insert_return_conversion(self, link, targettype, retvar):
     llops = LowLevelOpList()
     newvar = gen_cast(llops, targettype, retvar)
     convertblock = unsimplify.insert_empty_block(None, link, llops)
     # begin ouch!
     for index, linkvar in enumerate(convertblock.exits[0].args):
         # does this var come from retval ?
         try:
             index1 = convertblock.inputargs.index(linkvar)
         except ValueError:   # e.g. linkvar is a Constant
             continue
         if link.args[index1] is retvar:
             # yes
             convertblock.exits[0].args[index] = newvar
Пример #13
0
 def pop_roots(self, hop, livevars):
     if not livevars:
         return
     # mark the values as gc roots
     for var in livevars:
         if 0:
             # uses direct support in genc - more compact code,
             # but it's probably not changing anything
             hop.genop("asm_gcroot", [var])
         else:
             v_adr = gen_cast(hop.llops, llmemory.Address, var)
             v_newaddr = hop.genop("direct_call", [c_asm_gcroot, v_adr],
                                   resulttype=llmemory.Address)
             hop.genop("gc_reload_possibly_moved", [v_newaddr, var])
Пример #14
0
 def _make_cast_block(self, erased_types, exact_types):
     inputargs = [varoftype(t) for t in erased_types]
     cast_block = model.Block(inputargs)
     cast_block.operations = LowLevelOpList()
     output_args = []
     assert len(inputargs) == len([typ for typ in exact_types if typ != lltype.Void])
     i_arg = 0
     for typ in exact_types:
         if typ == lltype.Void:
             output_args.append(model.Constant(None, lltype.Void))
         else:
             arg = inputargs[i_arg]
             i_arg += 1
             output_args.append(gen_cast(cast_block.operations, typ, arg))
     assert i_arg == len(inputargs)
     return cast_block, output_args
Пример #15
0
 def push_roots(self, hop, keep_current_args=False):
     if self.incr_stack_ptr is None:
         return
     livevars = self.get_livevars_for_roots(hop, keep_current_args)
     self.num_pushs += len(livevars)
     if not livevars:
         return []
     c_len = rmodel.inputconst(lltype.Signed, len(livevars) )
     base_addr = hop.genop("direct_call", [self.incr_stack_ptr, c_len ],
                           resulttype=llmemory.Address)
     c_type = rmodel.inputconst(lltype.Void, llmemory.Address)
     for k,var in enumerate(livevars):
         c_k = rmodel.inputconst(lltype.Signed, k)
         v_adr = gen_cast(hop.llops, llmemory.Address, var)
         hop.genop("raw_store", [base_addr, c_type, c_k, v_adr])
     return livevars
Пример #16
0
 def push_roots(self, hop, keep_current_args=False):
     if self.incr_stack_ptr is None:
         return
     livevars = self.get_livevars_for_roots(hop, keep_current_args)
     self.num_pushs += len(livevars)
     if not livevars:
         return []
     c_len = rmodel.inputconst(lltype.Signed, len(livevars) )
     base_addr = hop.genop("direct_call", [self.incr_stack_ptr, c_len ],
                           resulttype=llmemory.Address)
     c_type = rmodel.inputconst(lltype.Void, llmemory.Address)
     for k,var in enumerate(livevars):
         c_k = rmodel.inputconst(lltype.Signed, k)
         v_adr = gen_cast(hop.llops, llmemory.Address, var)
         hop.genop("raw_store", [base_addr, c_type, c_k, v_adr])
     return livevars
Пример #17
0
    def _gct_resize_buffer_realloc(self, hop, v_newsize, grow=True):
        def intconst(c): return rmodel.inputconst(lltype.Signed, c)
        op = hop.spaceop
        flags = {'flavor':'gc', 'varsize': True}
        TYPE = op.args[0].concretetype.TO
        ARRAY = TYPE._flds[TYPE._arrayfld]
        offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld) + \
                           llmemory.ArrayLengthOffset(ARRAY)
        c_const_size = intconst(llmemory.sizeof(TYPE, 0))
        c_item_size = intconst(llmemory.sizeof(ARRAY.OF))

        c_lengthofs = intconst(offset_to_length)
        v_ptr = op.args[0]
        v_ptr = gen_cast(hop.llops, llmemory.GCREF, v_ptr)
        c_grow = rmodel.inputconst(lltype.Bool, grow)
        v_raw = self.perform_realloc(hop, v_ptr, v_newsize, c_const_size,
                                     c_item_size, c_lengthofs, c_grow)
        hop.cast_result(v_raw)
Пример #18
0
    def _gct_resize_buffer_realloc(self, hop, v_newsize, grow=True):
        def intconst(c):
            return rmodel.inputconst(lltype.Signed, c)

        op = hop.spaceop
        flags = {'flavor': 'gc', 'varsize': True}
        TYPE = op.args[0].concretetype.TO
        ARRAY = TYPE._flds[TYPE._arrayfld]
        offset_to_length = llmemory.FieldOffset(TYPE, TYPE._arrayfld) + \
                           llmemory.ArrayLengthOffset(ARRAY)
        c_const_size = intconst(llmemory.sizeof(TYPE, 0))
        c_item_size = intconst(llmemory.sizeof(ARRAY.OF))

        c_lengthofs = intconst(offset_to_length)
        v_ptr = op.args[0]
        v_ptr = gen_cast(hop.llops, llmemory.GCREF, v_ptr)
        c_grow = rmodel.inputconst(lltype.Bool, grow)
        v_raw = self.perform_realloc(hop, v_ptr, v_newsize, c_const_size,
                                     c_item_size, c_lengthofs, c_grow)
        hop.cast_result(v_raw)
Пример #19
0
    def _make_resume_retrieval_block(self, FRAME_TYPE, erased_types):
        retrieve_block = model.Block([varoftype(lltype.Signed)])
        retrieve_block.exitswitch = retrieve_block.inputargs[0]

        llops = LowLevelOpList()
        llops.genop("setfield",
                    [self.ll_global_state, self.c_restart_substate_name, self.c_minus_one])
        v_state_hdr = llops.genop("getfield",
                                  [self.ll_global_state, self.c_inst_top_name],
                                  resulttype=lltype.Ptr(STATE_HEADER))
        v_state = gen_cast(llops, lltype.Ptr(FRAME_TYPE), v_state_hdr)
        llops.genop("setfield",
                    [self.ll_global_state, self.c_inst_top_name, self.c_null_state])
        output_args = [retrieve_block.inputargs[0]]
        assert len(FRAME_TYPE._names[1:]) == len(erased_types)
        for fieldname, TYPE in zip(FRAME_TYPE._names[1:], erased_types):
            assert FRAME_TYPE._flds[fieldname] == TYPE
            output_args.append(llops.genop("getfield",
                                           [v_state, model.Constant(fieldname, lltype.Void)],
                                           resulttype=TYPE))
        retrieve_block.operations = llops
        return retrieve_block, output_args
Пример #20
0
    def saving_function_for_type(self, FRAME_TYPE):
        v_exception = varoftype(self.transformer.unwind_exception_type)
        v_restart = varoftype(lltype.Signed)
        
        save_block = model.Block([v_exception, v_restart])
        
        llops = LowLevelOpList()
        flags = {'flavor': 'gc'}
        if self.stackless_gc:
            flags['nocollect'] = True
        v_state = llops.genop('malloc',
                              [model.Constant(FRAME_TYPE, lltype.Void),
                               model.Constant(flags, lltype.Void)],
                              resulttype=lltype.Ptr(FRAME_TYPE))

        for fieldname in FRAME_TYPE._names[1:]: # skip the 'header' field
            v_arg = varoftype(FRAME_TYPE._flds[fieldname])
            save_block.inputargs.append(v_arg)
            llops.genop('setfield',
                        [v_state, model.Constant(fieldname, lltype.Void), v_arg],
                        resulttype=lltype.Void)

        v_header = gen_cast(llops, lltype.Ptr(STATE_HEADER), v_state)
        llops.genop('direct_call',
                    [self.transformer.add_frame_state_ptr, v_exception, v_header],
                    resulttype=lltype.Void)
        llops.genop("setfield",
                    [v_header, self.transformer.c_f_restart_name, v_restart],
                    resulttype=lltype.Void)

        save_state_graph = model.FunctionGraph('save_' + FRAME_TYPE._name, save_block,
                                               varoftype(lltype.Void))
        save_block.operations = llops
        save_block.closeblock(model.Link([v_header], save_state_graph.returnblock))

        FUNC_TYPE = lltype.FuncType([v.concretetype for v in save_block.inputargs],
                                    lltype.Void)
        return lltype.functionptr(FUNC_TYPE, save_state_graph.name,
                                  graph=save_state_graph)
Пример #21
0
    def gct_fv_gc_coalloc(self, hop, coallocator, flags, TYPE, *args):
        if self.coalloc_clear_ptr is None:
            return self.gct_fv_gc_malloc(hop, flags, TYPE, *args)
        op = hop.spaceop
        flavor = flags['flavor']
        assert not flags.get("nocollect", False)

        PTRTYPE = op.result.concretetype
        assert PTRTYPE.TO == TYPE
        type_id = self.get_type_id(TYPE)

        c_type_id = rmodel.inputconst(lltype.Signed, type_id)
        info = self.layoutbuilder.type_info_list[type_id]
        c_size = rmodel.inputconst(lltype.Signed, info.fixedsize)
        has_finalizer = bool(self.finalizer_funcptr_for_type(TYPE))
        assert not has_finalizer

        v_coallocator = gen_cast(hop.llops, llmemory.Address, coallocator)

        if not op.opname.endswith('_varsize'):
            malloc_ptr = self.coalloc_clear_ptr
            args = [self.c_const_gc, v_coallocator, c_type_id, c_size]
        else:
            v_length = op.args[-1]
            c_ofstolength = rmodel.inputconst(lltype.Signed, info.ofstolength)
            c_varitemsize = rmodel.inputconst(lltype.Signed, info.varitemsize)
            malloc_ptr = self.coalloc_varsize_clear_ptr
            args = [
                self.c_const_gc, v_coallocator, c_type_id, v_length, c_size,
                c_varitemsize, c_ofstolength
            ]
        livevars = self.push_roots(hop)
        v_result = hop.genop("direct_call", [malloc_ptr] + args,
                             resulttype=llmemory.GCREF)
        self.pop_roots(hop, livevars)
        return v_result
Пример #22
0
 def pop_alive_pyobj(self, var, llops):
     if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr:
         var = gen_cast(llops, PyObjPtr, var)
     llops.genop("gc_pop_alive_pyobj", [var])
Пример #23
0
 def push_alive_nopyobj(self, var, llops):
     v_adr = gen_cast(llops, llmemory.Address, var)
     llops.genop("direct_call", [self.increfptr, v_adr])
Пример #24
0
 def push_alive_nopyobj(self, var, llops):
     v_adr = gen_cast(llops, llmemory.Address, var)
     llops.genop("direct_call", [self.increfptr, v_adr])