[pypy-svn] r60146 - in pypy/branch/oo-jit/pypy: jit/hintannotator rpython/lltypesystem rpython/lltypesystem/test

arigo at codespeak.net arigo at codespeak.net
Wed Nov 26 10:49:35 CET 2008


Author: arigo
Date: Wed Nov 26 10:49:33 2008
New Revision: 60146

Added:
   pypy/branch/oo-jit/pypy/rpython/lltypesystem/rvirtualizable2.py   (contents, props changed)
   pypy/branch/oo-jit/pypy/rpython/lltypesystem/test/test_rvirtualizable2.py   (contents, props changed)
Modified:
   pypy/branch/oo-jit/pypy/jit/hintannotator/model.py
   pypy/branch/oo-jit/pypy/rpython/lltypesystem/lloperation.py
   pypy/branch/oo-jit/pypy/rpython/lltypesystem/opimpl.py
   pypy/branch/oo-jit/pypy/rpython/lltypesystem/rclass.py
Log:
Add the "_virtualizable2_" flag, with is a marker for
classes like "_virtualizable_" but requiring the new
layout of special instances required by pyjitpl.


Modified: pypy/branch/oo-jit/pypy/jit/hintannotator/model.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/hintannotator/model.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/hintannotator/model.py	Wed Nov 26 10:49:33 2008
@@ -39,6 +39,7 @@
                       subclassof
                       instanceof
                       oostring
+                      promote_virtualizable
                       """.split()
 
 BINARY_OPERATIONS = """int_add int_sub int_mul int_mod int_and int_rshift
@@ -523,6 +524,9 @@
     def jit_marker(*args_hs):
         pass
 
+    def promote_virtualizable(*args_hs):
+        pass
+
 class __extend__(SomeLLAbstractConstant):
 
     def same_as(hs_c1):

Modified: pypy/branch/oo-jit/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/oo-jit/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/branch/oo-jit/pypy/rpython/lltypesystem/lloperation.py	Wed Nov 26 10:49:33 2008
@@ -380,6 +380,7 @@
 
     'call_boehm_gc_alloc':  LLOp(canraise=(MemoryError,)),
     'jit_marker':           LLOp(),
+    'promote_virtualizable':LLOp(canrun=True),
 
     # __________ GC operations __________
 

Modified: pypy/branch/oo-jit/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/oo-jit/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/branch/oo-jit/pypy/rpython/lltypesystem/opimpl.py	Wed Nov 26 10:49:33 2008
@@ -514,6 +514,9 @@
     assert type(f) is float
     return ovfcheck(int(f))
 
+def op_promote_virtualizable(object, fieldname):
+    pass
+
 # ____________________________________________________________
 
 def get_op_impl(opname):

Modified: pypy/branch/oo-jit/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/branch/oo-jit/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/branch/oo-jit/pypy/rpython/lltypesystem/rclass.py	Wed Nov 26 10:49:33 2008
@@ -599,17 +599,25 @@
     if classdef is None:
         unboxed = []
         virtualizable = False
+        virtualizable2 = False
     else:
         unboxed = [subdef for subdef in classdef.getallsubdefs()
                           if subdef.classdesc.pyobj is not None and
                              issubclass(subdef.classdesc.pyobj, UnboxedValue)]
         virtualizable = classdef.classdesc.read_attribute('_virtualizable_',
                                                           Constant(False)).value
+        virtualizable2 = classdef.classdesc.read_attribute('_virtualizable2_',
+                                                           Constant(False)).value
     if virtualizable:
         assert len(unboxed) == 0
         assert gcflavor == 'gc'
         from pypy.rpython.lltypesystem import rvirtualizable
         return rvirtualizable.VirtualizableInstanceRepr(rtyper, classdef)
+    elif virtualizable2:
+        assert len(unboxed) == 0
+        assert gcflavor == 'gc'
+        from pypy.rpython.lltypesystem import rvirtualizable2
+        return rvirtualizable2.Virtualizable2InstanceRepr(rtyper, classdef)
     elif len(unboxed) == 0:
         return InstanceRepr(rtyper, classdef, gcflavor)
     else:

Added: pypy/branch/oo-jit/pypy/rpython/lltypesystem/rvirtualizable2.py
==============================================================================
--- (empty file)
+++ pypy/branch/oo-jit/pypy/rpython/lltypesystem/rvirtualizable2.py	Wed Nov 26 10:49:33 2008
@@ -0,0 +1,127 @@
+import py
+from pypy.rpython.rmodel import inputconst
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem.rclass import InstanceRepr
+from pypy.rpython.lltypesystem.rvirtualizable import VABLERTIPTR
+
+
+class VirtualizableAccessor(object):
+
+    def initialize(self, STRUCT, redirected_fields, PARENT=None):
+        self.STRUCT = STRUCT
+        self.redirected_fields = redirected_fields
+        self.subaccessors = []
+        if PARENT is None:
+            self.parent = None
+        else:
+            self.parent = PARENT.access
+            self.parent.subaccessors.append(self)
+
+    def __repr__(self):
+        return '<VirtualizableAccessor for %s>' % getattr(self, 'STRUCT', '?')
+
+    def __getattr__(self, name):
+        if name.startswith('getset') and 'getsets' not in self.__dict__:
+            self.prepare_getsets()
+            return getattr(self, name)
+        else:
+            raise AttributeError("%s object has no attribute %r" % (
+                self.__class__.__name__, name))
+
+    def prepare_getsets(self):
+        self.getsets = {}
+        STRUCT = self.STRUCT
+        for fieldname in self.redirected_fields:
+            FIELDTYPE = getattr(STRUCT, fieldname)
+            GETTER = lltype.FuncType([lltype.Ptr(STRUCT)], FIELDTYPE)
+            SETTER = lltype.FuncType([lltype.Ptr(STRUCT), FIELDTYPE],
+                                     lltype.Void)
+            VABLE_GETSET = lltype.Struct('vable_getset',
+                                         ('get', lltype.Ptr(GETTER)),
+                                         ('set', lltype.Ptr(SETTER)),
+                                         hints={'immutable': True})
+            getset = lltype.malloc(VABLE_GETSET, flavor='raw', zero=False)
+            # as long as no valid pointer has been put in the structure
+            # by the JIT, accessing the fields should raise, in order
+            # to prevent constant-folding
+            py.test.raises(lltype.UninitializedMemoryAccess, "getset.get")
+            py.test.raises(lltype.UninitializedMemoryAccess, "getset.set")
+            self.getsets[fieldname] = getset
+            setattr(self, 'getset_' + fieldname, getset)
+
+    def _freeze_(self):
+        return True
+
+
+class Virtualizable2InstanceRepr(InstanceRepr):
+
+    def __init__(self, rtyper, classdef):
+        InstanceRepr.__init__(self, rtyper, classdef)
+        classdesc = classdef.classdesc
+        if '_virtualizable2_' in classdesc.classdict:
+            basedesc = classdesc.basedesc
+            assert basedesc is None or basedesc.lookup('_virtualizable2_') is None
+            self.top_of_virtualizable_hierarchy = True
+        else:
+            self.top_of_virtualizable_hierarchy = False
+        self.accessor = VirtualizableAccessor()
+
+    def _setup_repr(self):
+        llfields = []
+        if self.top_of_virtualizable_hierarchy:
+            llfields.append(('vable_base', llmemory.Address))
+            llfields.append(('vable_rti', VABLERTIPTR))
+        InstanceRepr._setup_repr(self, llfields,
+                                 hints = {'virtualizable2': True},
+                                 adtmeths = {'access': self.accessor})
+        if self.top_of_virtualizable_hierarchy:
+            my_redirected_fields = []
+            for _, (mangled_name, _) in self.fields.items():
+                my_redirected_fields.append(mangled_name)
+            self.my_redirected_fields = dict.fromkeys(my_redirected_fields)
+            self.accessor.initialize(self.object_type, my_redirected_fields)
+        else:
+            xxx
+
+    def set_vable(self, llops, vinst, force_cast=False):
+        if self.top_of_virtualizable_hierarchy:
+            if force_cast:
+                vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
+            cname = inputconst(lltype.Void, 'vable_rti')
+            vvalue = inputconst(VABLERTIPTR, lltype.nullptr(VABLERTIPTR.TO))
+            llops.genop('setfield', [vinst, cname, vvalue])
+        else:
+            self.rbase.set_vable(llops, vinst, force_cast=True)
+
+    def new_instance(self, llops, classcallhop=None):
+        vptr = InstanceRepr.new_instance(self, llops, classcallhop)
+        self.set_vable(llops, vptr)
+        return vptr
+
+    def getfield(self, vinst, attr, llops, force_cast=False, flags={}):
+        """Read the given attribute (or __class__ for the type) of 'vinst'."""
+        if not flags.get('access_directly') and attr in self.fields:
+            mangled_name, r = self.fields[attr]
+            if mangled_name in self.my_redirected_fields:
+                if force_cast:
+                    vinst = llops.genop('cast_pointer', [vinst],
+                                        resulttype=self)
+                c_name = inputconst(lltype.Void, mangled_name)
+                llops.genop('promote_virtualizable', [vinst, c_name])
+                return llops.genop('getfield', [vinst, c_name], resulttype=r)
+        return InstanceRepr.getfield(self, vinst, attr, llops, force_cast)
+
+    def setfield(self, vinst, attr, vvalue, llops, force_cast=False,
+                 flags={}):
+        """Write the given attribute (or __class__ for the type) of 'vinst'."""
+        if not flags.get('access_directly') and attr in self.fields:
+            mangled_name, r = self.fields[attr]
+            if mangled_name in self.my_redirected_fields:
+                if force_cast:
+                    vinst = llops.genop('cast_pointer', [vinst],
+                                        resulttype=self)
+                c_name = inputconst(lltype.Void, mangled_name)
+                llops.genop('promote_virtualizable', [vinst, c_name])
+                llops.genop('setfield', [vinst, c_name, vvalue])
+                return
+        InstanceRepr.setfield(self, vinst, attr, vvalue, llops, force_cast)

Added: pypy/branch/oo-jit/pypy/rpython/lltypesystem/test/test_rvirtualizable2.py
==============================================================================
--- (empty file)
+++ pypy/branch/oo-jit/pypy/rpython/lltypesystem/test/test_rvirtualizable2.py	Wed Nov 26 10:49:33 2008
@@ -0,0 +1,20 @@
+import py
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.test.test_llinterp import interpret
+
+
+class V(object):
+    _virtualizable2_ = True
+
+    def __init__(self, v):
+        self.v = v
+
+def test_simple():
+    def f(v):
+        vinst = V(v)
+        return vinst, vinst.v
+    res = interpret(f, [42])
+    assert res.item1 == 42
+    res = lltype.normalizeptr(res.item0)
+    assert res.inst_v == 42
+    assert not res.vable_rti



More information about the Pypy-commit mailing list