[pypy-commit] pypy ffi-backend: (arigo, fijal) a half broken implementation of raw_store in the jit

fijal noreply at buildbot.pypy.org
Sun Jun 24 18:06:53 CEST 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: ffi-backend
Changeset: r55803:fd15b25e46da
Date: 2012-06-24 17:42 +0200
http://bitbucket.org/pypy/pypy/changeset/fd15b25e46da/

Log:	(arigo, fijal) a half broken implementation of raw_store in the jit

diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -81,9 +81,13 @@
     OS_LLONG_U_TO_FLOAT         = 94
     #
     OS_MATH_SQRT                = 100
+    #
+    OS_RAW_MALLOC_VARSIZE       = 110
+    OS_RAW_FREE                 = 111
 
     # for debugging:
-    _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL])
+    _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL,
+                        OS_RAW_MALLOC_VARSIZE])
 
     def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
                 write_descrs_fields, write_descrs_arrays,
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -11,6 +11,7 @@
 from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, c_last_exception
 from pypy.rlib import objectmodel
 from pypy.rlib.jit import _we_are_jitted
+from pypy.rlib.rgc import lltype_is_gc
 from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rclass, rffi
 from pypy.rpython.rclass import IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY
 from pypy.translator.simplify import get_funcobj
@@ -208,6 +209,10 @@
         if op.args[0] in self.vable_array_vars:
             self.vable_array_vars[op.result]= self.vable_array_vars[op.args[0]]
 
+    def rewrite_op_cast_ptr_to_adr(self, op):
+        if lltype_is_gc(op.args[0].concretetype):
+            raise Exception("cast_ptr_to_adr for GC types unsupported")
+
     def rewrite_op_cast_pointer(self, op):
         newop = self.rewrite_op_same_as(op)
         assert newop is None
@@ -520,9 +525,12 @@
             name += '_add_memory_pressure'
         if not track_allocation:
             name += '_no_track_allocation'
-        return self._do_builtin_call(op, name, args,
-                                     extra = (TYPE,),
-                                     extrakey = TYPE)
+        op1 = self.prepare_builtin_call(op, name, args, (TYPE,), TYPE)
+        if name == 'raw_malloc_varsize':
+            return self._handle_oopspec_call(op1, args,
+                                             EffectInfo.OS_RAW_MALLOC_VARSIZE,
+                                             EffectInfo.EF_CAN_RAISE)
+        return self.rewrite_op_direct_call(op1)
 
     def rewrite_op_malloc_varsize(self, op):
         if op.args[1].value['flavor'] == 'raw':
@@ -550,8 +558,13 @@
         name = 'raw_free'
         if not track_allocation:
             name += '_no_track_allocation'
-        return self._do_builtin_call(op, name, [op.args[0]],
-                                     extra = (STRUCT,), extrakey = STRUCT)
+        op1 = self.prepare_builtin_call(op, name, [op.args[0]], (STRUCT,),
+                                        STRUCT)
+        if name == 'raw_free':
+            return self._handle_oopspec_call(op1, [op.args[0]],
+                                             EffectInfo.OS_RAW_FREE,
+                                             EffectInfo.EF_CANNOT_RAISE)
+        return self.rewrite_op_direct_call(op1)
 
     def rewrite_op_getarrayitem(self, op):
         ARRAY = op.args[0].concretetype.TO
@@ -840,6 +853,12 @@
             return SpaceOperation('setinteriorfield_gc_%s' % kind, args,
                                   op.result)
 
+    def rewrite_op_raw_store(self, op):
+        kind = getkind(op.args[3].concretetype)[0]
+        return SpaceOperation('raw_store_%s' % kind,
+                              [op.args[0], op.args[2], op.args[3]],
+                              None)
+
     def _rewrite_equality(self, op, opname):
         arg0, arg1 = op.args
         if isinstance(arg0, Constant) and not arg0.value:
@@ -850,7 +869,7 @@
             return self._rewrite_symmetric(op)
 
     def _is_gc(self, v):
-        return getattr(getattr(v.concretetype, "TO", None), "_gckind", "?") == 'gc'
+        return lltype_is_gc(v.concretetype)
 
     def _is_rclass_instance(self, v):
         return lltype._castdepth(v.concretetype.TO, rclass.OBJECT) >= 0
diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py
--- a/pypy/jit/codewriter/test/test_jtransform.py
+++ b/pypy/jit/codewriter/test/test_jtransform.py
@@ -123,6 +123,7 @@
             INT = lltype.Signed
             UNICHAR = lltype.UniChar
             FLOAT = lltype.Float
+            ARRAYPTR = rffi.CArrayPtr(lltype.Signed)
             argtypes = {
              EI.OS_MATH_SQRT:  ([FLOAT], FLOAT),
              EI.OS_STR2UNICODE:([PSTR], PUNICODE),
@@ -139,16 +140,26 @@
              EI.OS_UNIEQ_NONNULL_CHAR:   ([PUNICODE, UNICHAR], INT),
              EI.OS_UNIEQ_CHECKNULL_CHAR: ([PUNICODE, UNICHAR], INT),
              EI.OS_UNIEQ_LENGTHOK:       ([PUNICODE, PUNICODE], INT),
+             EI.OS_RAW_MALLOC_VARSIZE:   ([INT], ARRAYPTR),
+             EI.OS_RAW_FREE:             ([ARRAYPTR], lltype.Void),
             }
             argtypes = argtypes[oopspecindex]
             assert argtypes[0] == [v.concretetype for v in op.args[1:]]
             assert argtypes[1] == op.result.concretetype
             if oopspecindex == EI.OS_STR2UNICODE:
                 assert extraeffect == EI.EF_ELIDABLE_CAN_RAISE
+            elif oopspecindex == EI.OS_RAW_MALLOC_VARSIZE:
+                assert extraeffect == EI.EF_CAN_RAISE
+            elif oopspecindex == EI.OS_RAW_FREE:
+                assert extraeffect == EI.EF_CANNOT_RAISE
             else:
                 assert extraeffect == EI.EF_ELIDABLE_CANNOT_RAISE
         return 'calldescr-%d' % oopspecindex
+
     def calldescr_canraise(self, calldescr):
+        EI = effectinfo.EffectInfo
+        if calldescr == 'calldescr-%d' % EI.OS_RAW_MALLOC_VARSIZE:
+            return True
         return False
 
 
@@ -547,10 +558,13 @@
     flags = Constant({'flavor': 'raw'}, lltype.Void)
     op = SpaceOperation('malloc_varsize', [Constant(S, lltype.Void), flags,
                                            v1], v)
-    tr = Transformer(FakeCPU(), FakeResidualCallControl())
+    tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
     op0, op1 = tr.rewrite_operation(op)
     assert op0.opname == 'residual_call_ir_i'
     assert op0.args[0].value == 'raw_malloc_varsize' # pseudo-function as a str
+    assert (op0.args[1] == 'calldescr-%d' %
+            effectinfo.EffectInfo.OS_RAW_MALLOC_VARSIZE)
+
     assert op1.opname == '-live-'
     assert op1.args == []
 
@@ -591,21 +605,28 @@
     assert op1.args == []
 
 def test_raw_free():
-    S = lltype.Struct('dummy', ('x', lltype.Signed))
-    for flag in [True, False]:
-        flags = Constant({'flavor': 'raw', 'track_allocation': flag},
-                         lltype.Void)
-        op = SpaceOperation('free', [varoftype(lltype.Ptr(S)), flags],
-                            varoftype(lltype.Void))
-        tr = Transformer(FakeCPU(), FakeResidualCallControl())
-        op0, op1 = tr.rewrite_operation(op)
-        assert op0.opname == 'residual_call_ir_v'
-        if flag:
-            pseudo_op_name = 'raw_free'
-        else:
-            pseudo_op_name = 'raw_free_no_track_allocation'
-        assert op0.args[0].value == pseudo_op_name   # pseudo-function as a str
-        assert op1.opname == '-live-'
+    S = rffi.CArray(lltype.Signed)
+    flags = Constant({'flavor': 'raw', 'track_allocation': True},
+                     lltype.Void)
+    op = SpaceOperation('free', [varoftype(lltype.Ptr(S)), flags],
+                        varoftype(lltype.Void))
+    tr = Transformer(FakeCPU(), FakeBuiltinCallControl())
+    op0 = tr.rewrite_operation(op)
+    assert op0.opname == 'residual_call_ir_v'
+    assert op0.args[0].value == 'raw_free'
+    assert op0.args[1] == 'calldescr-%d' % effectinfo.EffectInfo.OS_RAW_FREE
+
+def test_raw_free_no_track_allocation():
+    S = rffi.CArray(lltype.Signed)
+    flags = Constant({'flavor': 'raw', 'track_allocation': False},
+                     lltype.Void)
+    op = SpaceOperation('free', [varoftype(lltype.Ptr(S)), flags],
+                        varoftype(lltype.Void))
+    tr = Transformer(FakeCPU(), FakeResidualCallControl())
+    op0, op1 = tr.rewrite_operation(op)
+    assert op0.opname == 'residual_call_ir_v'
+    assert op0.args[0].value == 'raw_free_no_track_allocation'
+    assert op1.opname == '-live-'
 
 def test_rename_on_links():
     v1 = Variable()
@@ -621,6 +642,13 @@
     assert block.exits[0].target is block2
     assert block.exits[0].args == [v1]
 
+def test_cast_ptr_to_adr():
+    t = Transformer(FakeCPU(), None)
+    v = varoftype(lltype.Ptr(lltype.Array()))
+    v2 = varoftype(llmemory.Address)
+    op1 = t.rewrite_operation(SpaceOperation('cast_ptr_to_adr', [v], v2))
+    assert op1 is None
+
 def test_int_eq():
     v1 = varoftype(lltype.Signed)
     v2 = varoftype(lltype.Signed)
@@ -830,6 +858,15 @@
     op1 = Transformer(FakeCPU()).rewrite_operation(op)
     assert not op1
 
+def test_raw_store():
+    v_storage = varoftype(llmemory.Address)
+    v_typ = varoftype(lltype.Void)
+    v_index = varoftype(lltype.Signed)
+    v_item = varoftype(lltype.Signed) # for example
+    op = SpaceOperation('raw_store', [v_storage, v_typ, v_index, v_item])
+    op1 = Transformer(FakeCPU()).rewrite_operation(op)
+    assert op1.opname == 'raw_store'
+
 def test_promote_1():
     v1 = varoftype(lltype.Signed)
     v2 = varoftype(lltype.Signed)
diff --git a/pypy/jit/metainterp/test/test_rawmem.py b/pypy/jit/metainterp/test/test_rawmem.py
--- a/pypy/jit/metainterp/test/test_rawmem.py
+++ b/pypy/jit/metainterp/test/test_rawmem.py
@@ -1,6 +1,7 @@
 from pypy.jit.metainterp.test.support import LLJitMixin
 from pypy.rpython.lltypesystem import lltype, rffi
-
+from pypy.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem,
+                                  free_raw_storage)
 
 class TestJITRawMem(LLJitMixin):
     def test_cast_void_ptr(self):
@@ -18,7 +19,7 @@
             s += rffi.cast(lltype.Ptr(TP), a.storage)[0]
             lltype.free(x, flavor="raw")
             return s
-        res = self.interp_operations(f, [10])
+        self.interp_operations(f, [10])
 
     def test_fixed_size_malloc(self):
         TIMEVAL = lltype.Struct('dummy', ('tv_sec', rffi.LONG), ('tv_usec', rffi.LONG))
@@ -30,3 +31,14 @@
         assert res == 42
         self.check_operations_history({'call': 2, 'guard_no_exception': 1,
                                        'finish': 1})
+
+    def test_raw_storage(self):
+        def f():
+            p = alloc_raw_storage(15)
+            raw_storage_setitem(p, 3, 24)
+            free_raw_storage(p)
+            return 42
+        res = self.interp_operations(f, [])
+        assert res == 42
+        self.check_operations_history({'call': 2, 'guard_no_exception': 1,
+                                       'finish': 1})
diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py
--- a/pypy/rlib/rgc.py
+++ b/pypy/rlib/rgc.py
@@ -475,3 +475,6 @@
     def specialize_call(self, hop):
         hop.exception_is_here()
         return hop.genop('gc_typeids_z', [], resulttype = hop.r_result)
+
+def lltype_is_gc(TP):
+    return getattr(getattr(TP, "TO", None), "_gckind", "?") == 'gc'
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -1011,8 +1011,14 @@
     def op_raw_store(self, addr, typ, offset, value):
         checkadr(addr)
         assert lltype.typeOf(value) == typ
-        assert offset.TYPE == typ
-        getattr(addr, str(typ).lower())[offset.repeat] = value
+        if isinstance(offset, int):
+            from pypy.rpython.lltypesystem import rffi
+            ll_p = rffi.cast(rffi.CCHARP, addr)
+            ll_p = rffi.cast(rffi.CArrayPtr(typ), rffi.ptradd(ll_p, offset))
+            ll_p[0] = value
+        else:
+            assert offset.TYPE == typ
+            getattr(addr, str(typ).lower())[offset.repeat] = value
 
     def op_stack_malloc(self, size): # mmh
         raise NotImplementedError("backend only")


More information about the pypy-commit mailing list