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

Reply via email to