[pypy-svn] r37635 - in pypy/dist/pypy/jit/timeshifter: . test

ac at codespeak.net ac at codespeak.net
Tue Jan 30 20:58:05 CET 2007


Author: ac
Date: Tue Jan 30 20:58:04 2007
New Revision: 37635

Modified:
   pypy/dist/pypy/jit/timeshifter/rcontainer.py
   pypy/dist/pypy/jit/timeshifter/rtimeshift.py
   pypy/dist/pypy/jit/timeshifter/rvirtualizable.py
   pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
   pypy/dist/pypy/jit/timeshifter/vlist.py
Log:
(pedronis, arre) Support virtual list in virtualizables.



Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py	Tue Jan 30 20:58:04 2007
@@ -1,5 +1,5 @@
 import operator
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.annlowlevel import cachedtype, cast_base_ptr_to_instance
 from pypy.rpython.annlowlevel import base_ptr_lltype, cast_instance_to_base_ptr
 from pypy.jit.timeshifter import rvalue
@@ -7,7 +7,8 @@
 from pypy.jit.timeshifter import rvirtualizable
 
 from pypy.annotation import model as annmodel
-from pypy.rpython.lltypesystem import lloperation, llmemory
+
+from pypy.rpython.lltypesystem import lloperation
 debug_print = lloperation.llop.debug_print
 debug_pdb = lloperation.llop.debug_pdb
 
@@ -27,6 +28,11 @@
 class VirtualContainer(AbstractContainer):
     _attrs_ = []
 
+    allowed_in_virtualizable = False
+
+    def setforced(self, _):
+        raise NotImplementedError
+
 
 class FrozenContainer(AbstractContainer):
     _attrs_ = []
@@ -53,7 +59,7 @@
                     fielddescs fielddesc_by_name
                     immutable noidentity
                     materialize
-                    fill_into
+                    devirtualize
                  """.split()
                             
 
@@ -82,7 +88,7 @@
         self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
 
         self._compute_fielddescs(hrtyper)
-        self._define_fill_into()
+        self._define_devirtualize()
         if self.immutable and self.noidentity:
             self._define_materialize()
         
@@ -118,17 +124,26 @@
         self.fielddesc_by_name = fielddesc_by_name
         self.innermostdesc = innermostdesc        
 
-    def _define_fill_into(self):
+    def _define_devirtualize(self):
+        TYPE = self.TYPE
+        PTRTYPE = self.PTRTYPE
         descs = unrolling_iterable(self.fielddescs)
+
+        def make(vrti):
+            s = lltype.malloc(TYPE)
+            s = lltype.cast_opaque_ptr(llmemory.GCREF, s)
+            return s
+        
         def fill_into(vablerti, s, base, vrti):
+            s = lltype.cast_opaque_ptr(PTRTYPE, s)
             i = 0
             for desc in descs:
                 v = vrti._read_field(vablerti, desc, base, i)
-                i += 1
                 tgt = lltype.cast_pointer(desc.PTRTYPE, s)
                 setattr(tgt, desc.fieldname, v)
-                
-        self.fill_into = fill_into
+                i = i + 1
+
+        self.devirtualize = make, fill_into
 
     def _define_materialize(self):
         TYPE = self.TYPE
@@ -139,7 +154,8 @@
             i = 0
             for desc in descs:
                 v = rvalue.ll_getvalue(boxes[i], desc.RESTYPE)
-                setattr(s, desc.fieldname, v)
+                tgt = lltype.cast_pointer(desc.PTRTYPE, s)
+                setattr(tgt, desc.fieldname, v)
                 i = i + 1
             return rgenop.genconst(s)
 
@@ -230,7 +246,7 @@
         self._define_access_is_null(hrtyper)
 
 
-    def _define_fill_into(self):
+    def _define_virtual_desc(self):
         pass
 
     def _define_getset_field_ptr(self, hrtyper, fielddesc, j):
@@ -324,6 +340,8 @@
 # XXX basic field descs for now
 class FieldDesc(object):
     __metaclass__ = cachedtype
+    _attrs_ = 'structdesc'
+    
     allow_void = False
     virtualizable = False
     gv_default = None
@@ -343,7 +361,7 @@
                 self.virtualizable = T._hints.get('virtualizable', False)
             self.gcref = T._gckind == 'gc'
             if isinstance(T, lltype.ContainerType):
-                if not T._is_varsize():
+                if not T._is_varsize() or hasattr(T, 'll_newlist'):
                     self.canbevirtual = True
             else:
                 T = None
@@ -355,19 +373,12 @@
         if RESTYPE is lltype.Void and self.allow_void:
             pass   # no redboxcls at all
         elif self.virtualizable:
-            pass
+            self.structdesc = StructTypeDesc(hrtyper, T)
         else:
             self.redboxcls = rvalue.ll_redboxcls(RESTYPE)
-
-        if T is not None and isinstance(T, lltype.Struct): # xxx for now
-            self.structdesc = StructTypeDesc(hrtyper, T)
             
         self.immutable = PTRTYPE.TO._hints.get('immutable', False)
 
-    def _get_fill_into(self):
-        return self.structdesc.fill_into
-    fill_into = property(_get_fill_into)
-
     def _freeze_(self):
         return True
 
@@ -485,6 +496,8 @@
 class VirtualStruct(VirtualContainer):
     _attrs_ = "typedesc content_boxes ownbox".split()
 
+    allowed_in_virtualizable = True
+    
     def __init__(self, typedesc):
         self.typedesc = typedesc
         #self.content_boxes = ... set in factory()
@@ -497,6 +510,11 @@
             for box in self.content_boxes:
                 box.enter_block(incoming, memo)
 
+    def setforced(self, gv_forced):
+        self.content_boxes = None
+        self.ownbox.genvar = gv_forced
+        self.ownbox.content = None
+        
     def force_runtime_container(self, jitstate):
         typedesc = self.typedesc
         builder = jitstate.curbuilder
@@ -515,8 +533,7 @@
         #debug_pdb(lltype.Void)
         genvar = builder.genop_malloc_fixedsize(typedesc.alloctoken)
         # force the box pointing to this VirtualStruct
-        self.ownbox.genvar = genvar
-        self.ownbox.content = None
+        self.setforced(genvar)
         fielddescs = typedesc.fielddescs
         for i in range(len(fielddescs)):
             fielddesc = fielddescs[i]
@@ -568,7 +585,8 @@
         bitmask = 1 << memo.bitcount
         memo.bitcount += 1
         rgenop = jitstate.curbuilder.rgenop
-        vrti = rvirtualizable.VirtualStructRTI(rgenop, bitmask)
+        vrti = rvirtualizable.VirtualRTI(rgenop, bitmask)
+        vrti.devirtualize = typedesc.devirtualize
         memo.containers[self] = vrti
 
         builder = jitstate.curbuilder
@@ -590,7 +608,7 @@
                 varindexes.append(j)
                 assert isinstance(box, rvalue.PtrRedBox)
                 content = box.content
-                assert isinstance(content, VirtualStruct) # XXX for now
+                assert content.allowed_in_virtualizable                
                 vrtis.append(content.make_rti(jitstate, memo))
                 j -= 1
 
@@ -618,7 +636,7 @@
             if not box.genvar:
                 assert isinstance(box, rvalue.PtrRedBox)
                 content = box.content
-                assert isinstance(content, VirtualStruct) # xxx for now
+                assert content.allowed_in_virtualizable
                 content.reshape(jitstate, shapemask, memo)
 
 class VirtualizableStruct(VirtualStruct):
@@ -695,7 +713,7 @@
                 varindexes.append(j)
                 assert isinstance(box, rvalue.PtrRedBox)
                 content = box.content
-                assert isinstance(content, VirtualStruct) # XXX for now
+                assert content.allowed_in_virtualizable
                 vrtis.append(content.make_rti(jitstate, memo))
                 j -= 1
 
@@ -752,7 +770,7 @@
                 nvirtual += 1
                 assert isinstance(box, rvalue.PtrRedBox)
                 content = box.content
-                assert isinstance(content, VirtualStruct) # xxx for now
+                assert content.allowed_in_virtualizable
                 content.reshape(jitstate, shapemask, memo)
 
         bitmask = 1 << memo.bitcount

Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py	Tue Jan 30 20:58:04 2007
@@ -961,10 +961,8 @@
                 content.reshape(self, shapemask, memo)
 
             if shapemask:
-                for vstruct, gv_ptr in memo.forced:
-                    vstruct.content_boxes = None
-                    vstruct.ownbox.genvar = gv_ptr
-                    vstruct.ownbox.content = None
+                for vcontainer, gv_ptr in memo.forced:
+                    vcontainer.setforced(gv_ptr)
                 
     def freeze(self, memo):
         result = FrozenJITState()

Modified: pypy/dist/pypy/jit/timeshifter/rvirtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvirtualizable.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rvirtualizable.py	Tue Jan 30 20:58:04 2007
@@ -1,4 +1,5 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, lloperation
+from pypy.rpython.annlowlevel import cachedtype
 from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
 from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
 from pypy.rlib.unroll import unrolling_iterable
@@ -70,7 +71,7 @@
             (get_field_touched,   set_field_touched))
 
 
-class VirtualRTI(object):
+class RTI(object):
     _attrs_ = 'rgenop varindexes vrtis bitmask'.split()
     
     def __init__(self, rgenop, bitmask):
@@ -87,15 +88,14 @@
         index = -frameindex-1
         assert index >= 0
         vrti = self.vrtis[index]
-        assert isinstance(T, lltype.Ptr)
         assert fielddesc.canbevirtual
         assert fielddesc.gcref
-        assert isinstance(vrti, VirtualStructRTI)
+        assert isinstance(vrti, VirtualRTI)
         return vrti._get_forced(vablerti, fielddesc, base)
     _read_field._annspecialcase_ = "specialize:arg(2)"
 
 
-class VirtualizableRTI(VirtualRTI):
+class VirtualizableRTI(RTI):
     _attrs_ = "frameinfo touch_update shape_place".split()
 
     def is_field_virtual(self, base, index):
@@ -105,7 +105,7 @@
         index = -frameindex-1
         assert index >= 0
         vrti = self.vrtis[index]
-        assert isinstance(vrti, VirtualStructRTI)
+        assert isinstance(vrti, VirtualRTI)
         return vrti._is_virtual(self.get_shape(base))       
 
     def read_frame_var(self, T, base, frameindex):
@@ -139,23 +139,26 @@
         self.set_shape(base, bitmask | self.get_shape(base))
 
 
-class VirtualStructRTI(VirtualRTI):
-    _attrs_ = "forced_place"
+class VirtualRTI(RTI):
+    _attrs_ = "forced_place devirtualize".split()
 
-    def _get_forced(self, vablerti, fielddesc, base):
-        T = fielddesc.RESTYPE
+    def _get_forced(self, vablerti, elemdesc, base):
+        T = elemdesc.RESTYPE
         assert isinstance(T, lltype.Ptr)
         shapemask = vablerti.get_shape(base)
         bitmask = self.bitmask
         if bitmask & shapemask:
             return self.rgenop.read_frame_place(T, base, self.forced_place)
-        S = T.TO
-        s = lltype.malloc(S)
-        self.rgenop.write_frame_place(T, base, self.forced_place, s)
+        make, fill_into = self.devirtualize
+        cref = make(self)
+        c = lltype.cast_opaque_ptr(T, cref)        
+        self.rgenop.write_frame_place(T, base, self.forced_place, c)
         vablerti.set_shape(base, shapemask| bitmask)
-        fielddesc.fill_into(vablerti, s, base, self)
-        return s
+        fill_into(vablerti, cref, base, self)
+        return c
     _get_forced._annspecialcase_ = "specialize:arg(2)"
 
     def _is_virtual(self, shapemask):
         return bool(self.bitmask & shapemask)
+
+

Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py	Tue Jan 30 20:58:04 2007
@@ -1072,3 +1072,70 @@
         assert res == main()
 
 
+        
+    def test_virtual_list(self):
+        class V(object):
+            _virtualizable_ = True
+            def __init__(self, l):
+                self.l = l
+
+        def g(v):
+            l = v.l
+            x = l[0]
+            y = l[1]
+            l[0] = y
+            l[1] = x
+            v.l = [x*100, y*100]
+            
+        def f(v):
+            hint(None, global_merge_point=True)
+            l = [1, 10]
+            v.l = l
+            g(v)
+            l2 = v.l
+            return l[0]*2 + l[1] + l2[0] * 2 + l2[1]
+
+        def main():
+            v = V(None)
+            return f(v)
+
+        res = self.timeshift_from_portal(main, f, [], policy=StopAtXPolicy(g))
+        assert res == 20 + 1 + 200 + 1000
+
+    def test_virtual_list_and_struct(self):
+        class S(object):
+            def __init__(self, x, y):
+                self.x = x
+                self.y = y
+
+        class V(object):
+            _virtualizable_ = True
+            def __init__(self, l, s):
+                self.l = l
+                self.s = s
+        def g(v):
+            l = v.l
+            x = l[0]
+            y = l[1]
+            l[0] = y
+            l[1] = x
+            v.l = [x*100, y*100]
+            
+        def f(v):
+            hint(None, global_merge_point=True)
+            l = [1, 10]
+            s = S(3, 7)
+            v.l = l
+            v.s = s
+            g(v)
+            l2 = v.l
+            s2 = v.s
+            return l[0]*2 + l[1] + l2[0] * 2 + l2[1] + s.x * 7 + s.y + s2.x * 7 + s2.y 
+
+        def main():
+            v = V(None, None)
+            return f(v)
+
+        res = self.timeshift_from_portal(main, f, [], policy=StopAtXPolicy(g))
+        assert res == main()
+

Modified: pypy/dist/pypy/jit/timeshifter/vlist.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vlist.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/vlist.py	Tue Jan 30 20:58:04 2007
@@ -1,9 +1,26 @@
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.jit.timeshifter.rcontainer import VirtualContainer, FrozenContainer
 from pypy.jit.timeshifter.rcontainer import cachedtype
-from pypy.jit.timeshifter import rvalue
+from pypy.jit.timeshifter import rvalue, rvirtualizable
 
 
+class ItemDesc(object):
+    __metaclass__ = cachedtype
+    gcref = False
+    canbevirtual = False
+
+    def _freeze_(self):
+        return True
+
+    def __init__(self, ITEM):
+        self.RESTYPE = ITEM
+        if isinstance(ITEM, lltype.Ptr):
+            T = ITEM.TO
+            self.gcref = T._gckind == 'gc'
+            if isinstance(T, lltype.ContainerType):
+                if not T._is_varsize():
+                    self.canbevirtual = True
+
 class ListTypeDesc(object):
     __metaclass__ = cachedtype
 
@@ -13,6 +30,8 @@
         self.LIST = LIST
         self.LISTPTR = lltype.Ptr(LIST)
         self.ptrkind = RGenOp.kindToken(self.LISTPTR)
+        self.null = self.LISTPTR._defl()
+        self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
 
         argtypes = [lltype.Signed]
         ll_newlist_ptr = rtyper.annotate_helper_fn(LIST.ll_newlist,
@@ -27,6 +46,27 @@
         self.tok_ll_setitem_fast = RGenOp.sigToken(
             lltype.typeOf(ll_setitem_fast).TO)
 
+        self._define_devirtualize()
+
+    def _define_devirtualize(self):
+        LIST = self.LIST
+        LISTPTR = self.LISTPTR
+        itemdesc = ItemDesc(LIST.ITEM)
+
+        def make(vrti):
+            n = len(vrti.varindexes)
+            l = LIST.ll_newlist(n)
+            return lltype.cast_opaque_ptr(llmemory.GCREF, l)
+        
+        def fill_into(vablerti, l, base, vrti):
+            l = lltype.cast_opaque_ptr(LISTPTR, l)
+            n = len(vrti.varindexes)
+            for i in range(n):
+                v = vrti._read_field(vablerti, itemdesc, base, i)
+                l.ll_setitem_fast(i, v)
+
+        self.devirtualize = make, fill_into
+
     def _freeze_(self):
         return True
 
@@ -95,6 +135,8 @@
 
 class VirtualList(VirtualContainer):
 
+    allowed_in_virtualizable = True
+
     def __init__(self, typedesc, length=0, itembox=None):
         self.typedesc = typedesc
         self.item_boxes = [itembox] * length
@@ -107,6 +149,11 @@
             for box in self.item_boxes:
                 box.enter_block(incoming, memo)
 
+    def setforced(self, gv_forced):
+        self.item_boxes = None
+        self.ownbox.genvar = gv_forced
+        self.ownbox.content = None        
+
     def force_runtime_container(self, jitstate):
         typedesc = self.typedesc
         builder = jitstate.curbuilder
@@ -117,8 +164,8 @@
         gv_list = builder.genop_call(typedesc.tok_ll_newlist,
                                      typedesc.gv_ll_newlist,
                                      args_gv)
-        self.ownbox.genvar = gv_list
-        self.ownbox.content = None
+        self.setforced(gv_list)
+
         for i in range(len(boxes)):
             gv_item = boxes[i].getgenvar(jitstate)
             args_gv = [gv_list, builder.rgenop.genconst(i), gv_item]
@@ -156,6 +203,70 @@
             self.ownbox = self.ownbox.replace(memo)
 
 
+    def make_rti(self, jitstate, memo):
+        try:
+            return memo.containers[self]
+        except KeyError:
+            pass
+        typedesc = self.typedesc
+        bitmask = 1 << memo.bitcount
+        memo.bitcount += 1
+        rgenop = jitstate.curbuilder.rgenop
+        vrti = rvirtualizable.VirtualRTI(rgenop, bitmask)
+        vrti.devirtualize = typedesc.devirtualize
+        memo.containers[self] = vrti
+
+        builder = jitstate.curbuilder
+        place = builder.alloc_frame_place(typedesc.ptrkind,
+                                          typedesc.gv_null)
+        gv_forced = builder.genop_absorb_place(typedesc.ptrkind, place)
+        vrti.forced_place = place
+
+        vars_gv = memo.framevars_gv
+        varindexes = vrti.varindexes
+        vrtis = vrti.vrtis
+        j = -1
+        for box in self.item_boxes:
+            if box.genvar:
+                varindexes.append(memo.frameindex)
+                memo.frameindex += 1
+                vars_gv.append(box.genvar)
+            else:
+                varindexes.append(j)
+                assert isinstance(box, rvalue.PtrRedBox)
+                content = box.content
+                assert content.allowed_in_virtualizable
+                vrtis.append(content.make_rti(jitstate, memo))
+                j -= 1
+
+        self.item_boxes.append(rvalue.PtrRedBox(typedesc.ptrkind,
+                                                   gv_forced))
+                
+        return vrti
+
+    def reshape(self, jitstate, shapemask, memo):
+        if self in memo.containers:
+            return
+        typedesc = self.typedesc
+        builder = jitstate.curbuilder        
+        memo.containers[self] = None
+        bitmask = 1<<memo.bitcount
+        memo.bitcount += 1
+
+        boxes = self.item_boxes
+        outside_box = boxes.pop()
+        if bitmask&shapemask:
+            gv_forced = outside_box.genvar
+            memo.forced.append((self, gv_forced))
+            
+        for box in boxes:
+            if not box.genvar:
+                assert isinstance(box, rvalue.PtrRedBox)
+                content = box.content
+                assert content.allowed_in_virtualizable
+                content.reshape(jitstate, shapemask, memo)
+
+
 def oop_newlist(jitstate, oopspecdesc, lengthbox, itembox=None):
     if lengthbox.is_constant():
         length = rvalue.ll_getvalue(lengthbox, lltype.Signed)



More information about the Pypy-commit mailing list