Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit