Example #1
0
 def _prepare_getfield(self, op):
     ofs, size, sign = unpack_fielddescr(op.getdescr())
     base_loc = self.ensure_reg(op.getarg(0))
     ofs_loc = self.ensure_reg_or_16bit_imm(ConstInt(ofs))
     self.free_op_vars()
     res = self.force_allocate_reg(op)
     return [base_loc, ofs_loc, res, imm(size), imm(sign)]
Example #2
0
    def gen_malloc_frame(self, frame_info):
        descrs = self.gc_ll_descr.getframedescrs(self.cpu)
        if self.gc_ll_descr.kind == 'boehm':
            ofs, size, sign = unpack_fielddescr(descrs.jfi_frame_depth)
            if sign:
                size = -size
            args = [ConstInt(frame_info), ConstInt(ofs), ConstInt(size)]
            size = ResOperation(rop.GC_LOAD_I, args)
            self.emit_op(size)
            frame = ResOperation(rop.NEW_ARRAY, [size],
                                 descr=descrs.arraydescr)
            self.handle_new_array(descrs.arraydescr, frame)
            return self.get_box_replacement(frame)
        else:
            # we read size in bytes here, not the length
            ofs, size, sign = unpack_fielddescr(descrs.jfi_frame_size)
            if sign:
                size = -size
            args = [ConstInt(frame_info), ConstInt(ofs), ConstInt(size)]
            size = ResOperation(rop.GC_LOAD_I, args)
            self.emit_op(size)
            frame = self.gen_malloc_nursery_varsize_frame(size)
            self.gen_initialize_tid(frame, descrs.arraydescr.tid)
            # we need to explicitely zero all the gc fields, because
            # of the unusal malloc pattern

            length = self.emit_getfield(ConstInt(frame_info),
                                        descr=descrs.jfi_frame_depth, raw=True)
            self.emit_setfield(frame, self.c_zero,
                               descr=descrs.jf_extra_stack_depth)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_savedata)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_force_descr)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_descr)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_guard_exc)
            self.emit_setfield(frame, self.c_null,
                               descr=descrs.jf_forward)
            self.gen_initialize_len(frame, length,
                                    descrs.arraydescr.lendescr)
            return self.get_box_replacement(frame)
Example #3
0
 def calculate_offset(self, cpu):
     descrs = cpu.gc_ll_descr.getframedescrs(cpu)
     offset, size, _ = unpack_fielddescr(descrs.arraydescr.lendescr)
     assert size == WORD
     return offset
Example #4
0
 def emit_setfield(self, ptr, value, descr):
     ofs, size, sign = unpack_fielddescr(descr)
     self.emit_gc_store_or_indexed(None, ptr, ConstInt(0), value, size, 1,
                                   ofs)
Example #5
0
 def emit_getfield(self, ptr, descr, type='i', raw=False):
     ofs, size, sign = unpack_fielddescr(descr)
     op = self.emit_gc_load_or_indexed(None, ptr, ConstInt(0), size, 1, ofs,
                                       sign)
     return op
Example #6
0
 def transform_to_gc_load(self, op):
     NOT_SIGNED = 0
     CINT_ZERO = ConstInt(0)
     opnum = op.getopnum()
     if rop.is_getarrayitem(opnum) or \
        opnum in (rop.GETARRAYITEM_RAW_I,
                  rop.GETARRAYITEM_RAW_F):
         self.handle_getarrayitem(op)
     elif opnum in (rop.SETARRAYITEM_GC, rop.SETARRAYITEM_RAW):
         self.handle_setarrayitem(op)
     elif opnum == rop.RAW_STORE:
         itemsize, ofs, _ = unpack_arraydescr(op.getdescr())
         ptr_box = op.getarg(0)
         index_box = op.getarg(1)
         value_box = op.getarg(2)
         self.emit_gc_store_or_indexed(op, ptr_box, index_box, value_box,
                                       itemsize, 1, ofs)
     elif opnum in (rop.RAW_LOAD_I, rop.RAW_LOAD_F):
         itemsize, ofs, sign = unpack_arraydescr(op.getdescr())
         ptr_box = op.getarg(0)
         index_box = op.getarg(1)
         self.emit_gc_load_or_indexed(op, ptr_box, index_box, itemsize, 1,
                                      ofs, sign)
     elif opnum in (rop.GETINTERIORFIELD_GC_I, rop.GETINTERIORFIELD_GC_R,
                    rop.GETINTERIORFIELD_GC_F):
         ofs, itemsize, fieldsize, sign = unpack_interiorfielddescr(
             op.getdescr())
         ptr_box = op.getarg(0)
         index_box = op.getarg(1)
         self.emit_gc_load_or_indexed(op, ptr_box, index_box, fieldsize,
                                      itemsize, ofs, sign)
     elif opnum in (rop.SETINTERIORFIELD_RAW, rop.SETINTERIORFIELD_GC):
         ofs, itemsize, fieldsize, sign = unpack_interiorfielddescr(
             op.getdescr())
         ptr_box = op.getarg(0)
         index_box = op.getarg(1)
         value_box = op.getarg(2)
         self.emit_gc_store_or_indexed(op, ptr_box, index_box, value_box,
                                       fieldsize, itemsize, ofs)
     elif opnum in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F, rop.GETFIELD_GC_R,
                    rop.GETFIELD_RAW_I, rop.GETFIELD_RAW_F,
                    rop.GETFIELD_RAW_R):
         ofs, itemsize, sign = unpack_fielddescr(op.getdescr())
         ptr_box = op.getarg(0)
         if op.getopnum() in (rop.GETFIELD_GC_F, rop.GETFIELD_GC_I,
                              rop.GETFIELD_GC_R):
             # See test_zero_ptr_field_before_getfield().  We hope there is
             # no getfield_gc in the middle of initialization code, but there
             # shouldn't be, given that a 'new' is already delayed by previous
             # optimization steps.  In practice it should immediately be
             # followed by a bunch of 'setfields', and the 'pending_zeros'
             # optimization we do here is meant for this case.
             self.emit_pending_zeros()
             self.emit_gc_load_or_indexed(op, ptr_box, ConstInt(0),
                                          itemsize, 1, ofs, sign)
             self.emit_op(op)
             return True
         self.emit_gc_load_or_indexed(op, ptr_box, ConstInt(0), itemsize, 1,
                                      ofs, sign)
     elif opnum in (rop.SETFIELD_GC, rop.SETFIELD_RAW):
         ofs, itemsize, sign = unpack_fielddescr(op.getdescr())
         ptr_box = op.getarg(0)
         value_box = op.getarg(1)
         self.emit_gc_store_or_indexed(op, ptr_box, ConstInt(0), value_box,
                                       itemsize, 1, ofs)
     elif opnum == rop.ARRAYLEN_GC:
         descr = op.getdescr()
         assert isinstance(descr, ArrayDescr)
         ofs = descr.lendescr.offset
         self.emit_gc_load_or_indexed(op, op.getarg(0), ConstInt(0), WORD,
                                      1, ofs, NOT_SIGNED)
     elif opnum == rop.STRLEN:
         basesize, itemsize, ofs_length = get_array_token(
             rstr.STR, self.cpu.translate_support_code)
         self.emit_gc_load_or_indexed(op, op.getarg(0), ConstInt(0), WORD,
                                      1, ofs_length, NOT_SIGNED)
     elif opnum == rop.UNICODELEN:
         basesize, itemsize, ofs_length = get_array_token(
             rstr.UNICODE, self.cpu.translate_support_code)
         self.emit_gc_load_or_indexed(op, op.getarg(0), ConstInt(0), WORD,
                                      1, ofs_length, NOT_SIGNED)
     elif opnum == rop.STRHASH:
         offset, size = get_field_token(rstr.STR, 'hash',
                                        self.cpu.translate_support_code)
         assert size == WORD
         self.emit_gc_load_or_indexed(op,
                                      op.getarg(0),
                                      ConstInt(0),
                                      WORD,
                                      1,
                                      offset,
                                      sign=True)
     elif opnum == rop.UNICODEHASH:
         offset, size = get_field_token(rstr.UNICODE, 'hash',
                                        self.cpu.translate_support_code)
         assert size == WORD
         self.emit_gc_load_or_indexed(op,
                                      op.getarg(0),
                                      ConstInt(0),
                                      WORD,
                                      1,
                                      offset,
                                      sign=True)
     elif opnum == rop.STRGETITEM:
         basesize, itemsize, ofs_length = get_array_token(
             rstr.STR, self.cpu.translate_support_code)
         assert itemsize == 1
         basesize -= 1  # for the extra null character
         self.emit_gc_load_or_indexed(op, op.getarg(0), op.getarg(1),
                                      itemsize, itemsize, basesize,
                                      NOT_SIGNED)
     elif opnum == rop.UNICODEGETITEM:
         basesize, itemsize, ofs_length = get_array_token(
             rstr.UNICODE, self.cpu.translate_support_code)
         self.emit_gc_load_or_indexed(op, op.getarg(0), op.getarg(1),
                                      itemsize, itemsize, basesize,
                                      NOT_SIGNED)
     elif opnum == rop.STRSETITEM:
         basesize, itemsize, ofs_length = get_array_token(
             rstr.STR, self.cpu.translate_support_code)
         assert itemsize == 1
         basesize -= 1  # for the extra null character
         self.emit_gc_store_or_indexed(op, op.getarg(0), op.getarg(1),
                                       op.getarg(2), itemsize, itemsize,
                                       basesize)
     elif opnum == rop.UNICODESETITEM:
         basesize, itemsize, ofs_length = get_array_token(
             rstr.UNICODE, self.cpu.translate_support_code)
         self.emit_gc_store_or_indexed(op, op.getarg(0), op.getarg(1),
                                       op.getarg(2), itemsize, itemsize,
                                       basesize)
     return False
Example #7
0
 def emit_setfield(self, ptr, value, descr):
     ofs, size, sign = unpack_fielddescr(descr)
     self.emit_gc_store_or_indexed(None, ptr, ConstInt(0), value,
                                   size, 1, ofs)
Example #8
0
 def emit_getfield(self, ptr, descr, type='i', raw=False):
     ofs, size, sign = unpack_fielddescr(descr)
     op = self.emit_gc_load_or_indexed(None, ptr, ConstInt(0), size, 1, ofs, sign)
     return op
Example #9
0
 def transform_to_gc_load(self, op):
     NOT_SIGNED = 0
     CINT_ZERO = ConstInt(0)
     opnum = op.getopnum()
     #if opnum == rop.CALL_MALLOC_NURSERY_VARSIZE:
     #    v_length = op.getarg(2)
     #    scale = op.getarg(1).getint()
     #    if scale not in self.cpu.load_supported_factors:
     #        scale, offset, v_length = \
     #                self._emit_mul_if_factor_offset_not_supported(v_length, scale, 0)
     #        op.setarg(1, ConstInt(scale))
     #        op.setarg(2, v_length)
     if rop.is_getarrayitem(opnum) or \
        opnum in (rop.GETARRAYITEM_RAW_I,
                  rop.GETARRAYITEM_RAW_F):
         self.handle_getarrayitem(op)
     elif opnum in (rop.SETARRAYITEM_GC, rop.SETARRAYITEM_RAW):
         self.handle_setarrayitem(op)
     elif opnum == rop.RAW_STORE:
         itemsize, ofs, _ = unpack_arraydescr(op.getdescr())
         ptr_box = op.getarg(0)
         index_box = op.getarg(1)
         value_box = op.getarg(2)
         self.emit_gc_store_or_indexed(op, ptr_box, index_box, value_box, itemsize, 1, ofs)
     elif opnum in (rop.RAW_LOAD_I, rop.RAW_LOAD_F):
         itemsize, ofs, sign = unpack_arraydescr(op.getdescr())
         ptr_box = op.getarg(0)
         index_box = op.getarg(1)
         self.emit_gc_load_or_indexed(op, ptr_box, index_box, itemsize, 1, ofs, sign)
     elif opnum in (rop.GETINTERIORFIELD_GC_I, rop.GETINTERIORFIELD_GC_R,
                    rop.GETINTERIORFIELD_GC_F):
         ofs, itemsize, fieldsize, sign = unpack_interiorfielddescr(op.getdescr())
         ptr_box = op.getarg(0)
         index_box = op.getarg(1)
         self.emit_gc_load_or_indexed(op, ptr_box, index_box, fieldsize, itemsize, ofs, sign)
     elif opnum in (rop.SETINTERIORFIELD_RAW, rop.SETINTERIORFIELD_GC):
         ofs, itemsize, fieldsize, sign = unpack_interiorfielddescr(op.getdescr())
         ptr_box = op.getarg(0)
         index_box = op.getarg(1)
         value_box = op.getarg(2)
         self.emit_gc_store_or_indexed(op, ptr_box, index_box, value_box,
                                       fieldsize, itemsize, ofs)
     elif opnum in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F, rop.GETFIELD_GC_R,
                    rop.GETFIELD_RAW_I, rop.GETFIELD_RAW_F, rop.GETFIELD_RAW_R):
         ofs, itemsize, sign = unpack_fielddescr(op.getdescr())
         ptr_box = op.getarg(0)
         if op.getopnum() in (rop.GETFIELD_GC_F, rop.GETFIELD_GC_I, rop.GETFIELD_GC_R):
             # See test_zero_ptr_field_before_getfield().  We hope there is
             # no getfield_gc in the middle of initialization code, but there
             # shouldn't be, given that a 'new' is already delayed by previous
             # optimization steps.  In practice it should immediately be
             # followed by a bunch of 'setfields', and the 'pending_zeros'
             # optimization we do here is meant for this case.
             self.emit_pending_zeros()
             self.emit_gc_load_or_indexed(op, ptr_box, ConstInt(0), itemsize, 1, ofs, sign)
             self.emit_op(op)
             return True
         self.emit_gc_load_or_indexed(op, ptr_box, ConstInt(0), itemsize, 1, ofs, sign)
     elif opnum in (rop.SETFIELD_GC, rop.SETFIELD_RAW):
         ofs, itemsize, sign = unpack_fielddescr(op.getdescr())
         ptr_box = op.getarg(0)
         value_box = op.getarg(1)
         self.emit_gc_store_or_indexed(op, ptr_box, ConstInt(0), value_box, itemsize, 1, ofs)
     elif opnum == rop.ARRAYLEN_GC:
         descr = op.getdescr()
         assert isinstance(descr, ArrayDescr)
         ofs = descr.lendescr.offset
         self.emit_gc_load_or_indexed(op, op.getarg(0), ConstInt(0),
                                      WORD, 1, ofs, NOT_SIGNED)
     elif opnum == rop.STRLEN:
         basesize, itemsize, ofs_length = get_array_token(rstr.STR,
                                              self.cpu.translate_support_code)
         self.emit_gc_load_or_indexed(op, op.getarg(0), ConstInt(0),
                                      WORD, 1, ofs_length, NOT_SIGNED)
     elif opnum == rop.UNICODELEN:
         basesize, itemsize, ofs_length = get_array_token(rstr.UNICODE,
                                              self.cpu.translate_support_code)
         self.emit_gc_load_or_indexed(op, op.getarg(0), ConstInt(0),
                                      WORD, 1, ofs_length, NOT_SIGNED)
     elif opnum == rop.STRGETITEM:
         basesize, itemsize, ofs_length = get_array_token(rstr.STR,
                                              self.cpu.translate_support_code)
         assert itemsize == 1
         self.emit_gc_load_or_indexed(op, op.getarg(0), op.getarg(1),
                                      itemsize, itemsize, basesize, NOT_SIGNED)
     elif opnum == rop.UNICODEGETITEM:
         basesize, itemsize, ofs_length = get_array_token(rstr.UNICODE,
                                              self.cpu.translate_support_code)
         self.emit_gc_load_or_indexed(op, op.getarg(0), op.getarg(1),
                                      itemsize, itemsize, basesize, NOT_SIGNED)
     elif opnum == rop.STRSETITEM:
         basesize, itemsize, ofs_length = get_array_token(rstr.STR,
                                              self.cpu.translate_support_code)
         assert itemsize == 1
         self.emit_gc_store_or_indexed(op, op.getarg(0), op.getarg(1), op.getarg(2),
                                      itemsize, itemsize, basesize)
     elif opnum == rop.UNICODESETITEM:
         basesize, itemsize, ofs_length = get_array_token(rstr.UNICODE,
                                              self.cpu.translate_support_code)
         self.emit_gc_store_or_indexed(op, op.getarg(0), op.getarg(1), op.getarg(2),
                                      itemsize, itemsize, basesize)
     return False
Example #10
0
 def calculate_offset(self, cpu):
     descrs = cpu.gc_ll_descr.getframedescrs(cpu)
     offset, size, _ = unpack_fielddescr(descrs.arraydescr.lendescr)
     assert size == WORD
     return offset
Example #11
0
 def prepare_setfield_gc(self, op):
     ofs, size, _ = unpack_fielddescr(op.getdescr())
     base_loc = self.ensure_reg(op.getarg(0))
     value_loc = self.ensure_reg(op.getarg(1))
     ofs_loc = self.ensure_reg_or_16bit_imm(ConstInt(ofs))
     return [value_loc, base_loc, ofs_loc, imm(size)]