Author: Antonio Cuni <[email protected]>
Branch: invalidate-virtualrefs
Changeset: r44519:15073d77a970
Date: 2011-05-26 16:13 +0200
http://bitbucket.org/pypy/pypy/changeset/15073d77a970/
Log: (arigo, antocuni): fix the logic when we force the vref already
during tracing: in that case, we want to store the object inside
forced; in the 'normal' case, we just store null (and optimize the
setfield away, because it is constant); also, write a test that
checks that we can call a vref after finish in case we already
forced it
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py
b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -341,8 +341,10 @@
# - set 'forced' to point to the real object
seo = self.optimizer.send_extra_operation
- ## seo(ResOperation(rop.SETFIELD_GC, op.getarglist(), None,
- ## descr = vrefinfo.descr_forced))
+ vrefbox, objbox = op.getarglist()
+ if not self.optimizer.cpu.ts.CONST_NULL.same_constant(objbox):
+ seo(ResOperation(rop.SETFIELD_GC, op.getarglist(), None,
+ descr = vrefinfo.descr_forced))
# - set 'virtual_token' to TOKEN_NONE
args = [op.getarg(0), ConstInt(vrefinfo.TOKEN_NONE)]
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1049,8 +1049,10 @@
vrefinfo = metainterp.staticdata.virtualref_info
vref = vrefbox.getref_base()
if vrefinfo.is_virtual_ref(vref):
+ # XXX write a comment about nullbox
+ nullbox = self.metainterp.cpu.ts.CONST_NULL
metainterp.history.record(rop.VIRTUAL_REF_FINISH,
- [vrefbox, lastbox], None)
+ [vrefbox, nullbox], None)
@arguments()
def opimpl_ll_read_timestamp(self):
diff --git a/pypy/jit/metainterp/test/test_virtualref.py
b/pypy/jit/metainterp/test/test_virtualref.py
--- a/pypy/jit/metainterp/test/test_virtualref.py
+++ b/pypy/jit/metainterp/test/test_virtualref.py
@@ -566,5 +566,35 @@
py.test.raises(InvalidVirtualRef, "fn(10)")
py.test.raises(LLException, "self.meta_interp(fn, [10])")
+ def test_call_virtualref_already_forced(self):
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'res'])
+ #
+ class XY:
+ n = 0
+ #
+ @dont_look_inside
+ def force_it(vref, n):
+ if n % 6 == 0:
+ return vref().n
+ return 0
+ def fn(n):
+ res = 0
+ while n > 0:
+ myjitdriver.can_enter_jit(n=n, res=res)
+ myjitdriver.jit_merge_point(n=n, res=res)
+ xy = XY()
+ xy.n = n
+ vref = virtual_ref(xy)
+ force_it(vref, n)
+ virtual_ref_finish(vref, xy)
+ res += force_it(vref, n) # doesn't raise, because it was
already forced
+ n -= 1
+ return res
+ #
+ assert fn(10) == 6
+ res = self.meta_interp(fn, [10])
+ assert res == 6
+
+
class TestLLtype(VRefTests, LLJitMixin):
pass
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit