[pypy-commit] pypy dynamic-specialized-tuple: (arigo, alex) some hacks, and some cleanup. Pretend that a varsized GcStruct is an array from the JIT's point of view

alex_gaynor noreply at buildbot.pypy.org
Wed Mar 14 23:44:41 CET 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: dynamic-specialized-tuple
Changeset: r53617:5d305b2895a0
Date: 2012-03-14 15:44 -0700
http://bitbucket.org/pypy/pypy/changeset/5d305b2895a0/

Log:	(arigo, alex) some hacks, and some cleanup. Pretend that a varsized
	GcStruct is an array from the JIT's point of view

diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -1424,25 +1424,27 @@
     uni = lltype.cast_opaque_ptr(lltype.Ptr(rstr.UNICODE), string)
     return ord(uni.chars[index])
 
-def do_getarrayitem_gc_int(array, index):
-    array = array._obj.container
-    return cast_to_int(array.getitem(index))
+def new_do_getarrayitem(cast_func, gc):
+    def do_getarrayitem(array, index):
+        if gc:
+            array = array._obj.container
+            A = lltype.typeOf(array)
+            if isinstance(A, lltype.GcStruct):
+                array = getattr(array, A._arrayfld)
+        else:
+            array = array.adr.ptr._obj
+        value = array.getitem(index)
+        if cast_func is cast_to_ptr and lltype.typeOf(value) is llmemory.Address:
+            assert isinstance(A, lltype.GcStruct)
+            value = llmemory.cast_adr_to_ptr(value, llmemory.GCREF)
+        return cast_func(value)
+    return do_getarrayitem
 
-def do_getarrayitem_raw_int(array, index):
-    array = array.adr.ptr._obj
-    return cast_to_int(array.getitem(index))
-
-def do_getarrayitem_gc_float(array, index):
-    array = array._obj.container
-    return cast_to_floatstorage(array.getitem(index))
-
-def do_getarrayitem_raw_float(array, index):
-    array = maybe_uncast(FLOAT_ARRAY_TP, array.adr.ptr)
-    return cast_to_floatstorage(array._obj.getitem(index))
-
-def do_getarrayitem_gc_ptr(array, index):
-    array = array._obj.container
-    return cast_to_ptr(array.getitem(index))
+do_getarrayitem_gc_int = new_do_getarrayitem(cast_to_int, gc=True)
+do_getarrayitem_raw_int = new_do_getarrayitem(cast_to_int, gc=False)
+do_getarrayitem_gc_float = new_do_getarrayitem(cast_to_floatstorage, gc=True)
+do_getarrayitem_raw_float = new_do_getarrayitem(cast_to_floatstorage, gc=False)
+do_getarrayitem_gc_ptr = new_do_getarrayitem(cast_to_ptr, gc=True)
 
 def _getfield_gc(struct, fieldnum):
     STRUCT, fieldname = symbolic.TokenToField[fieldnum]
@@ -1504,36 +1506,39 @@
     x = lltype.malloc(TYPE, count, zero=True)
     return cast_to_ptr(x)
 
-def do_setarrayitem_gc_int(array, index, newvalue):
-    array = array._obj.container
-    ITEMTYPE = lltype.typeOf(array).OF
-    newvalue = cast_from_int(ITEMTYPE, newvalue)
-    array.setitem(index, newvalue)
+def new_do_setarrayitem(cast_func, gc):
+    def do_setarrayitem(array, index, newvalue):
+        casted = False
+        if gc:
+            array = array._obj.container
+            A = lltype.typeOf(array)
+            if isinstance(A, lltype.GcStruct):
+                ITEMTYPE = getattr(A, A._arrayfld).OF
+                if (ITEMTYPE is llmemory.Address and
+                    isinstance(lltype.typeOf(newvalue), lltype.Ptr)):
+                    newvalue = llmemory.cast_ptr_to_adr(newvalue)
+                    casted = True
+            else:
+                ITEMTYPE = lltype.typeOf(array).OF
+        else:
+            array = array.adr.ptr
+            ITEMTYPE = lltype.typeOf(array).TO.OF
+        if not casted:
+            newvalue = cast_func(ITEMTYPE, newvalue)
+        if gc:
+            if isinstance(A, lltype.GcStruct):
+                getattr(array, A._arrayfld).setitem(index, newvalue)
+            else:
+                array.setitem(index, newvalue)
+        else:
+            array._obj.setitem(index, newvalue)
+    return do_setarrayitem
 
-def do_setarrayitem_raw_int(array, index, newvalue):
-    array = array.adr.ptr
-    ITEMTYPE = lltype.typeOf(array).TO.OF
-    newvalue = cast_from_int(ITEMTYPE, newvalue)
-    array._obj.setitem(index, newvalue)
-
-def do_setarrayitem_gc_float(array, index, newvalue):
-    array = array._obj.container
-    ITEMTYPE = lltype.typeOf(array).OF
-    newvalue = cast_from_floatstorage(ITEMTYPE, newvalue)
-    array.setitem(index, newvalue)
-
-
-def do_setarrayitem_raw_float(array, index, newvalue):
-    array = maybe_uncast(FLOAT_ARRAY_TP, array.adr.ptr)
-    ITEMTYPE = lltype.typeOf(array).TO.OF
-    newvalue = cast_from_floatstorage(ITEMTYPE, newvalue)
-    array._obj.setitem(index, newvalue)
-
-def do_setarrayitem_gc_ptr(array, index, newvalue):
-    array = array._obj.container
-    ITEMTYPE = lltype.typeOf(array).OF
-    newvalue = cast_from_ptr(ITEMTYPE, newvalue)
-    array.setitem(index, newvalue)
+do_setarrayitem_gc_int = new_do_setarrayitem(cast_from_int, gc=True)
+do_setarrayitem_raw_int = new_do_setarrayitem(cast_from_int, gc=False)
+do_setarrayitem_gc_float = new_do_setarrayitem(cast_from_floatstorage, gc=True)
+do_setarrayitem_raw_float = new_do_setarrayitem(cast_from_floatstorage, gc=False)
+do_setarrayitem_gc_ptr = new_do_setarrayitem(cast_from_ptr, gc=True)
 
 def new_setfield_gc(cast_func):
     def do_setfield_gc(struct, fieldnum, newvalue):
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -388,9 +388,12 @@
         return llimpl.grab_exc_value()
 
     def arraydescrof(self, A):
+        size = symbolic.get_size(A)
+        if isinstance(A, lltype.GcStruct):
+            A = getattr(A, A._arrayfld)
+        else:
+            assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False)
         assert A.OF != lltype.Void
-        assert isinstance(A, lltype.GcArray) or A._hints.get('nolength', False)
-        size = symbolic.get_size(A)
         if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive):
             token = history.getkind(A.OF)[0]
         elif isinstance(A.OF, lltype.Struct):
@@ -399,6 +402,11 @@
             token = '?'
         return self.getdescr(size, token)
 
+    def copy_and_change_descr_typeinfo_to_ptr(self, descr):
+        return self.getdescr(descr.ofs, "r", descr.extrainfo, descr.name,
+                             descr.arg_types, descr.count_fields_if_immut,
+                             descr.ffi_flags, descr.width)
+
     # ---------- the backend-dependent operations ----------
 
     def bh_strlen(self, string):


More information about the pypy-commit mailing list