def test_arrayitems(self): TP = lltype.GcArray(lltype.Signed) ofs = symbolic.get_field_token(TP, 'length', False)[0] itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref', descr) resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 10 self.execute_operation(rop.SETARRAYITEM_GC, [res, ConstInt(2), BoxInt(38)], 'void', descr) assert resbuf[itemsofs / WORD + 2] == 38 self.execute_operation(rop.SETARRAYITEM_GC, [res, BoxInt(3), BoxInt(42)], 'void', descr) assert resbuf[itemsofs / WORD + 3] == 42 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, ConstInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res.constbox(), BoxInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation( rop.GETARRAYITEM_GC, [res.constbox(), ConstInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, BoxInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, BoxInt(3)], 'int', descr) assert r.value == 42
def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): assert type(opts) is not bool self.opts = opts from rpython.jit.backend.llsupport.gc import get_ll_description AbstractCPU.__init__(self) self.rtyper = rtyper self.stats = stats self.translate_support_code = translate_support_code if translate_support_code and rtyper is not None: translator = rtyper.annotator.translator self.remove_gctypeptr = translator.config.translation.gcremovetypeptr else: translator = None self.gc_ll_descr = get_ll_description(gcdescr, translator, rtyper) # support_guard_gc_type indicates if a gc type of an object can be read. # In some states (boehm or x86 untranslated) the type is not known just yet, # because there are cases where it is not guarded. The precise place where it's not # is while inlining short preamble. self.supports_guard_gc_type = self.gc_ll_descr.supports_guard_gc_type if translator and translator.config.translation.gcremovetypeptr: self.vtable_offset = None else: self.vtable_offset, _ = symbolic.get_field_token( rclass.OBJECT, 'typeptr', translate_support_code) self.subclassrange_min_offset, _ = symbolic.get_field_token( rclass.OBJECT_VTABLE, 'subclassrange_min', translate_support_code) if translate_support_code: self._setup_exception_handling_translated() else: self._setup_exception_handling_untranslated() self.asmmemmgr = asmmemmgr.AsmMemoryManager() if self.HAS_CODEMAP: self.codemap = codemap.CodemapStorage() self._setup_frame_realloc(translate_support_code) ad = self.gc_ll_descr.getframedescrs(self).arraydescr self.signedarraydescr = ad # the same as normal JITFRAME, however with an array of pointers self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, FLAG_POINTER) if WORD == 4: self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize * 2, ad.lendescr, FLAG_FLOAT) else: self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, FLAG_FLOAT) self.setup() self._debug_tls_errno_container = lltype.malloc(rffi.CArray( lltype.Signed), 7, flavor='raw', zero=True, track_allocation=False) self._debug_tls_errno_container[1] = 1234 # dummy thread ident
def __init__(self, rtyper, stats, opts, translate_support_code=False, gcdescr=None): assert type(opts) is not bool self.opts = opts from rpython.jit.backend.llsupport.gc import get_ll_description AbstractCPU.__init__(self) self.rtyper = rtyper self.stats = stats self.translate_support_code = translate_support_code if translate_support_code and rtyper is not None: translator = rtyper.annotator.translator self.remove_gctypeptr = translator.config.translation.gcremovetypeptr else: translator = None self.gc_ll_descr = get_ll_description(gcdescr, translator, rtyper) # support_guard_gc_type indicates if a gc type of an object can be read. # In some states (boehm or x86 untranslated) the type is not known just yet, # because there are cases where it is not guarded. The precise place where it's not # is while inlining short preamble. self.supports_guard_gc_type = self.gc_ll_descr.supports_guard_gc_type if translator and translator.config.translation.gcremovetypeptr: self.vtable_offset = None else: self.vtable_offset, _ = symbolic.get_field_token(rclass.OBJECT, 'typeptr', translate_support_code) self.subclassrange_min_offset, _ = symbolic.get_field_token( rclass.OBJECT_VTABLE, 'subclassrange_min', translate_support_code) if translate_support_code: self._setup_exception_handling_translated() else: self._setup_exception_handling_untranslated() self.asmmemmgr = asmmemmgr.AsmMemoryManager() if self.HAS_CODEMAP: self.codemap = codemap.CodemapStorage() self._setup_frame_realloc(translate_support_code) ad = self.gc_ll_descr.getframedescrs(self).arraydescr self.signedarraydescr = ad # the same as normal JITFRAME, however with an array of pointers self.refarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, FLAG_POINTER) if WORD == 4: self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize * 2, ad.lendescr, FLAG_FLOAT) else: self.floatarraydescr = ArrayDescr(ad.basesize, ad.itemsize, ad.lendescr, FLAG_FLOAT) self.setup() self._debug_errno_container = lltype.malloc( rffi.CArray(lltype.Signed), 7, flavor='raw', zero=True, track_allocation=False)
def test_stringitems(self): from rpython.rtyper.lltypesystem.rstr import STR ofs = symbolic.get_field_token(STR, 'chars', False)[0] ofs_items = symbolic.get_field_token(STR.chars, 'items', False)[0] res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ref') self.execute_operation(rop.STRSETITEM, [InputArgRef(res), ConstInt(2), ConstInt(ord('d'))], 'void') resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs + ofs_items + 2] == 'd' self.execute_operation(rop.STRSETITEM, [InputArgRef(res), InputArgInt(2), ConstInt(ord('z'))], 'void') assert resbuf[ofs + ofs_items + 2] == 'z' r = self.execute_operation(rop.STRGETITEM, [InputArgRef(res), InputArgInt(2)], 'int') assert r == ord('z')
def test_stringitems(self): from rpython.rtyper.lltypesystem.rstr import STR ofs = symbolic.get_field_token(STR, 'chars', False)[0] ofs_items = symbolic.get_field_token(STR.chars, 'items', False)[0] res = self.execute_operation(rop.NEWSTR, [ConstInt(10)], 'ref') self.execute_operation(rop.STRSETITEM, [res, ConstInt(2), ConstInt(ord('d'))], 'void') resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs + ofs_items + 2] == 'd' self.execute_operation(rop.STRSETITEM, [res, BoxInt(2), ConstInt(ord('z'))], 'void') assert resbuf[ofs + ofs_items + 2] == 'z' r = self.execute_operation(rop.STRGETITEM, [res, BoxInt(2)], 'int') assert r.value == ord('z')
def test_allocations(self): py.test.skip("rewrite or kill") from rpython.rtyper.lltypesystem import rstr allocs = [None] all = [] orig_new = self.cpu.gc_ll_descr.funcptr_for_new def f(size): allocs.insert(0, size) return orig_new(size) self.cpu.assembler.setup_once() self.cpu.gc_ll_descr.funcptr_for_new = f ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 7 # ------------------------------------------------------------ res = self.execute_operation(rop.NEWSTR, [InputArgInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 7 # ------------------------------------------------------------ TP = lltype.GcArray(lltype.Signed) ofs = symbolic.get_field_token(TP, 'length', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref', descr) assert allocs[0] == 10 * WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 10 # ------------------------------------------------------------ res = self.execute_operation(rop.NEW_ARRAY, [InputArgInt(10)], 'ref', descr) assert allocs[0] == 10 * WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs / WORD] == 10
def test_allocations(self): py.test.skip("rewrite or kill") from rpython.rtyper.lltypesystem import rstr allocs = [None] all = [] orig_new = self.cpu.gc_ll_descr.funcptr_for_new def f(size): allocs.insert(0, size) return orig_new(size) self.cpu.assembler.setup_once() self.cpu.gc_ll_descr.funcptr_for_new = f ofs = symbolic.get_field_token(rstr.STR, 'chars', False)[0] res = self.execute_operation(rop.NEWSTR, [ConstInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 7 # ------------------------------------------------------------ res = self.execute_operation(rop.NEWSTR, [BoxInt(7)], 'ref') assert allocs[0] == 7 + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 7 # ------------------------------------------------------------ TP = lltype.GcArray(lltype.Signed) ofs = symbolic.get_field_token(TP, 'length', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref', descr) assert allocs[0] == 10*WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 # ------------------------------------------------------------ res = self.execute_operation(rop.NEW_ARRAY, [BoxInt(10)], 'ref', descr) assert allocs[0] == 10*WORD + ofs + WORD resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10
def test_arrayitems_not_int(self): TP = lltype.GcArray(lltype.Char) ofs = symbolic.get_field_token(TP, 'length', False)[0] itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref', descr) resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs] == chr(10) for i in range(10): self.execute_operation( rop.SETARRAYITEM_GC, [res, ConstInt(i), BoxInt(i)], 'void', descr) for i in range(10): assert resbuf[itemsofs + i] == chr(i) for i in range(10): r = self.execute_operation(rop.GETARRAYITEM_GC, [res, ConstInt(i)], 'int', descr) assert r.value == i
def test_arrayitems_not_int(self): TP = lltype.GcArray(lltype.Char) ofs = symbolic.get_field_token(TP, 'length', False)[0] itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref', descr) resbuf = self._resbuf(res, ctypes.c_char) assert resbuf[ofs] == chr(10) for i in range(10): self.execute_operation(rop.SETARRAYITEM_GC, [res, ConstInt(i), BoxInt(i)], 'void', descr) for i in range(10): assert resbuf[itemsofs + i] == chr(i) for i in range(10): r = self.execute_operation(rop.GETARRAYITEM_GC, [res, ConstInt(i)], 'int', descr) assert r.value == i
def test_repr_of_descr(): def repr_of_descr(descr): s = descr.repr_of_descr() assert ',' not in s # makes the life easier for pypy.tool.jitlogparser return s c0 = GcCache(False) T = lltype.GcStruct('T') S = lltype.GcStruct('S', ('x', lltype.Char), ('y', lltype.Ptr(T)), ('z', lltype.Ptr(T))) descr1 = get_size_descr(c0, S) s = symbolic.get_size(S, False) assert repr_of_descr(descr1) == '<SizeDescr %d>' % s # descr2 = get_field_descr(c0, S, 'y') o, _ = symbolic.get_field_token(S, 'y', False) assert repr_of_descr(descr2) == '<FieldP S.y %d>' % o # descr2i = get_field_descr(c0, S, 'x') o, _ = symbolic.get_field_token(S, 'x', False) assert repr_of_descr(descr2i) == '<FieldU S.x %d>' % o # descr3 = get_array_descr(c0, lltype.GcArray(lltype.Ptr(S))) o = symbolic.get_size(lltype.Ptr(S), False) assert repr_of_descr(descr3) == '<ArrayP %d>' % o # descr3i = get_array_descr(c0, lltype.GcArray(lltype.Char)) assert repr_of_descr(descr3i) == '<ArrayU 1>' # descr4 = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Ptr(S)) assert repr_of_descr(descr4) == '<Callr %d ir>' % o # descr4i = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Char) assert repr_of_descr(descr4i) == '<Calli 1 ir>' # descr4f = get_call_descr(c0, [lltype.Char, lltype.Ptr(S)], lltype.Float) assert repr_of_descr(descr4f) == '<Callf 8 ir>' # descr5f = get_call_descr(c0, [lltype.Char], lltype.SingleFloat) assert repr_of_descr(descr5f) == '<CallS 4 i>'
def test_unicode(self): ofs = symbolic.get_field_token(rstr.UNICODE, 'chars', False)[0] u = rstr.mallocunicode(13) for i in range(13): u.chars[i] = unichr(ord(u'a') + i) b = InputArgRef(lltype.cast_opaque_ptr(llmemory.GCREF, u)) r = self.execute_operation(rop.UNICODEGETITEM, [b, ConstInt(2)], 'int') assert r == ord(u'a') + 2 self.execute_operation( rop.UNICODESETITEM, [b, ConstInt(2), ConstInt(ord(u'z'))], 'void') assert u.chars[2] == u'z' assert u.chars[3] == u'd'
def test_unicode(self): ofs = symbolic.get_field_token(rstr.UNICODE, 'chars', False)[0] u = rstr.mallocunicode(13) for i in range(13): u.chars[i] = unichr(ord(u'a') + i) b = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, u)) r = self.execute_operation(rop.UNICODEGETITEM, [b, ConstInt(2)], 'int') assert r.value == ord(u'a') + 2 self.execute_operation(rop.UNICODESETITEM, [b, ConstInt(2), ConstInt(ord(u'z'))], 'void') assert u.chars[2] == u'z' assert u.chars[3] == u'd'
def test_arrayitems(self): TP = lltype.GcArray(lltype.Signed) ofs = symbolic.get_field_token(TP, 'length', False)[0] itemsofs = symbolic.get_field_token(TP, 'items', False)[0] descr = self.cpu.arraydescrof(TP) res = self.execute_operation(rop.NEW_ARRAY, [ConstInt(10)], 'ref', descr) resbuf = self._resbuf(res) assert resbuf[ofs/WORD] == 10 self.execute_operation(rop.SETARRAYITEM_GC, [res, ConstInt(2), BoxInt(38)], 'void', descr) assert resbuf[itemsofs/WORD + 2] == 38 self.execute_operation(rop.SETARRAYITEM_GC, [res, BoxInt(3), BoxInt(42)], 'void', descr) assert resbuf[itemsofs/WORD + 3] == 42 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, ConstInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res.constbox(), BoxInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res.constbox(), ConstInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, BoxInt(2)], 'int', descr) assert r.value == 38 r = self.execute_operation(rop.GETARRAYITEM_GC, [res, BoxInt(3)], 'int', descr) assert r.value == 42
def get_field_descr(gccache, STRUCT, fieldname): cache = gccache._cache_field try: return cache[STRUCT][fieldname] except KeyError: offset, size = symbolic.get_field_token(STRUCT, fieldname, gccache.translate_support_code) FIELDTYPE = getattr(STRUCT, fieldname) flag = get_type_flag(FIELDTYPE) name = '%s.%s' % (STRUCT._name, fieldname) fielddescr = FieldDescr(name, offset, size, flag) cachedict = cache.setdefault(STRUCT, {}) cachedict[fieldname] = fielddescr return fielddescr
def _setup_guard_is_object(self): from rpython.memory.gctypelayout import GCData, T_IS_RPYTHON_INSTANCE import struct infobits_offset, _ = symbolic.get_field_token(GCData.TYPE_INFO, 'infobits', True) # compute the offset to the actual *byte*, and the byte mask mask = struct.pack("l", T_IS_RPYTHON_INSTANCE) assert mask.count('\x00') == len(mask) - 1 infobits_offset_plus = 0 while mask.startswith('\x00'): infobits_offset_plus += 1 mask = mask[1:] self._infobits_offset = infobits_offset self._infobits_offset_plus = infobits_offset_plus self._T_IS_RPYTHON_INSTANCE_BYTE = ord(mask[0])
def get_field_descr(gccache, STRUCT, fieldname): cache = gccache._cache_field try: return cache[STRUCT][fieldname] except KeyError: offset, size = symbolic.get_field_token(STRUCT, fieldname, gccache.translate_support_code) FIELDTYPE = getattr(STRUCT, fieldname) flag = get_type_flag(FIELDTYPE) name = '%s.%s' % (STRUCT._name, fieldname) index_in_parent = heaptracker.get_fielddescr_index_in(STRUCT, fieldname) is_pure = STRUCT._immutable_field(fieldname) != False fielddescr = FieldDescr(name, offset, size, flag, index_in_parent, is_pure) cachedict = cache.setdefault(STRUCT, {}) cachedict[fieldname] = fielddescr if STRUCT is rclass.OBJECT: vtable = lltype.nullptr(rclass.OBJECT_VTABLE) else: vtable = heaptracker.get_vtable_for_gcstruct(gccache, STRUCT) fielddescr.parent_descr = get_size_descr(gccache, STRUCT, vtable) return fielddescr
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
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