[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