[pypy-svn] r65887 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Tue Jun 23 19:26:19 CEST 2009


Author: arigo
Date: Tue Jun 23 19:26:17 2009
New Revision: 65887

Modified:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py
Log:
Try to handle generically all cases that raise VirtualizableArrayField
by marking the whole function as residual.


Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py	Tue Jun 23 19:26:17 2009
@@ -271,6 +271,7 @@
             assert not portal, "portal has been hidden!"
             graph = make_calling_stub(codewriter.rtyper, graph)
         self.graph = graph
+        self._tmphack = False
 
     def assemble(self):
         """Assemble the opcodes for self.bytecode."""
@@ -281,9 +282,21 @@
         self.seen_blocks = {}
         self.dont_minimize_variables = 0
         self.pending_exception_handlers = []
-        self.make_bytecode_block(self.graph.startblock)
-        while self.pending_exception_handlers:
-            self.make_exception_handler(self.pending_exception_handlers.pop())
+        try:
+            self.make_bytecode_block(self.graph.startblock)
+            while self.pending_exception_handlers:
+                exc_handler = self.pending_exception_handlers.pop()
+                self.make_exception_handler(exc_handler)
+        except VirtualizableArrayField:
+            # using a virtualizable's array in an unsupported way -- give up
+            # (XXX temporary hack, improve...)
+            if self.portal:
+                raise
+            assert self._tmphack is False
+            self._tmphack = True
+            self.graph = make_calling_stub(self.codewriter.rtyper, self.graph)
+            self.assemble()
+            return
 
         labelpos = {}
         code = assemble(labelpos, self.codewriter.metainterp_sd,
@@ -920,8 +933,10 @@
             self.register_var(op.result)
             return
         # normal case follows
+        arraydescr = self.cpu.arraydescrof(ARRAY)
         self.emit('arraylen_gc')
         self.emit(self.var_position(op.args[0]))
+        self.emit(self.get_position(arraydescr))
         self.register_var(op.result)
 
     def serialize_op_getinteriorarraysize(self, op):
@@ -997,6 +1012,8 @@
 
     def serialize_op_direct_call(self, op):
         kind = self.codewriter.policy.guess_call_kind(op)
+        if self._tmphack:
+            kind = 'residual'
         return getattr(self, 'handle_%s_call' % kind)(op)
 
     def serialize_op_indirect_call(self, op):
@@ -1320,10 +1337,9 @@
             try:
                 return self.var_positions[v]
             except KeyError:
-                if v not in self.vable_array_vars:
-                    raise
-                raise Exception("trying to use a virtualizable's array in "
-                                "an unsupported way")
+                if v in self.vable_array_vars:
+                    raise VirtualizableArrayField
+                raise
 
     def emit(self, *stuff):
         self.assembler.extend(stuff)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py	Tue Jun 23 19:26:17 2009
@@ -226,6 +226,36 @@
         self.check_loops(getfield_gc=0, setfield_gc=0,
                          getarrayitem_gc=0, arraylen_gc=0)
 
+    def test_residual_function(self):
+        myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2'],
+                                virtualizables = ['xy2'])
+        ARRAY = lltype.GcArray(lltype.Signed)
+        def h(xy2):
+            # so far, this function is marked for residual calls because
+            # it does something with a virtualizable's array that is not
+            # just accessing an item
+            return xy2.inst_l2
+        def g(xy2, n):
+            while n > 0:
+                myjitdriver.can_enter_jit(xy2=xy2, n=n)
+                myjitdriver.jit_merge_point(xy2=xy2, n=n)
+                xy2.inst_l1[1] = xy2.inst_l1[1] + len(h(xy2))
+                n -= 1
+        def f(n):
+            xy2 = self.setup2()
+            xy2.inst_x = 2
+            xy2.inst_l1 = lltype.malloc(ARRAY, 2)
+            xy2.inst_l1[0] = 1941309
+            xy2.inst_l1[1] = 2941309
+            xy2.inst_l2 = lltype.malloc(ARRAY, 1)
+            xy2.inst_l2[0] = 10000
+            g(xy2, n)
+            return xy2.inst_l1[1]
+        res = self.meta_interp(f, [18])
+        assert res == 2941309 + 18
+        self.check_loops(getfield_gc=0, setfield_gc=0,
+                         getarrayitem_gc=0, arraylen_gc=1, call=1)
+
     # ------------------------------
 
 



More information about the Pypy-commit mailing list