[pypy-commit] pypy ffi-backend: Fix for a corner case in which the heapcache returns a Box

arigo noreply at buildbot.pypy.org
Wed Aug 8 12:09:13 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r56651:9ae67c49c5d3
Date: 2012-08-08 12:08 +0200
http://bitbucket.org/pypy/pypy/changeset/9ae67c49c5d3/

Log:	Fix for a corner case in which the heapcache returns a Box when in
	that particular case we can return a Const.

diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -460,6 +460,13 @@
 
     @arguments("box", "descr", "box")
     def _opimpl_getarrayitem_gc_pure_any(self, arraybox, arraydescr, indexbox):
+        if isinstance(arraybox, ConstPtr) and isinstance(indexbox, ConstInt):
+            # if the arguments are directly constants, bypass the heapcache
+            # completely
+            resbox = executor.execute(self.metainterp.cpu, self.metainterp,
+                                      rop.GETARRAYITEM_GC_PURE, arraydescr,
+                                      arraybox, indexbox)
+            return resbox.constbox()
         return self._do_getarrayitem_gc_any(rop.GETARRAYITEM_GC_PURE, arraybox, arraydescr, indexbox)
 
     opimpl_getarrayitem_gc_i_pure = _opimpl_getarrayitem_gc_pure_any
@@ -571,6 +578,11 @@
 
     @arguments("box", "descr")
     def _opimpl_getfield_gc_pure_any(self, box, fielddescr):
+        if isinstance(box, ConstPtr):
+            # if 'box' is directly a ConstPtr, bypass the heapcache completely
+            resbox = executor.execute(self.metainterp.cpu, self.metainterp,
+                                      rop.GETFIELD_GC_PURE, fielddescr, box)
+            return resbox.constbox()
         return self._opimpl_getfield_gc_any_pureornot(
                 rop.GETFIELD_GC_PURE, box, fielddescr)
     opimpl_getfield_gc_i_pure = _opimpl_getfield_gc_pure_any
diff --git a/pypy/jit/metainterp/test/test_immutable.py b/pypy/jit/metainterp/test/test_immutable.py
--- a/pypy/jit/metainterp/test/test_immutable.py
+++ b/pypy/jit/metainterp/test/test_immutable.py
@@ -124,6 +124,56 @@
                                       getarrayitem_raw_pure=0,
                                       int_mul=0)
 
+    def test_read_on_promoted(self):
+        # this test used to fail because the n = f.n was staying alive
+        # in a box (not a const, as it was read before promote), and
+        # thus the second f.n was returning the same box, although it
+        # could now return a const.
+        class Foo(object):
+            _immutable_fields_ = ['n']
+            def __init__(self, n):
+                self.n = n
+        f1 = Foo(42); f2 = Foo(43)
+        @jit.dont_look_inside
+        def some(m):
+            return [f1, f2][m]
+        @jit.dont_look_inside
+        def do_stuff_with(n):
+            print n
+        def main(m):
+            f = some(m)
+            n = f.n
+            f = jit.hint(f, promote=True)
+            res = f.n * 6
+            do_stuff_with(n)
+            return res
+        res = self.interp_operations(main, [1])
+        assert res == 43 * 6
+        self.check_operations_history(int_mul=0)   # constant-folded
+
+    def test_read_on_promoted_array(self):
+        class Foo(object):
+            _immutable_fields_ = ['lst[*]']
+            def __init__(self, lst):
+                self.lst = lst
+        f1 = Foo([42]); f2 = Foo([43])
+        @jit.dont_look_inside
+        def some(m):
+            return [f1, f2][m]
+        @jit.dont_look_inside
+        def do_stuff_with(n):
+            print n
+        def main(m):
+            f = some(m)
+            n = f.lst[0]
+            f = jit.hint(f, promote=True)
+            res = f.lst[0] * 6
+            do_stuff_with(n)
+            return res
+        res = self.interp_operations(main, [1])
+        assert res == 43 * 6
+        self.check_operations_history(int_mul=0)   # constant-folded
+
 
 class TestLLtypeImmutableFieldsTests(ImmutableFieldsTests, LLJitMixin):
     pass


More information about the pypy-commit mailing list