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

pedronis at codespeak.net pedronis at codespeak.net
Wed Mar 15 17:55:21 CET 2006


Author: pedronis
Date: Wed Mar 15 17:55:19 2006
New Revision: 24399

Modified:
   pypy/dist/pypy/jit/hintrtyper.py
   pypy/dist/pypy/jit/rtimeshift.py
   pypy/dist/pypy/jit/test/test_hint_timeshift.py
Log:
(arre, pedronis)

some support for virtual substrucures. Carry around the topmost parent and an address to the 
substructure.



Modified: pypy/dist/pypy/jit/hintrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/hintrtyper.py	(original)
+++ pypy/dist/pypy/jit/hintrtyper.py	Wed Mar 15 17:55:19 2006
@@ -5,7 +5,7 @@
 from pypy.rpython.rmodel import Repr, inputconst
 from pypy.rpython.rstr import string_repr
 from pypy.rpython.typesystem import TypeSystem
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython import rgenop
 from pypy.jit import hintmodel, rtimeshift
 from pypy.jit import hintcontainer
@@ -144,6 +144,13 @@
         if isinstance(hop.args_r[0], BlueRepr):
             return hop.args_r[0].timeshift_setfield(hop)
         # non virtual case ...
+        raise NotImplementedError
+
+    def translate_op_getsubstruct(self, hop):
+        if isinstance(hop.args_r[0], BlueRepr):
+            return hop.args_r[0].timeshift_getsubstruct(hop)
+        # non virtual case ...
+        raise NotImplementedError
 
     def translate_op_malloc(self, hop):
         r_result = hop.r_result
@@ -212,9 +219,21 @@
         assert isinstance(hs_container.contentdef, hintcontainer.VirtualStructDef)
         vstructdef = hs_container.contentdef
 
-        assert vstructdef.vparent is None
+        # compute reconstruction information up to our top-most parent
+        chain = [vstructdef.T]
+        cur = vstructdef
+        while cur.vparent is not None:
+            for name, fieldvalue in cur.vparent.fields.iteritems():
+                s_field = fieldvalue.s_value
+                if isinstance(s_field, hintmodel.SomeLLAbstractContainer):
+                    if s_field.contentdef is cur:
+                        chain.append((name, cur.vparent.T))
+                        break
+            else:
+                assert False, "can't find ourself in parent"
+            cur = cur.vparent
 
-        key = [hs_container.__class__, vstructdef.T]
+        key = [hs_container.__class__, tuple(chain)]
         for name in vstructdef.names:
             fielditem = vstructdef.fields[name]
             key.append(fielditem)
@@ -260,31 +279,44 @@
         self.original_concretetype = original_concretetype
         self.timeshifter = timeshifter
         self.lowleveltype = timeshifter.r_RedBox.lowleveltype
-        self.CONTENT = lltype.GcForwardReference()
+        if virtualstructdef.vparent is None:
+            self.ENVELOPE = lltype.GcForwardReference()                                 
         self.vstructdef = virtualstructdef        
 
     def fldname(self, name):
-        return "fld_%s" % name
+        return name
 
     def _setup_repr(self):
         field_reprs = {}
-        fields = [("tag" ,rtimeshift.VCONTAINER)]
+        fields = []
         vstructdef = self.vstructdef
         hrtyper = self.timeshifter.hrtyper
+        T = self.original_concretetype.TO
         for name in vstructdef.names:
             fieldvalue = vstructdef.fields[name]
             field_repr = hrtyper.getrepr(fieldvalue.s_value)
             field_reprs[name] = field_repr
-            fields.append((self.fldname(name), field_repr.lowleveltype))
-        self.CONTENT.become(lltype.GcStruct('vstruct', *fields))
+            SUBFIELD = getattr(T, name)
+            if isinstance(SUBFIELD, lltype.Struct):
+                # virtual substructure case
+                field_lltype = field_repr.DATA
+            else:
+                field_lltype = field_repr.lowleveltype
+            fields.append((self.fldname(name), field_lltype))
         self.field_reprs = field_reprs
+        self.DATA = lltype.Struct('vstruct', *fields)
+        if vstructdef.vparent is None:
+            self.ENVELOPE.become(lltype.GcStruct('vstruct_envelope', ('tag', rtimeshift.VCONTAINER),
+                                                                     ('data', self.DATA)))
             
     # helpers
 
     def create(self, hop):
         llops = hop.llops
-        c_CONTENT = inputconst(lltype.Void, self.CONTENT)
-        v_content = hop.genop('malloc', [c_CONTENT], resulttype=lltype.Ptr(self.CONTENT))
+        c_ENVELOPE = inputconst(lltype.Void, self.ENVELOPE)
+        v_envelope = hop.genop('malloc', [c_ENVELOPE], resulttype=lltype.Ptr(self.ENVELOPE))
+        c_data = inputconst(lltype.Void, 'data')
+        v_data = hop.genop('getsubstruct', [v_envelope, c_data], lltype.Ptr(self.DATA))
         for name, field_repr in self.field_reprs.iteritems():
             if isinstance(field_repr, RedRepr):
                 T = field_repr.original_concretetype
@@ -294,13 +326,28 @@
                                                       [s_defl], [c_defl],
                                                       self.timeshifter.s_RedBox)
                 c_name = inputconst(lltype.Void, self.fldname(name))
-                hop.genop('setfield', [v_content, c_name, v_field])            
+                hop.genop('setfield', [v_data, c_name, v_field])            
         VCONTPTR = lltype.Ptr(rtimeshift.VCONTAINER)
-        v_content = hop.genop('cast_pointer', [v_content],
-                              resulttype=VCONTPTR)
+        v_envelope = hop.genop('cast_pointer', [v_envelope],
+                               resulttype=VCONTPTR)
+        v_content = hop.genop('cast_ptr_to_adr', [v_data], resulttype=llmemory.Address)
         return llops.genmixlevelhelpercall(rtimeshift.ContainerRedBox.ll_make_container_box,
-                                           [annmodel.SomePtr(VCONTPTR)], [v_content],
+                                           [annmodel.SomePtr(VCONTPTR), annmodel.SomeAddress()],
+                                           [v_envelope,                 v_content],
                                            self.timeshifter.s_RedBox)
+
+    def getdata(self, hop, v_box):
+        llops = hop.llops
+        rtyper = self.timeshifter.rtyper
+        DATAPTR = lltype.Ptr(self.DATA)
+        v_data_addr = llops.genmixlevelhelpercall(rtimeshift.ll_getcontent,
+                                                  [self.timeshifter.s_RedBox],
+                                                  [v_box],
+                                                  annmodel.SomeAddress())
+        # cannot do this inside ll_getcontent because DATAPTR parts can be setup only later :(
+        v_data = hop.genop('cast_adr_to_ptr', [v_data_addr], resulttype=DATAPTR)
+        return v_data
+
         
     def timeshift_setfield(self, hop):
         llops = hop.llops        
@@ -309,15 +356,9 @@
         field_repr = self.field_reprs[name]
         v_box = hop.inputarg(self, arg=0)
         v_value = hop.inputarg(field_repr, arg=2)
-        VCONTPTR = lltype.Ptr(rtimeshift.VCONTAINER)
-        v_content = llops.genmixlevelhelpercall(rtimeshift.ll_getcontent,
-                                                [self.timeshifter.s_RedBox], [v_box],
-                                                annmodel.SomePtr(VCONTPTR))
-        v_content = hop.genop('cast_pointer', [v_content],
-                              resulttype=lltype.Ptr(self.CONTENT))
+        v_data = self.getdata(hop, v_box)
         c_name = inputconst(lltype.Void, self.fldname(name))
-        hop.genop('setfield', [v_content, c_name, v_value])
-
+        hop.genop('setfield', [v_data, c_name, v_value])
 
     def timeshift_getfield(self, hop):
         llops = hop.llops        
@@ -325,16 +366,29 @@
         name = hop.args_s[1].const
         field_repr = self.field_reprs[name]
         v_box = hop.inputarg(self, arg=0)
-        VCONTPTR = lltype.Ptr(rtimeshift.VCONTAINER)
-        v_content = llops.genmixlevelhelpercall(rtimeshift.ll_getcontent,
-                                                [self.timeshifter.s_RedBox], [v_box],
-                                                annmodel.SomePtr(VCONTPTR))
-        v_content = hop.genop('cast_pointer', [v_content],
-                              resulttype=lltype.Ptr(self.CONTENT))
+        v_data = self.getdata(hop, v_box)
         c_name = inputconst(lltype.Void, self.fldname(name))
-        return hop.genop('getfield', [v_content, c_name],
+        return hop.genop('getfield', [v_data, c_name],
                          resulttype=field_repr.lowleveltype)
 
+    def timeshift_getsubstruct(self, hop):
+        llops = hop.llops        
+        assert hop.args_s[1].is_constant()
+        name = hop.args_s[1].const
+        field_repr = self.field_reprs[name]
+        v_box = hop.inputarg(self, arg=0)
+        v_data = self.getdata(hop, v_box)
+        c_name = inputconst(lltype.Void, self.fldname(name))
+        NEWDATAPTR = lltype.Ptr(field_repr.DATA)
+        v_newdata = hop.genop('getsubstruct', [v_data, c_name],
+                              resulttype=NEWDATAPTR)
+        v_content = hop.genop('cast_ptr_to_adr', [v_newdata], resulttype=llmemory.Address)
+        return llops.genmixlevelhelpercall(rtimeshift.ContainerRedBox.ll_make_subcontainer_box,
+                                           [self.timeshifter.s_RedBox, annmodel.SomeAddress()],
+                                           [v_box,                     v_content],
+                                           self.timeshifter.s_RedBox)
+        
+
 
 class GreenRepr(Repr):
     def __init__(self, lowleveltype):

Modified: pypy/dist/pypy/jit/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/rtimeshift.py	(original)
+++ pypy/dist/pypy/jit/rtimeshift.py	Wed Mar 15 17:55:19 2006
@@ -44,19 +44,29 @@
 VCONTAINER = lltype.GcStruct("vcontainer")
 
 class ContainerRedBox(RedBox):
-    def __init__(self, content):
-        self.content = content
+    def __init__(self, envelope, content_addr):
+        self.envelope = envelope
+        self.content_addr = content_addr
 
     def getgenvar(self): # not support at the moment
         raise RuntimeError("cannot force virtual containers")
 
-    def ll_make_container_box(content):
-        return ContainerRedBox(content)
+    def ll_make_container_box(envelope, content_addr):
+        return ContainerRedBox(envelope, content_addr)
     ll_make_container_box = staticmethod(ll_make_container_box)
 
+    def ll_make_subcontainer_box(box, content_addr):
+        return ContainerRedBox(box.envelope, content_addr)
+    ll_make_subcontainer_box = staticmethod(ll_make_subcontainer_box)
+
+
+def ll_getenvelope(box):
+    assert isinstance(box, ContainerRedBox)
+    return box.envelope
+
 def ll_getcontent(box):
     assert isinstance(box, ContainerRedBox)
-    return box.content
+    return box.content_addr
 
 class ConstRedBox(RedBox):
     "A red box that contains a run-time constant."

Modified: pypy/dist/pypy/jit/test/test_hint_timeshift.py
==============================================================================
--- pypy/dist/pypy/jit/test/test_hint_timeshift.py	(original)
+++ pypy/dist/pypy/jit/test/test_hint_timeshift.py	Wed Mar 15 17:55:19 2006
@@ -301,3 +301,18 @@
     assert res == 3
     assert insns == {}
 
+def test_inlined_substructure():
+    S = lltype.Struct('S', ('n', lltype.Signed))
+    T = lltype.GcStruct('T', ('s', S), ('n', lltype.Float))
+    def ll_function(k):
+        t = lltype.malloc(T)
+        t.s.n = k
+        l = t.s.n
+        return l
+    insns, res = timeshift(ll_function, [7], [])
+    assert res == 7
+    assert insns == {}
+
+    insns, res = timeshift(ll_function, [7], [0])
+    assert res == 7
+    assert insns == {}    



More information about the Pypy-commit mailing list