Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r66865:af5e7f014b6e Date: 2013-09-09 18:12 +0200 http://bitbucket.org/pypy/pypy/changeset/af5e7f014b6e/
Log: Use raw_load() and raw_store() instead of custom logic for {read_write}_{int,ref,float}_at_mem(), with an extention that puts them on the same level as getfield/ setfield: the variant 'raw_store(GC obj, offset, GC obj)' generates a write barrier in gctransform/framework.py. diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -368,68 +368,42 @@ @specialize.argtype(1) def read_int_at_mem(self, gcref, ofs, size, sign): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) for STYPE, UTYPE, itemsize in unroll_basic_sizes: if size == itemsize: if sign: - items = rffi.cast(rffi.CArrayPtr(STYPE), items) - val = items[0] + val = llop.raw_load(STYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) else: - items = rffi.cast(rffi.CArrayPtr(UTYPE), items) - val = items[0] + val = llop.raw_load(UTYPE, gcref, ofs) val = rffi.cast(lltype.Signed, val) - # --- end of GC unsafe code --- return val else: raise NotImplementedError("size = %d" % size) @specialize.argtype(1) def write_int_at_mem(self, gcref, ofs, size, newvalue): - # --- start of GC unsafe code (no GC operation!) --- - items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) for TYPE, _, itemsize in unroll_basic_sizes: if size == itemsize: - items = rffi.cast(rffi.CArrayPtr(TYPE), items) - items[0] = rffi.cast(TYPE, newvalue) - # --- end of GC unsafe code --- + newvalue = rffi.cast(TYPE, newvalue) + llop.raw_store(lltype.Void, gcref, ofs, newvalue) return else: raise NotImplementedError("size = %d" % size) def read_ref_at_mem(self, 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) - pval = self._cast_int_to_gcref(items[0]) - # --- end of GC unsafe code --- - return pval + return llop.raw_load(llmemory.GCREF, gcref, ofs) def write_ref_at_mem(self, gcref, ofs, newvalue): - self.gc_ll_descr.do_write_barrier(gcref, newvalue) - # --- 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) - items[0] = self.cast_gcref_to_int(newvalue) - # --- end of GC unsafe code --- + llop.raw_store(lltype.Void, gcref, ofs, newvalue) + # the write barrier is implied above @specialize.argtype(1) def read_float_at_mem(self, 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) - fval = items[0] - # --- end of GC unsafe code --- - return fval + return llop.raw_load(longlong.FLOATSTORAGE, gcref, ofs) @specialize.argtype(1) def write_float_at_mem(self, gcref, ofs, newvalue): - # --- 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) - items[0] = newvalue - # --- end of GC unsafe code --- + llop.raw_store(lltype.Void, gcref, ofs, newvalue) # ____________________________________________________________ diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -1100,7 +1100,8 @@ opname = hop.spaceop.opname v_struct = hop.spaceop.args[0] v_newvalue = hop.spaceop.args[-1] - assert opname in ('setfield', 'setarrayitem', 'setinteriorfield') + assert opname in ('setfield', 'setarrayitem', 'setinteriorfield', + 'raw_store') assert isinstance(v_newvalue.concretetype, lltype.Ptr) # XXX for some GCs the skipping if the newvalue is a constant won't be # ok diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py --- a/rpython/memory/gctransform/transform.py +++ b/rpython/memory/gctransform/transform.py @@ -330,6 +330,7 @@ hop.rename('bare_' + hop.spaceop.opname) gct_setarrayitem = gct_setfield gct_setinteriorfield = gct_setfield + gct_raw_store = gct_setfield gct_getfield = default diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -969,6 +969,10 @@ op_raw_load.need_result_type = True def op_raw_store(self, addr, offset, value): + # XXX handle the write barrier by delegating to self.heap instead + self.op_bare_raw_store(addr, offset, value) + + def op_bare_raw_store(self, addr, offset, value): checkadr(addr) ARGTYPE = lltype.typeOf(value) if isinstance(offset, int): diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -410,8 +410,9 @@ 'raw_memclear': LLOp(), 'raw_memcopy': LLOp(), 'raw_memmove': LLOp(), - 'raw_load': LLOp(sideeffects=False), - 'raw_store': LLOp(), + 'raw_load': LLOp(sideeffects=False, canrun=True), + 'raw_store': LLOp(canrun=True), + 'bare_raw_store': LLOp(), 'stack_malloc': LLOp(), # mmh 'track_alloc_start': LLOp(), 'track_alloc_stop': LLOp(), diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py --- a/rpython/rtyper/lltypesystem/opimpl.py +++ b/rpython/rtyper/lltypesystem/opimpl.py @@ -660,6 +660,26 @@ msg = ''.join(ll_msg.chars) raise LLFatalError(msg) +def op_raw_store(p, ofs, newvalue): + from rpython.rtyper.lltypesystem import rffi + TP = lltype.typeOf(p) + if TP != llmemory.Address: + assert TP == llmemory.GCREF + p = rffi.cast(llmemory.Address, p) + TVAL = lltype.typeOf(newvalue) + p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) + p[0] = newvalue + +def op_raw_load(TVAL, p, ofs): + from rpython.rtyper.lltypesystem import rffi + TP = lltype.typeOf(p) + if TP != llmemory.Address: + assert TP == llmemory.GCREF + p = rffi.cast(llmemory.Address, p) + p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) + return p[0] +op_raw_load.need_result_type = True + # ____________________________________________________________ def get_op_impl(opname): diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -692,6 +692,7 @@ return ( '((%(typename)s) (((char *)%(addr)s) + %(offset)s))[0] = %(value)s;' % locals()) + OP_BARE_RAW_STORE = OP_RAW_STORE def OP_RAW_LOAD(self, op): addr = self.expr(op.args[0]) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit