[pypy-commit] pypy stm-jit: gc_load, stm_gc_load, gc_store: the most generic operations on GC objects,

arigo noreply at buildbot.pypy.org
Sun Aug 5 18:40:01 CEST 2012


Author: Armin Rigo <arigo at 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)


More information about the pypy-commit mailing list