[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