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

arigo at codespeak.net arigo at codespeak.net
Wed Jul 22 09:44:29 CEST 2009


Author: arigo
Date: Wed Jul 22 09:44:29 2009
New Revision: 66499

Modified:
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
   pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Protect against loops and duplicate arguments.


Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/optimizeopt.py	Wed Jul 22 09:44:29 2009
@@ -36,9 +36,11 @@
     def force_box(self):
         return self.box
 
-    def get_args_for_fail(self, list):
+    def get_args_for_fail(self, list, memo):
         if not self.is_constant():
-            list.append(self.box)
+            if self.box not in memo:
+                list.append(self.box)
+                memo[self.box] = None
 
     def is_constant(self):
         return self.level == LEVEL_CONSTANT
@@ -118,14 +120,19 @@
                 newoperations.append(op)
         return self.box
 
-    def get_args_for_fail(self, list):
+    def get_args_for_fail(self, list, memo):
         if self.box is not None:
-            InstanceValue.get_args_for_fail(self, list)
+            InstanceValue.get_args_for_fail(self, list, memo)
         else:
+            if self.source_op is not None: #otherwise, no loop detection needed
+                keybox = self.source_op.result
+                if keybox in memo:
+                    return
+                memo[keybox] = None
             lst = self._fields.keys()
             sort_descrs(lst)
             for ofs in lst:
-                self._fields[ofs].get_args_for_fail(list)
+                self._fields[ofs].get_args_for_fail(list, memo)
 
 
 class __extend__(SpecNode):
@@ -251,14 +258,17 @@
         op_fail = op1.suboperations[0]
         assert op_fail.opnum == rop.FAIL
         #
+        memo = {}
         newboxes = []
         for box in op_fail.args:
             try:
                 value = self.values[box]
             except KeyError:
-                newboxes.append(box)
+                if box not in memo:
+                    newboxes.append(box)
+                    memo[box] = None
             else:
-                value.get_args_for_fail(newboxes)
+                value.get_args_for_fail(newboxes, memo)
         # NB. we mutate op_fail in-place above.  That's bad.  Hopefully
         # it does not really matter because no-one is going to look again
         # at its unoptimized version.  We cannot really clone it because of

Modified: pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py	(original)
+++ pypy/branch/pyjitpl5-optimize4/pypy/jit/metainterp/test/test_optimizeopt.py	Wed Jul 22 09:44:29 2009
@@ -591,6 +591,24 @@
         """
         self.optimize_loop(ops, 'Not, Not, Not, Not', expected, i1=1)
 
+    def test_expand_fail_loop(self):
+        ops = """
+        [i1, i2]
+        p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+        setfield_gc(p1, i2, descr=valuedescr)
+        setfield_gc(p1, p1, descr=nextdescr)
+        guard_true(i1)
+            fail(p1)
+        jump(i1, i2)
+        """
+        expected = """
+        [i1, i2]
+        guard_true(i1)
+            fail(i2)
+        jump(1, i2)
+        """
+        self.optimize_loop(ops, 'Not, Not', expected, i1=1)
+
 
 class TestLLtype(BaseTestOptimizeOpt, LLtypeMixin):
     pass



More information about the Pypy-commit mailing list