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

Reply via email to