[pypy-commit] pypy vref-copy: start hacking on vref-getfield

fijal noreply at buildbot.pypy.org
Tue Aug 21 17:31:16 CEST 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: vref-copy
Changeset: r56775:0235d65362bf
Date: 2012-08-21 17:30 +0200
http://bitbucket.org/pypy/pypy/changeset/0235d65362bf/

Log:	start hacking on vref-getfield

diff --git a/pypy/jit/metainterp/test/test_virtualref.py b/pypy/jit/metainterp/test/test_virtualref.py
--- a/pypy/jit/metainterp/test/test_virtualref.py
+++ b/pypy/jit/metainterp/test/test_virtualref.py
@@ -654,6 +654,30 @@
         res = self.meta_interp(f, [10])
         assert res == 0
 
+    def test_vref_getfield(self):
+        driver = JitDriver(greens = [], reds = ['n', 's'])
+
+        class X(object):
+            def __init__(self, x):
+                self.x = x
+
+        @dont_look_inside
+        def residual(vref):
+            return vref.getfield('x')
+
+        def f(n):
+            s = 0
+            while n > 0:
+                driver.jit_merge_point(n=n, s=s)
+                x = X(1)
+                v = virtual_ref(x)
+                s += residual(v)
+                virtual_ref_finish(v, x)
+                n -= 1
+            return s
+
+        res = self.meta_interp(f, [10])
+        assert res == 10
 
 class TestLLtype(VRefTests, LLJitMixin):
     pass
diff --git a/pypy/jit/metainterp/virtualref.py b/pypy/jit/metainterp/virtualref.py
--- a/pypy/jit/metainterp/virtualref.py
+++ b/pypy/jit/metainterp/virtualref.py
@@ -36,11 +36,19 @@
     def _freeze_(self):
         return True
 
+    def _find_type_of_virtualref(self):
+        # XXX limitation is that we can only have one type
+        for graph in graphs:
+            for block in graph.iterblocks():
+                for op in block.operations:
+
     def replace_force_virtual_with_call(self, graphs):
         # similar to rvirtualizable2.replace_force_virtualizable_with_call().
         c_force_virtual_ptr = None
         c_is_virtual_ptr = None
+        c_getfield_ptrs = {} # fieldname -> function
         force_virtual_count = 0
+        self._find_type_of_virtualref()
         for graph in graphs:
             for block in graph.iterblocks():
                 for op in block.operations:
@@ -60,6 +68,16 @@
                         #
                         op.opname = 'direct_call'
                         op.args = [c_is_virtual_ptr, op.args[0]]
+                    if op.opname == 'jit_vref_getfield':
+                        # get a function for each field
+                        key = op.args[1].value
+                        c_func = c_getfield_ptrs.get(key, None)
+                        if c_func is None:
+                            c_func = self.get_vref_getfield_fnptr(key,
+                                                        op.result.concretetype)
+                            c_getfield_ptrs[key] = c_func
+                        op.opname = 'direct_call'
+                        op.args = [c_func, op.args[0]]
         #
         if c_force_virtual_ptr is not None:
             log("replaced %d 'jit_force_virtual' with %r" % (force_virtual_count,
@@ -137,6 +155,18 @@
             force_virtual_if_necessary)
         return inputconst(lltype.typeOf(funcptr), funcptr)
 
+    def get_vref_getfield_fnptr(self, name, RES_TP):
+        def read_virtual_field(inst):
+            if inst.typeptr != self.jit_virtual_ref_vtable:
+                lltype.cast_ptr(
+                xxx
+            xxx
+        FUNC = lltype.FuncType([rclass.OBJECTPTR], RES_TP)
+        funcptr = self.warmrunnerdesc.helper_func(
+            lltype.Ptr(FUNC),
+            read_virtual_field)
+        return inputconst(lltype.typeOf(funcptr), funcptr)
+
     def get_is_virtual_fnptr(self):
         #
         def is_virtual(inst):
diff --git a/pypy/rlib/_jit_vref.py b/pypy/rlib/_jit_vref.py
--- a/pypy/rlib/_jit_vref.py
+++ b/pypy/rlib/_jit_vref.py
@@ -53,6 +53,7 @@
 
     def specialize_call(self, hop):
         r_generic_object = getinstancerepr(hop.rtyper, None)
+        hop.genop('jit_record_vref', [hop.args_v[0]], resulttype=lltype.Void)
         [v] = hop.inputargs(r_generic_object)   # might generate a cast_pointer
         hop.exception_cannot_occur()
         return v
@@ -82,9 +83,7 @@
         hop.exception_cannot_occur()
         v = hop.inputarg(self, arg=0)
         c_name = hop.inputconst(lltype.Void, attr)
-        r_arg = hop.rtyper.getrepr(hop.args_s[0].s_instance)
-        v2 = hop.genop('cast_pointer', [v], resulttype=r_arg)
-        return hop.genop('jit_vref_getfield', [v2, c_name],
+        return hop.genop('jit_vref_getfield', [v, c_name],
                          resulttype = hop.r_result)
 
 from pypy.rpython.ootypesystem.rclass import OBJECT
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -435,6 +435,7 @@
     'jit_force_quasi_immutable': LLOp(canrun=True),
     'jit_record_known_class'  : LLOp(canrun=True),
     'jit_vref_getfield' : LLOp(canrun=True),
+    'jit_record_vref': LLOp(canrun=True),
     'get_exception_addr':   LLOp(),
     'get_exc_value_addr':   LLOp(),
     'do_malloc_fixedsize_clear':LLOp(canmallocgc=True),
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -558,7 +558,8 @@
     return x
 
 def op_jit_vref_getfield(x, field):
-    return getattr(x, 'inst_' + field)
+    # XXX is this even a correct hack?
+    return getattr(x._obj._parentstructure(), 'inst_' + field)
 
 def op_jit_is_virtual(x):
     return False


More information about the pypy-commit mailing list