Author: Armin Rigo <ar...@tunes.org> Branch: stm-jit Changeset: r56588:777f095f8f84 Date: 2012-08-05 17:26 +0200 http://bitbucket.org/pypy/pypy/changeset/777f095f8f84/
Log: gc_load, stm_gc_load, gc_store: the most generic operations on GC objects, reading or writing a field of any type in a given GC object at a given offset. diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py --- a/pypy/jit/backend/llsupport/gc.py +++ b/pypy/jit/backend/llsupport/gc.py @@ -635,14 +635,16 @@ def get_write_barrier_from_array_fn(self, cpu): # returns a function with arguments [array, index, newvalue] + assert not self.returns_modified_object llop1 = self.llop1 funcptr = llop1.get_write_barrier_from_array_failing_case( self.WB_FUNCPTR) funcaddr = llmemory.cast_ptr_to_adr(funcptr) - assert not (funcaddr and self.returns_modified_object) return cpu.cast_adr_to_int(funcaddr) # this may return 0 def has_write_barrier_from_array(self, cpu): + if self.returns_modified_object: + return False return self.get_write_barrier_from_array_fn(cpu) != 0 diff --git a/pypy/jit/backend/llsupport/llmodel.py b/pypy/jit/backend/llsupport/llmodel.py --- a/pypy/jit/backend/llsupport/llmodel.py +++ b/pypy/jit/backend/llsupport/llmodel.py @@ -394,8 +394,8 @@ for TYPE, _, itemsize in unroll_basic_sizes: if size == itemsize: ofs += itemsize * itemindex - llop.stm_gc_store(lltype.Void, gcref, ofs, - rffi.cast(TYPE, newvalue)) + llop.gc_store(lltype.Void, gcref, ofs, + rffi.cast(TYPE, newvalue)) return else: raise NotImplementedError("size = %d" % size) @@ -406,7 +406,7 @@ else: ofs = self.unpack_arraydescr(arraydescr) ofs += llmemory.sizeof(llmemory.GCREF) * itemindex - llop.stm_gc_store(lltype.Void, gcref, ofs, newvalue) + llop.gc_store(lltype.Void, gcref, ofs, newvalue) def bh_setarrayitem_gc_f(self, arraydescr, gcref, itemindex, newvalue): if not self.gc_ll_descr.stm: @@ -414,7 +414,7 @@ else: ofs = self.unpack_arraydescr(arraydescr) ofs += llmemory.sizeof(longlong.FLOATSTORAGE) * itemindex - llop.stm_gc_store(lltype.Void, gcref, ofs, newvalue) + llop.gc_store(lltype.Void, gcref, ofs, newvalue) bh_setarrayitem_raw_i = _base_setarrayitem_i bh_setarrayitem_raw_f = _base_setarrayitem_f @@ -428,10 +428,10 @@ if size == itemsize: ofs += itemsize * itemindex if sign: - val = llop.stm_gc_load(STYPE, gcref, ofs) + val = llop.gc_load(STYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) else: - val = llop.stm_gc_load(UTYPE, gcref, ofs) + val = llop.gc_load(UTYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) return val else: @@ -443,7 +443,7 @@ else: ofs = self.unpack_arraydescr(arraydescr) ofs += llmemory.sizeof(llmemory.GCREF) * itemindex - return llop.stm_gc_load(llmemory.GCREF, gcref, ofs) + return llop.gc_load(llmemory.GCREF, gcref, ofs) def bh_getarrayitem_gc_f(self, arraydescr, gcref, itemindex): if not self.gc_ll_descr.stm: @@ -451,7 +451,7 @@ else: ofs = self.unpack_arraydescr(arraydescr) ofs += llmemory.sizeof(longlong.FLOATSTORAGE) * itemindex - return llop.stm_gc_load(longlong.FLOATSTORAGE, gcref, ofs) + return llop.gc_load(longlong.FLOATSTORAGE, gcref, ofs) bh_getarrayitem_raw_i = _base_getarrayitem_i bh_getarrayitem_raw_f = _base_getarrayitem_f @@ -469,10 +469,10 @@ for STYPE, UTYPE, itemsize in unroll_basic_sizes: if fieldsize == itemsize: if sign: - val = llop.stm_gc_load(STYPE, gcref, fullofs) + val = llop.gc_load(STYPE, gcref, fullofs) val = rffi.cast(lltype.Signed, val) else: - val = llop.stm_gc_load(UTYPE, gcref, fullofs) + val = llop.gc_load(UTYPE, gcref, fullofs) val = rffi.cast(lltype.Signed, val) return val else: @@ -501,7 +501,7 @@ ofs += descr.fielddescr.offset + size * itemindex # if self.gc_ll_descr.stm: - return llop.stm_gc_load(llmemory.GCREF, gcref, ofs) + return llop.gc_load(llmemory.GCREF, gcref, ofs) # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) @@ -516,7 +516,7 @@ ofs += descr.fielddescr.offset + size * itemindex # if self.gc_ll_descr.stm: - return llop.stm_gc_load(longlong.FLOATSTORAGE, gcref, ofs) + return llop.gc_load(longlong.FLOATSTORAGE, gcref, ofs) # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) items = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), items) @@ -535,8 +535,8 @@ if self.gc_ll_descr.stm: for TYPE, _, itemsize in unroll_basic_sizes: if fieldsize == itemsize: - llop.stm_gc_store(lltype.Void, gcref, ofs, - rffi.cast(TYPE, value)) + llop.gc_store(lltype.Void, gcref, ofs, + rffi.cast(TYPE, value)) return else: raise NotImplementedError("size = %d" % fieldsize) @@ -558,7 +558,7 @@ ofs += descr.fielddescr.offset + size * itemindex # if self.gc_ll_descr.stm: - llop.stm_gc_store(llmemory.GCREF, gcref, ofs, newvalue) + llop.gc_store(llmemory.GCREF, gcref, ofs, newvalue) return # self.gc_ll_descr.do_write_barrier(gcref, newvalue) @@ -575,7 +575,7 @@ ofs += descr.fielddescr.offset + size * itemindex # if self.gc_ll_descr.stm: - llop.stm_gc_store(longlong.FLOATSTORAGE, gcref, ofs, newvalue) + llop.gc_store(longlong.FLOATSTORAGE, gcref, ofs, newvalue) return # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) @@ -647,10 +647,10 @@ for STYPE, UTYPE, itemsize in unroll_basic_sizes: if size == itemsize: if sign: - val = llop.stm_gc_load(STYPE, struct, ofs) + val = llop.gc_load(STYPE, struct, ofs) val = rffi.cast(lltype.Signed, val) else: - val = llop.stm_gc_load(UTYPE, struct, ofs) + val = llop.gc_load(UTYPE, struct, ofs) val = rffi.cast(lltype.Signed, val) return val else: @@ -661,14 +661,14 @@ return self._base_do_getfield_r(struct, fielddescr) else: ofs = self.unpack_fielddescr(fielddescr) - return llop.stm_gc_load(llmemory.GCREF, struct, ofs) + return llop.gc_load(llmemory.GCREF, struct, ofs) def bh_getfield_gc_f(self, struct, fielddescr): if not self.gc_ll_descr.stm: return self._base_do_getfield_f(struct, fielddescr) else: ofs = self.unpack_fielddescr(fielddescr) - return llop.stm_gc_load(longlong.FLOATSTORAGE, struct, ofs) + return llop.gc_load(longlong.FLOATSTORAGE, struct, ofs) bh_getfield_raw_i = _base_do_getfield_i bh_getfield_raw_f = _base_do_getfield_f @@ -712,8 +712,8 @@ ofs, size, sign = self.unpack_fielddescr_size(fielddescr) for TYPE, _, itemsize in unroll_basic_sizes: if size == itemsize: - llop.stm_gc_store(lltype.Void, struct, ofs, - rffi.cast(TYPE, newvalue)) + llop.gc_store(lltype.Void, struct, ofs, + rffi.cast(TYPE, newvalue)) return else: raise NotImplementedError("size = %d" % size) @@ -723,14 +723,14 @@ self._base_do_setfield_r(struct, fielddescr, newvalue) else: ofs = self.unpack_fielddescr(fielddescr) - llop.stm_gc_store(lltype.Void, struct, ofs, newvalue) + llop.gc_store(lltype.Void, struct, ofs, newvalue) def bh_setfield_gc_f(self, struct, fielddescr, newvalue): if not self.gc_ll_descr.stm: self._base_do_setfield_f(struct, fielddescr, newvalue) else: ofs = self.unpack_fielddescr(fielddescr) - llop.stm_gc_store(lltype.Void, struct, ofs, newvalue) + llop.gc_store(lltype.Void, struct, ofs, newvalue) bh_setfield_raw_i = _base_do_setfield_i bh_setfield_raw_f = _base_do_setfield_f diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py --- a/pypy/rpython/lltypesystem/lloperation.py +++ b/pypy/rpython/lltypesystem/lloperation.py @@ -409,8 +409,9 @@ 'stm_start_transaction': LLOp(canrun=True, canmallocgc=True), 'stm_stop_transaction': LLOp(canrun=True, canmallocgc=True), + 'gc_load': LLOp(sideeffects=False), # so far, only if stm + 'gc_store': LLOp(), # so far, only if stm 'stm_gc_load': LLOp(sideeffects=False), - 'stm_gc_store': LLOp(), # __________ address operations __________ diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py --- a/pypy/rpython/lltypesystem/lltype.py +++ b/pypy/rpython/lltypesystem/lltype.py @@ -206,7 +206,7 @@ assert isinstance(T, Struct) T = getattr(T, fieldname) else: - assert isinstance(T, Array) + assert isinstance(T, (Array, FixedSizeArray)) T = T.OF return False diff --git a/pypy/translator/c/funcgen.py b/pypy/translator/c/funcgen.py --- a/pypy/translator/c/funcgen.py +++ b/pypy/translator/c/funcgen.py @@ -610,6 +610,7 @@ OP_STM_GETINTERIORFIELD = _OP_STM OP_STM_SETINTERIORFIELD = _OP_STM OP_STM_BECOME_INEVITABLE = _OP_STM + OP_STM_GC_LOAD = _OP_STM def OP_PTR_NONZERO(self, op): diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py --- a/pypy/translator/stm/funcgen.py +++ b/pypy/translator/stm/funcgen.py @@ -55,6 +55,16 @@ access_info = (None, ptr, expr) return _stm_generic_get(funcgen, op, access_info) +def stm_gc_load(funcgen, op): + ptr = funcgen.expr(op.args[0]) + ofs = funcgen.expr(op.args[1]) + T = funcgen.lltypemap(op.result) + resulttypename = funcgen.db.gettype(T) + cresulttypename_ptr = cdecl(resulttypename, ' *') + expr = '(*(%s)(((char *)(%s)) + (%s)))' % (cresulttypename_ptr, ptr, ofs) + access_info = (None, ptr, expr) + return _stm_generic_get(funcgen, op, access_info) + def stm_become_inevitable(funcgen, op): try: diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py --- a/pypy/translator/stm/transform.py +++ b/pypy/translator/stm/transform.py @@ -203,6 +203,12 @@ def stt_setinteriorfield(self, newoperations, op): self.transform_set(newoperations, op) + def stt_gc_load(self, newoperations, op): + self.transform_get(newoperations, op, 'stm_gc_load') + + def stt_gc_store(self, newoperations, op): + self.transform_set(newoperations, op) + def stt_stm_writebarrier(self, newoperations, op): if self.localtracker.try_ensure_local(op.args[0]): op = SpaceOperation('same_as', op.args, op.result) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit