[pypy-svn] r71381 - in pypy/trunk/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Sun Feb 21 15:31:57 CET 2010
Author: arigo
Date: Sun Feb 21 15:31:55 2010
New Revision: 71381
Modified:
pypy/trunk/pypy/jit/metainterp/codewriter.py
pypy/trunk/pypy/jit/metainterp/effectinfo.py
pypy/trunk/pypy/jit/metainterp/optimizeopt.py
pypy/trunk/pypy/jit/metainterp/pyjitpl.py
pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py
pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py
pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
Log:
Fix one of the issues that I've been fighting for since a week: the
accesses to the 'forced' field of virtualrefs is not recorded in the
effectinfo, thus from time to time invalid code is generated -- by
delaying the SETFIELD_GC for too long. This is how force_virtual()
occasionally showed invalid VIRTUAL_REF structures: because the
structure was not fully updated yet.
This fix also simplifies things: the effectinfos that used to have the
flag 'forces_virtual_or_virtualizable' are now always stored just as
None. I think that there is not a lot of benefits from optimizing field
reads or writes around calls to functions that can force anyway.
This is a merge from r71373+r71374 in branch/debug-vref2.
Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/trunk/pypy/jit/metainterp/codewriter.py Sun Feb 21 15:31:55 2010
@@ -337,10 +337,12 @@
assert RESULT == FUNC.RESULT
# ok
if consider_effects_of is not None:
- effectinfo = effectinfo_from_writeanalyze(
+ if self.virtualizable_analyzer.analyze(consider_effects_of):
+ effectinfo = None # forcing virtualizable or vrefs
+ else:
+ effectinfo = effectinfo_from_writeanalyze(
self.readwrite_analyzer.analyze(consider_effects_of),
- self.cpu,
- self.virtualizable_analyzer.analyze(consider_effects_of))
+ self.cpu)
calldescr = self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), RESULT, effectinfo)
else:
calldescr = self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), RESULT)
@@ -1259,8 +1261,7 @@
loopinvariant = getattr(func, "_jit_loop_invariant_", False)
if pure or loopinvariant:
effectinfo = calldescr.get_extra_info()
- assert (effectinfo is not None and
- not effectinfo.forces_virtual_or_virtualizable)
+ assert effectinfo is not None
try:
canraise = self.codewriter.raise_analyzer.can_raise(op)
except lltype.DelayedPointer:
Modified: pypy/trunk/pypy/jit/metainterp/effectinfo.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/effectinfo.py (original)
+++ pypy/trunk/pypy/jit/metainterp/effectinfo.py Sun Feb 21 15:31:55 2010
@@ -8,24 +8,20 @@
_cache = {}
def __new__(cls, readonly_descrs_fields,
- write_descrs_fields, write_descrs_arrays,
- forces_virtual_or_virtualizable=False):
+ write_descrs_fields, write_descrs_arrays):
key = (frozenset(readonly_descrs_fields),
frozenset(write_descrs_fields),
- frozenset(write_descrs_arrays),
- forces_virtual_or_virtualizable)
+ frozenset(write_descrs_arrays))
if key in cls._cache:
return cls._cache[key]
result = object.__new__(cls)
result.readonly_descrs_fields = readonly_descrs_fields
result.write_descrs_fields = write_descrs_fields
result.write_descrs_arrays = write_descrs_arrays
- result.forces_virtual_or_virtualizable= forces_virtual_or_virtualizable
cls._cache[key] = result
return result
-def effectinfo_from_writeanalyze(effects, cpu,
- forces_virtual_or_virtualizable=False):
+def effectinfo_from_writeanalyze(effects, cpu):
from pypy.translator.backendopt.writeanalyze import top_set
if effects is top_set:
return None
@@ -61,8 +57,7 @@
assert 0
return EffectInfo(readonly_descrs_fields,
write_descrs_fields,
- write_descrs_arrays,
- forces_virtual_or_virtualizable)
+ write_descrs_arrays)
def consider_struct(TYPE, fieldname):
if fieldType(TYPE, fieldname) is lltype.Void:
Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Sun Feb 21 15:31:55 2010
@@ -1024,7 +1024,7 @@
if (opnum == rop.CALL or
opnum == rop.CALL_MAY_FORCE or
opnum == rop.CALL_ASSEMBLER):
- if opnum == rop.CALL_ASSEMBLER:
+ if opnum != rop.CALL:
effectinfo = None
else:
effectinfo = op.descr.get_extra_info()
Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Sun Feb 21 15:31:55 2010
@@ -1073,7 +1073,7 @@
def do_residual_call(self, argboxes, descr, exc):
effectinfo = descr.get_extra_info()
- if effectinfo is None or effectinfo.forces_virtual_or_virtualizable:
+ if effectinfo is None:
# residual calls require attention to keep virtualizables in-sync
self.metainterp.vable_and_vrefs_before_residual_call()
# xxx do something about code duplication
Modified: pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py Sun Feb 21 15:31:55 2010
@@ -306,7 +306,6 @@
assert calldescrs[0][4] is not None
assert not calldescrs[0][4].write_descrs_fields
assert not calldescrs[0][4].write_descrs_arrays
- assert not calldescrs[0][4].forces_virtual_or_virtualizable
def test_oosend_look_inside_only_one(self):
class A:
@@ -453,9 +452,9 @@
effectinfo_g1 = calldescrs[1][4]
effectinfo_g2 = calldescrs[2][4]
effectinfo_h = calldescrs[3][4]
- assert effectinfo_g1.forces_virtual_or_virtualizable
- assert effectinfo_g2.forces_virtual_or_virtualizable
- assert not effectinfo_h.forces_virtual_or_virtualizable
+ assert effectinfo_g1 is None
+ assert effectinfo_g2 is None
+ assert effectinfo_h is not None
def make_vrefinfo(self):
from pypy.jit.metainterp.virtualref import VirtualRefInfo
Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_optimizefindnode.py Sun Feb 21 15:31:55 2010
@@ -111,9 +111,7 @@
EffectInfo([], [adescr], [arraydescr]))
readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
EffectInfo([adescr], [], []))
- mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([nextdescr], [], [],
- forces_virtual_or_virtualizable=True))
+ mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
class LoopToken(AbstractDescr):
pass
asmdescr = LoopToken() # it can be whatever, it's not a descr though
Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Sun Feb 21 15:31:55 2010
@@ -2564,7 +2564,6 @@
#
call_may_force(i1, descr=mayforcevirtdescr)
guard_not_forced() [i1]
- setfield_gc(p0, NULL, descr=nextdescr)
#
p1 = new_with_vtable(ConstClass(node_vtable))
p1b = new_with_vtable(ConstClass(node_vtable))
@@ -2573,6 +2572,7 @@
setfield_gc(p2, p1, descr=virtualforceddescr)
setfield_gc(p2, -2, descr=virtualtokendescr)
#
+ setfield_gc(p0, NULL, descr=nextdescr)
jump(p0, i1)
"""
self.optimize_loop(ops, 'Not, Not', expected)
@@ -2606,7 +2606,6 @@
#
call_may_force(i1, descr=mayforcevirtdescr)
guard_not_forced(descr=fdescr) [p2, i1]
- setfield_gc(p0, NULL, descr=nextdescr)
#
p1 = new_with_vtable(ConstClass(node_vtable))
p1b = new_with_vtable(ConstClass(node_vtable))
@@ -2615,6 +2614,7 @@
setfield_gc(p2, p1, descr=virtualforceddescr)
setfield_gc(p2, -2, descr=virtualtokendescr)
#
+ setfield_gc(p0, NULL, descr=nextdescr)
jump(p0, i1)
"""
# the point of this test is that 'i1' should show up in the fail_args
@@ -2664,6 +2664,32 @@
where p1b is a node_vtable, valuedescr=i1
''')
+ def test_vref_nonvirtual_and_lazy_setfield(self):
+ self.make_fail_descr()
+ ops = """
+ [i1, p1]
+ p2 = virtual_ref(p1, 23)
+ escape(p2)
+ virtual_ref_finish(p2, p1)
+ call_may_force(i1, descr=mayforcevirtdescr)
+ guard_not_forced() [i1]
+ jump(i1, p1)
+ """
+ expected = """
+ [i1, p1]
+ i3 = force_token()
+ p2 = new_with_vtable(ConstClass(jit_virtual_ref_vtable))
+ setfield_gc(p2, i3, descr=virtualtokendescr)
+ setfield_gc(p2, 23, descr=virtualrefindexdescr)
+ escape(p2)
+ setfield_gc(p2, p1, descr=virtualforceddescr)
+ setfield_gc(p2, -2, descr=virtualtokendescr)
+ call_may_force(i1, descr=mayforcevirtdescr)
+ guard_not_forced() [i1]
+ jump(i1, p1)
+ """
+ self.optimize_loop(ops, 'Not, Not', expected)
+
class TestOOtype(BaseTestOptimizeOpt, OOtypeMixin):
More information about the Pypy-commit
mailing list