Exemple #1
0
 def prepare_op_call_malloc_nursery_varsize(self, op, fcond):
     gc_ll_descr = self.cpu.gc_ll_descr
     if not hasattr(gc_ll_descr, 'max_size_of_young_obj'):
         raise Exception("unreachable code")
         # for boehm, this function should never be called
     arraydescr = op.getdescr()
     length_box = op.getarg(2)
     assert not isinstance(length_box,
                           Const)  # we cannot have a const here!
     # can only use spill_or_move_registers_before_call() as a hint if
     # we are sure that length_box stays alive and won't be freed now
     # (it should always be the case, see below, but better safe than sorry)
     if self.rm.stays_alive(length_box):
         self.rm.spill_or_move_registers_before_call([r.r0, r.r1])
     # the result will be in r0
     self.rm.force_allocate_reg(op, selected_reg=r.r0)
     # we need r1 as a temporary
     tmp_box = TempVar()
     self.rm.force_allocate_reg(tmp_box, selected_reg=r.r1)
     gcmap = self.get_gcmap([r.r0, r.r1])  # allocate the gcmap *before*
     self.rm.possibly_free_var(tmp_box)
     # length_box always survives: it's typically also present in the
     # next operation that will copy it inside the new array.  It's
     # fine to load it from the stack too, as long as it's != r0, r1.
     lengthloc = self.rm.loc(length_box)
     self.rm.possibly_free_var(length_box)
     #
     itemsize = op.getarg(1).getint()
     maxlength = (gc_ll_descr.max_size_of_young_obj - WORD * 2) / itemsize
     self.assembler.malloc_cond_varsize(
         op.getarg(0).getint(), gc_ll_descr.get_nursery_free_addr(),
         gc_ll_descr.get_nursery_top_addr(), lengthloc, itemsize, maxlength,
         gcmap, arraydescr)
Exemple #2
0
    def ensure_even_odd_pair(self,
                             origvar,
                             bindvar,
                             bind_first=True,
                             must_exist=True,
                             load_loc_odd=True,
                             move_regs=True):
        """ Allocates two registers that can be used by the instruction.
            origvar: is the original register holding the value
            bindvar: is the variable that will be bound
                     (= self.reg_bindings[bindvar] = new register)
            bind_first: the even register will be bound to bindvar,
                        if bind_first == False: the odd register will
                        be bound
        """
        self._check_type(origvar)
        prev_loc = self.loc(origvar, must_exist=must_exist)
        var2 = TempVar()
        if bindvar is None:
            bindvar = TempVar()
        if bind_first:
            loc, loc2 = self.force_allocate_reg_pair(bindvar, var2,
                                                     self.temp_boxes)
        else:
            loc, loc2 = self.force_allocate_reg_pair(var2, bindvar,
                                                     self.temp_boxes)
        if isinstance(bindvar, TempVar):
            self.temp_boxes.append(bindvar)

        self.temp_boxes.append(var2)
        assert loc.is_even() and loc2.is_odd()
        if move_regs and prev_loc is not loc2:
            if load_loc_odd:
                self.assembler.regalloc_mov(prev_loc, loc2)
            else:
                self.assembler.regalloc_mov(prev_loc, loc)
        return loc, loc2
Exemple #3
0
 def get_scratch_reg(self):
     box = TempVar()
     reg = self.force_allocate_reg(box, forbidden_vars=self.temp_boxes)
     self.temp_boxes.append(box)
     return reg