[pypy-commit] pypy virtual-dicts: make the heapcache a bit smarter about how stuff escaped

alex_gaynor noreply at buildbot.pypy.org
Tue Oct 25 20:33:24 CEST 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: virtual-dicts
Changeset: r48447:d58706c7bdb6
Date: 2011-10-25 14:33 -0400
http://bitbucket.org/pypy/pypy/changeset/d58706c7bdb6/

Log:	make the heapcache a bit smarter about how stuff escaped

diff --git a/pypy/jit/metainterp/heapcache.py b/pypy/jit/metainterp/heapcache.py
--- a/pypy/jit/metainterp/heapcache.py
+++ b/pypy/jit/metainterp/heapcache.py
@@ -41,6 +41,13 @@
                 self.dependencies.setdefault(box, []).append(valuebox)
             else:
                 self._escape(valuebox)
+        elif opnum == rop.SETARRAYITEM_GC:
+            assert len(argboxes) == 3
+            box, indexbox, valuebox = argboxes
+            if self.is_unescaped(box) and self.is_unescaped(valuebox):
+                self.dependencies.setdefault(box, []).append(valuebox)
+            else:
+                self._escape(valuebox)
         # GETFIELD_GC and MARK_OPAQUE_PTR doesn't escape their arguments
         elif opnum != rop.GETFIELD_GC and opnum != rop.MARK_OPAQUE_PTR:
             idx = 0
@@ -60,14 +67,11 @@
                 self._escape(dep)
 
     def clear_caches(self, opnum, descr, argboxes):
-        if opnum == rop.SETFIELD_GC:
-            return
-        if opnum == rop.SETARRAYITEM_GC:
-            return
-        if opnum == rop.SETFIELD_RAW:
-            return
-        if opnum == rop.SETARRAYITEM_RAW:
-            return
+        if (opnum == rop.SETFIELD_GC or
+            opnum == rop.SETARRAYITEM_GC or
+            opnum == rop.SETFIELD_RAW or
+            opnum == rop.SETARRAYITEM_RAW or
+            opnum == rop.SETINTERIORFIELD_GC):
         if rop._OVF_FIRST <= opnum <= rop._OVF_LAST:
             return
         if rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST:
@@ -75,9 +79,9 @@
         if opnum == rop.CALL or opnum == rop.CALL_LOOPINVARIANT:
             effectinfo = descr.get_extra_info()
             ef = effectinfo.extraeffect
-            if ef == effectinfo.EF_LOOPINVARIANT or \
-               ef == effectinfo.EF_ELIDABLE_CANNOT_RAISE or \
-               ef == effectinfo.EF_ELIDABLE_CAN_RAISE:
+            if (ef == effectinfo.EF_LOOPINVARIANT or
+                ef == effectinfo.EF_ELIDABLE_CANNOT_RAISE or
+                ef == effectinfo.EF_ELIDABLE_CAN_RAISE):
                 return
             # A special case for ll_arraycopy, because it is so common, and its
             # effects are so well defined.
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -3521,7 +3521,7 @@
         self.check_loops({"int_sub": 1, "int_gt": 1, "guard_true": 1, "jump": 1})
 
     def test_virtual_opaque_ptr(self):
-        myjitdriver = JitDriver(greens = [], reds=["n"])
+        myjitdriver = JitDriver(greens = [], reds = ["n"])
         erase, unerase = rerased.new_erasing_pair("x")
         @look_inside_iff(lambda x: isvirtual(x))
         def g(x):
@@ -3539,6 +3539,27 @@
         assert res == 0
         self.check_loops({"int_sub": 1, "int_gt": 1, "guard_true": 1, "jump": 1})
 
+    def test_virtual_opaque_dict(self):
+        myjitdriver = JitDriver(greens = [], reds = ["n"])
+        erase, unerase = rerased.new_erasing_pair("x")
+        @look_inside_iff(lambda x: isvirtual(x))
+        def g(x):
+            return x[0]["key"] - 1
+        def f(n):
+            while n > 0:
+                myjitdriver.jit_merge_point(n=n)
+                x = [{}]
+                x[0]["key"] = n
+                x[0]["other key"] = n
+                y = erase(x)
+                z = unerase(y)
+                n = g(x)
+            return n
+        res = self.meta_interp(f, [10])
+        assert res == 0
+        self.check_loops({"int_sub": 1, "int_gt": 1, "guard_true": 1, "jump": 1})
+
+
 
 class TestLLtype(BaseLLtypeTests, LLJitMixin):
     def test_tagged(self):


More information about the pypy-commit mailing list