[pypy-svn] r37158 - in pypy/dist/pypy: jit/timeshifter jit/timeshifter/test rpython/lltypesystem

pedronis at codespeak.net pedronis at codespeak.net
Mon Jan 22 20:41:50 CET 2007


Author: pedronis
Date: Mon Jan 22 20:41:46 2007
New Revision: 37158

Modified:
   pypy/dist/pypy/jit/timeshifter/hrtyper.py
   pypy/dist/pypy/jit/timeshifter/rcontainer.py
   pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
   pypy/dist/pypy/rpython/lltypesystem/rclass.py
   pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py
Log:
(arre, pedronis)  first test using a virtualizable declared class passing through rtyping and timeshifting correctly.



Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py	Mon Jan 22 20:41:46 2007
@@ -1644,12 +1644,13 @@
             RedRepr.build_portal_arg_helpers(self)
             return
 
+        typedesc = self.gettypedesc()
+        names = unrolling_iterable([(fielddesc.fieldname, j)
+                                    for (fielddesc, j) in typedesc.redirected_fielddescs])
 
-        names = unrolling_iterable([name for name in T._names
-                                    if name not in rcontainer.VABLEFIELDS])
         def collect_residual_args(v): 
             t = (v,)
-            for name in names:
+            for name, _ in names:
                 t = t + (getattr(v, name),) # xxx need to use access ?
             return t
         self.collect_residual_args = collect_residual_args
@@ -1657,26 +1658,22 @@
         TYPE = self.original_concretetype
         kind = self.hrtyper.RGenOp.kindToken(TYPE)
         boxcls = rvalue.ll_redboxcls(TYPE)
-
-        typedesc = self.gettypedesc()
         
         def make_arg_redbox(jitstate, inputargs_gv, i):
             box = typedesc.factory()
             jitstate.add_virtualizable(box)
-            j = rcontainer.NVABLEFIELDS
             content = box.content
             assert isinstance(content, rcontainer.VirtualStruct)
             content_boxes = content.content_boxes
             gv_outside = inputargs_gv[i]
             i += 1
-            for name in names:
+            for name, j in names:
                 content_boxes[j].genvar = inputargs_gv[i]
-                j = j + 1
                 i += 1
-            content_boxes[j].genvar = gv_outside
+            content_boxes[-1].genvar = gv_outside
             return box
         self.make_arg_redbox = make_arg_redbox
-        make_arg_redbox.consumes = len(T._names)-rcontainer.NVABLEFIELDS+1
+        make_arg_redbox.consumes = len(typedesc.redirected_fielddescs)+1
 
     def gettypedesc(self):
         if self.typedesc is None:
@@ -1697,10 +1694,9 @@
         T = self.original_concretetype.TO
         if T._hints.get('virtualizable', False):
             getredrepr = self.hrtyper.getredrepr
-            for name in T._names:
-                if name in rcontainer.VABLEFIELDS:
-                    continue
-                FIELDTYPE = getattr(T, name)
+            typedesc = self.gettypedesc()
+            for fielddesc, _ in typedesc.redirected_fielddescs:
+                FIELDTYPE = getattr(T, fielddesc.fieldname)
                 argtypes += getredrepr(FIELDTYPE).residual_argtypes()
         return argtypes
 

Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py	(original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py	Mon Jan 22 20:41:46 2007
@@ -38,10 +38,7 @@
         raise NotImplementedError
 
 # ____________________________________________________________
-
-VABLEFIELDS = ('vable_base', 'vable_info', 'vable_access')
-NVABLEFIELDS = len(VABLEFIELDS)
-VABLEINFOPTR = base_ptr_lltype()
+from pypy.rpython.lltypesystem.rvirtualizable import VABLEINFOPTR
 
 class StructTypeDesc(object):
     __metaclass__ = cachedtype
@@ -116,6 +113,7 @@
             self.info_desc = self.getfielddesc('vable_info')
             self.access_desc = self.getfielddesc('vable_access')
             ACCESS = TYPE.vable_access.TO
+            redirected_fields = ACCESS.redirected_fields
             access = lltype.malloc(ACCESS, immortal=True)
             self.gv_access = RGenOp.constPrebuiltGlobal(access)
             annhelper = hrtyper.annhelper
@@ -129,8 +127,14 @@
                                                  struc.vable_base, j)
                 return get_field
             s_structtype = annmodel.lltype_to_annotation(self.PTRTYPE)
-            for i in range(NVABLEFIELDS, len(fielddescs)):
-                fielddesc = fielddescs[i]        
+            self.redirected_fielddescs = redirected_fieldescs = []
+            i = -1
+            for fielddesc in fielddescs:
+                i += 1
+                name = fielddesc.fieldname
+                if name not in redirected_fields:
+                   continue
+                redirected_fieldescs.append((fielddesc, i))
                 get_field = make_get_field(fielddesc, j)
                 j += 1
                 s_lltype = annmodel.lltype_to_annotation(fielddesc.RESTYPE)
@@ -138,7 +142,6 @@
                                                           [s_structtype],
                                                           s_lltype,
                                                           needtype = True)
-                name = fielddesc.fieldname
                 setattr(access, 'get_'+name, get_field_ptr)
         else:
             self.VStructCls = VirtualStruct
@@ -564,21 +567,19 @@
         return gv_outside
 
     def store_back(self, jitstate):
-        fielddescs = self.typedesc.fielddescs
+        typedesc = self.typedesc
         boxes = self.content_boxes
         gv_outside = boxes[-1].genvar
-        for i in range(NVABLEFIELDS, len(fielddescs)):
-            fielddesc = fielddescs[i]
+        for fielddesc, i in typedesc.redirected_fielddescs:
             box = boxes[i]
             fielddesc.generate_set(jitstate, gv_outside,
                                    box.getgenvar(jitstate))
 
     def load_from(self, jitstate, gv_outside):
-        fielddescs = self.typedesc.fielddescs
+        typedesc = self.typedesc
         boxes = self.content_boxes
         boxes[-1].genvar = gv_outside
-        for i in range(NVABLEFIELDS, len(fielddescs)):
-            fielddesc = fielddescs[i]
+        for fielddesc, i in typedesc.redirected_fielddescs:
             boxes[i] = fielddesc.generate_get(jitstate, gv_outside)
         jitstate.add_virtualizable(self.ownbox)
 
@@ -603,7 +604,7 @@
                                [gv_zeromask])
             memo.containers[self] = gv_vinfo
             
-            for i in range(NVABLEFIELDS, n-1):
+            for _, i in typedesc.redirected_fielddescs:
                 box = boxes[i]
                 if box.genvar:
                     vars_gv.append(box.genvar)
@@ -664,17 +665,18 @@
             info_token = info_desc.fieldtoken
             gv_vinfo = builder.genop_getfield(info_token, gv_outside)            
             boxes = self.content_boxes
-            n = len(boxes)
-            for i in range(NVABLEFIELDS, n-1):
+            j = 0
+            for _, i in typedesc.redirected_fielddescs:
                 box = boxes[i]
                 if not box.genvar:
                     gv_vinfo1 = builder.genop_call(typedesc.vinfo_get_vinfo_token,
                                                    typedesc.gv_vinfo_get_vinfo_ptr,
-                                                   [gv_vinfo, builder.rgenop.genconst(i-NVABLEFIELDS)])
+                                                   [gv_vinfo, builder.rgenop.genconst(j)])
                     assert isinstance(box, rvalue.PtrRedBox)
                     content = box.content
                     assert isinstance(content, VirtualStruct) # xxx for now
                     content.reshape(jitstate, gv_vinfo1, shapemask, memo)
+                j += 1
                     
 # ____________________________________________________________
 

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	Mon Jan 22 20:41:46 2007
@@ -26,6 +26,7 @@
                           ('get_y', GETTER(XY)),
                           ('set_y', SETTER(XY)),
                           hints = {'immutable': True},
+                          adtmeths = {'redirected_fields': ('x', 'y')}
                           )
 
 
@@ -35,6 +36,7 @@
                           ('get_p', PGETTER(XP)),
                           ('set_p', PSETTER(XP)),
                           hints = {'immutable': True},
+                          adtmeths = {'redirected_fields': ('x', 'p')}
                           )
 
 XY.become(lltype.GcStruct('xy',
@@ -68,6 +70,7 @@
                           ('get_q', PGETTER(PQ)),
                           ('set_q', PSETTER(PQ)),
                           hints = {'immutable': True},
+                          adtmeths = {'redirected_fields': ('p', 'q')}
                           )
 
 PQ.become(lltype.GcStruct('pq',
@@ -82,9 +85,9 @@
 E3 = lltype.GcStruct('e', ('pq', lltype.Ptr(PQ)),
                          ('w',  lltype.Signed))
 
-class TestVirtualizable(PortalTest):
+class TestVirtualizableExplict(PortalTest):
 
-    def test_simple_explicit(self):
+    def test_simple(self):
    
         def f(xy):
             xy_access = xy.vable_access
@@ -114,7 +117,7 @@
         assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
                 [lltype.Ptr(XY), lltype.Signed, lltype.Signed])
 
-    def test_simple_explicit_set(self):
+    def test_simple_set(self):
    
         def f(xy):
             xy_access = xy.vable_access
@@ -149,7 +152,7 @@
         assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
                 [lltype.Ptr(XY), lltype.Signed, lltype.Signed])
 
-    def test_explicit_set_effect(self):
+    def test_set_effect(self):
    
         def f(xy):
             xy_access = xy.vable_access
@@ -185,7 +188,7 @@
         assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
                 [lltype.Ptr(XY), lltype.Signed, lltype.Signed])
 
-    def test_simple_explicit_escape(self):
+    def test_simple_escape(self):
    
         def f(e, xy):
             xy_access = xy.vable_access
@@ -213,7 +216,7 @@
         assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
                 [lltype.Ptr(E), lltype.Ptr(XY), lltype.Signed, lltype.Signed])
 
-    def test_simple_explicit_return_it(self):
+    def test_simple_return_it(self):
         def f(which, xy1, xy2):
             xy1_access = xy1.vable_access
             if xy1_access:
@@ -248,7 +251,7 @@
         assert res == 23
         self.check_insns(getfield=0)
 
-    def test_simple_explicit_construct_no_escape(self):
+    def test_simple_construct_no_escape(self):
    
         def f(x, y):
             xy = lltype.malloc(XY)
@@ -274,7 +277,7 @@
         assert res == 42
         self.check_insns(getfield=0)
 
-    def test_simple_explicit_construct_escape(self):
+    def test_simple_construct_escape(self):
    
         def f(x, y):
             xy = lltype.malloc(XY)
@@ -301,7 +304,7 @@
         assert res == 42
         self.check_insns(getfield=0)
 
-    def test_simple_with_struct_explicit(self):
+    def test_simple_with_struct(self):
    
         def f(xp):
             xp_access = xp.vable_access
@@ -331,7 +334,7 @@
         assert res == 42
         self.check_insns(getfield=2)    
 
-    def test_simple_with_setting_struct_explicit(self):
+    def test_simple_with_setting_struct(self):
    
         def f(xp, s):
             xp_access = xp.vable_access
@@ -366,7 +369,7 @@
         assert res == 42
         self.check_insns(getfield=3)
 
-    def test_simple_with_setting_new_struct_explicit(self):
+    def test_simple_with_setting_new_struct(self):
    
         def f(xp, a, b):
             s = lltype.malloc(S)
@@ -402,7 +405,7 @@
         self.check_insns(getfield=2, malloc=1)
 
 
-    def test_simple_constr_with_setting_new_struct_explicit(self):
+    def test_simple_constr_with_setting_new_struct(self):
    
         def f(x, a, b):
             xp = lltype.malloc(XP)
@@ -437,7 +440,7 @@
         assert res == 42
         self.check_insns(getfield=0, malloc=2)
 
-    def test_simple_explicit_read(self):
+    def test_simple_read(self):
    
         def f(e):
             xy = e.xy
@@ -462,7 +465,7 @@
         assert res == 63
         self.check_insns(getfield=3)
 
-    def test_simple_explicit_escape_through_vstruct(self):
+    def test_simple_escape_through_vstruct(self):
    
         def f(x, y):
             xy = lltype.malloc(XY)
@@ -492,7 +495,7 @@
         assert res == 42
         self.check_insns(getfield=0, malloc=2)
 
-    def test_explicit_late_residual_red_call(self):
+    def test_late_residual_red_call(self):
         def g(e):
             xy = e.xy
             xy_access = xy.vable_access
@@ -543,7 +546,7 @@
                                          policy=StopAtGPolicy())
         assert res == 42
 
-    def test_explicit_residual_red_call(self):
+    def test_residual_red_call(self):
         
         def g(e):
             xy = e.xy
@@ -595,7 +598,7 @@
                                          policy=StopAtGPolicy())
         assert res == 42
 
-    def test_explicit_force_in_residual_red_call(self):
+    def test_force_in_residual_red_call(self):
 
         def g(e):
             xp = e.xp
@@ -663,7 +666,7 @@
                                          policy=StopAtGPolicy())
         assert res == 42
 
-    def test_explicit_force_multiple_reads_residual_red_call(self):
+    def test_force_multiple_reads_residual_red_call(self):
         def get_p(xp):
             xp_access = xp.vable_access
             if xp_access:
@@ -729,7 +732,7 @@
         assert res == 1
 
 
-    def test_explicit_force_unaliased_residual_red_call(self):
+    def test_force_unaliased_residual_red_call(self):
         def get_p(pq):
             pq_access = pq.vable_access
             if pq_access:
@@ -799,7 +802,7 @@
                                          policy=StopAtGPolicy())
         assert res == 1
 
-    def test_explicit_force_aliased_residual_red_call(self):
+    def test_force_aliased_residual_red_call(self):
         def get_p(pq):
             pq_access = pq.vable_access
             if pq_access:
@@ -866,7 +869,7 @@
                                          policy=StopAtGPolicy())
         assert res == 1
 
-    def test_explicit_force_in_residual_red_call_with_more_use(self):
+    def test_force_in_residual_red_call_with_more_use(self):
         def g(e):
             xp = e.xp
             xp_access = xp.vable_access
@@ -934,3 +937,26 @@
         res = self.timeshift_from_portal(main, f, [2, 20, 10],
                                          policy=StopAtGPolicy())
         assert res == 42 + 140 + 10
+
+
+class TestVirtualizableImplicit(PortalTest):
+
+    def test_simple(self):
+
+        class XY(object):
+            _virtualizable_ = True
+            
+            def __init__(self, x, y):
+                self.x = x
+                self.y = y
+   
+        def f(xy):
+            return xy.x+xy.y
+
+        def main(x, y):
+            xy = XY(x, y)
+            return f(xy)
+
+        res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
+        assert res == 42
+        self.check_insns(getfield=0)

Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rclass.py	Mon Jan 22 20:41:46 2007
@@ -314,7 +314,7 @@
         self.lowleveltype = Ptr(self.object_type)
         self.gcflavor = gcflavor
 
-    def _setup_repr(self, llfields=None, adtmeths=None):
+    def _setup_repr(self, llfields=None, hints=None, adtmeths=None):
         # NOTE: don't store mutable objects like the dicts below on 'self'
         #       before they are fully built, to avoid strange bugs in case
         #       of recursion where other code would uses these
@@ -355,8 +355,11 @@
             MkStruct = lltype.STRUCT_BY_FLAVOR[LLFLAVOR[self.gcflavor]]
             if adtmeths is None:
                 adtmeths = {}
+            if hints is None:
+                hints = {}
             object_type = MkStruct(self.classdef.name,
                                    ('super', self.rbase.object_type),
+                                   hints=hints,
                                    adtmeths=adtmeths,
                                    *llfields)
             self.object_type.become(object_type)

Modified: pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rvirtualizable.py	Mon Jan 22 20:41:46 2007
@@ -1,9 +1,11 @@
 from pypy.rpython.error import TyperError
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.rmodel import inputconst
-from pypy.rpython.lltypesystem.rclass import InstanceRepr
+from pypy.rpython.lltypesystem.rclass import OBJECTPTR, InstanceRepr
 from pypy.rpython.annlowlevel import cachedtype
 
+VABLEINFOPTR = OBJECTPTR
+
 class VirtualizableInstanceRepr(InstanceRepr):
 
     def __init__(self, rtyper, classdef):
@@ -21,9 +23,12 @@
         llfields = []
         ACCESS = lltype.ForwardReference()
         if self.top_of_virtualizable_hierarchy:
+            llfields.append(('vable_base',   llmemory.Address))
+            llfields.append(('vable_info',   VABLEINFOPTR))
             llfields.append(('vable_access', lltype.Ptr(ACCESS)))
         InstanceRepr._setup_repr(self, llfields,
-                                 adtmeths={'ACCESS': ACCESS})
+                                 hints = {'virtualizable': True},
+                                 adtmeths = {'ACCESS': ACCESS})
         rbase = self.rbase
         accessors = []
         if self.top_of_virtualizable_hierarchy:
@@ -35,13 +40,18 @@
             accessors.append(('parent', rbase.ACCESS))
         name = self.lowleveltype.TO._name
         SELF = self.lowleveltype
+        redirected_fields = []
         for name, (mangled_name, r) in self.fields.items():
             T = r.lowleveltype
             GETTER = lltype.Ptr(lltype.FuncType([SELF], T))
             SETTER = lltype.Ptr(lltype.FuncType([SELF, T], lltype.Void))
             accessors.append(('get_'+mangled_name, GETTER))
             accessors.append(('set_'+mangled_name, SETTER))
-        ACCESS.become(lltype.Struct(name+'_access', *accessors))
+            redirected_fields.append(mangled_name)
+        ACCESS.become(lltype.Struct(name+'_access',
+                                    hints = {'immutable': True},
+                                    adtmeths = {'redirected_fields': tuple(redirected_fields)},
+                                    *accessors))
                                     
         self.ACCESS = ACCESS
 
@@ -55,7 +65,9 @@
         if self.top_of_virtualizable_hierarchy:
             if force_cast:
                 vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
-            for name, llvalue in (('access', lltype.nullptr(self.ACCESS)),):
+            for name, llvalue in (('access', lltype.nullptr(self.ACCESS)),
+                                  ('base',   llmemory.NULL),
+                                  ('info',   lltype.nullptr(VABLEINFOPTR.TO))):
                 cname = inputconst(lltype.Void, 'vable_'+name)
                 vvalue = inputconst(lltype.typeOf(llvalue), llvalue)
                 llops.genop('setfield', [vinst, cname, vvalue])



More information about the Pypy-commit mailing list