[pypy-commit] pypy improve-consecutive-dict-lookups: fix and write more tests

fijal noreply at buildbot.pypy.org
Mon Mar 17 13:35:52 CET 2014


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: improve-consecutive-dict-lookups
Changeset: r70010:b828e827b47f
Date: 2014-03-17 14:35 +0200
http://bitbucket.org/pypy/pypy/changeset/b828e827b47f/

Log:	fix and write more tests

diff --git a/rpython/jit/codewriter/call.py b/rpython/jit/codewriter/call.py
--- a/rpython/jit/codewriter/call.py
+++ b/rpython/jit/codewriter/call.py
@@ -178,7 +178,7 @@
         return (fnaddr, calldescr)
 
     def getcalldescr(self, op, oopspecindex=EffectInfo.OS_NONE,
-                     extraeffect=None):
+                     extraeffect=None, extradescr=None):
         """Return the calldescr that describes all calls done by 'op'.
         This returns a calldescr that we can put in the corresponding
         call operation in the calling jitcode.  It gets an effectinfo
@@ -259,6 +259,7 @@
         effectinfo = effectinfo_from_writeanalyze(
             self.readwrite_analyzer.analyze(op, self.seen), self.cpu,
             extraeffect, oopspecindex, can_invalidate, call_release_gil_target,
+            extradescr,
         )
         #
         assert effectinfo is not None
diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -97,7 +97,8 @@
                 extraeffect=EF_CAN_RAISE,
                 oopspecindex=OS_NONE,
                 can_invalidate=False,
-                call_release_gil_target=llmemory.NULL):
+                call_release_gil_target=llmemory.NULL,
+                extradescr=None):
         key = (frozenset_or_none(readonly_descrs_fields),
                frozenset_or_none(readonly_descrs_arrays),
                frozenset_or_none(write_descrs_fields),
@@ -133,6 +134,7 @@
         result.extraeffect = extraeffect
         result.can_invalidate = can_invalidate
         result.oopspecindex = oopspecindex
+        result.extradescr = extradescr
         result.call_release_gil_target = call_release_gil_target
         if result.check_can_raise():
             assert oopspecindex in cls._OS_CANRAISE
@@ -173,7 +175,8 @@
                                  extraeffect=EffectInfo.EF_CAN_RAISE,
                                  oopspecindex=EffectInfo.OS_NONE,
                                  can_invalidate=False,
-                                 call_release_gil_target=llmemory.NULL):
+                                 call_release_gil_target=llmemory.NULL,
+                                 extradescr=None):
     from rpython.translator.backendopt.writeanalyze import top_set
     if effects is top_set or extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
         readonly_descrs_fields = None
@@ -222,7 +225,8 @@
                       extraeffect,
                       oopspecindex,
                       can_invalidate,
-                      call_release_gil_target)
+                      call_release_gil_target,
+                      extradescr)
 
 def consider_struct(TYPE, fieldname):
     if fieldType(TYPE, fieldname) is lltype.Void:
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1684,9 +1684,11 @@
     # ----------
     # Strings and Unicodes.
 
-    def _handle_oopspec_call(self, op, args, oopspecindex, extraeffect=None):
+    def _handle_oopspec_call(self, op, args, oopspecindex, extraeffect=None,
+                             extradescr=None):
         calldescr = self.callcontrol.getcalldescr(op, oopspecindex,
-                                                  extraeffect)
+                                                  extraeffect,
+                                                  extradescr=extradescr)
         if extraeffect is not None:
             assert (is_test_calldescr(calldescr)      # for tests
                     or calldescr.get_extra_info().extraeffect == extraeffect)
@@ -1851,8 +1853,11 @@
                                          EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
 
     def _handle_dict_lookup_call(self, op, oopspec_name, args):
+        extradescr = self.cpu.fielddescrof(op.args[1].concretetype.TO,
+                                           'entries')
         return self._handle_oopspec_call(op, args, EffectInfo.OS_DICT_LOOKUP,
-                                         EffectInfo.EF_CAN_RAISE)
+                                         EffectInfo.EF_CAN_RAISE,
+                                         extradescr=extradescr)
 
     def _handle_rgc_call(self, op, oopspec_name, args):
         if oopspec_name == 'rgc.ll_shrink_array':
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -298,7 +298,7 @@
 
     def _optimize_CALL_DICT_LOOKUP(self, op):
         args = self.optimizer.make_args_key(op)
-        descr = op.getdescr()
+        descr = op.getdescr().extrainfo.extradescr
         res_v = self.getvalue(op.result)
         if descr in self.cached_dict_reads:
             d = self.cached_dict_reads[descr]
@@ -331,6 +331,10 @@
         for arraydescr in effectinfo.readonly_descrs_arrays:
             self.force_lazy_setarrayitem(arraydescr)
         for fielddescr in effectinfo.write_descrs_fields:
+            try:
+                del self.cached_dict_reads[fielddescr]
+            except KeyError:
+                pass
             self.force_lazy_setfield(fielddescr, can_cache=False)
         for arraydescr in effectinfo.write_descrs_arrays:
             self.force_lazy_setarrayitem(arraydescr, can_cache=False)
diff --git a/rpython/jit/metainterp/test/test_dict.py b/rpython/jit/metainterp/test/test_dict.py
--- a/rpython/jit/metainterp/test/test_dict.py
+++ b/rpython/jit/metainterp/test/test_dict.py
@@ -214,23 +214,42 @@
 
     def test_dict_insert_invalidates_caches(self):
         driver = JitDriver(greens = [], reds = 'auto')
-        d = {'a': 3, 'b': 4}
-        indexes = ['a', 'b']
+        indexes = ['aa', 'b', 'cc']
 
         def f(n):
+            d = {'aa': 3, 'b': 4, 'cc': 5}
             s = 0
             while n > 0:
                 driver.jit_merge_point()
                 index = indexes[n & 1]
                 s += d[index]
-                d['aa'] = 13 # this will invalidate the index
+                d['aa'] += 1 # this will invalidate the index
                 s += d[index]
                 n -= 1
             return s
 
-        self.meta_interp(f, [10])
-        self.check_simple_loop(call=1, getinteriorfield_gc=1,
-                               guard_no_exception=1)
+        res = self.meta_interp(f, [10])
+        assert res == f(10)
+        self.check_simple_loop(call=5)
+
+    def test_dict_double_lookup_2(self):
+        driver = JitDriver(greens = [], reds = 'auto')
+        indexes = ['aa', 'b', 'cc']
+
+        def f(n):
+            d = {'aa': 3, 'b': 4, 'cc': 5}
+            s = 0
+            while n > 0:
+                driver.jit_merge_point()
+                index = indexes[n & 1]
+                s += d[index]
+                d[index] += 1
+                n -= 1
+            return s
+
+        res = self.meta_interp(f, [10])
+        assert res == f(10)
+        self.check_simple_loop(call=3)
 
 class TestLLtype(DictTests, LLJitMixin):
     pass


More information about the pypy-commit mailing list