[pypy-svn] r69921 - in pypy/branch/virtual-forcing/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Sun Dec 6 17:13:49 CET 2009


Author: arigo
Date: Sun Dec  6 17:13:47 2009
New Revision: 69921

Added:
   pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualref.py
      - copied, changed from r69909, pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_vref.py
Removed:
   pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_vref.py
Modified:
   pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/resume.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_resume.py
   pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualizable.py
Log:
Replace 'all_virtual_refs' with a regular list of boxes,
'virtualref_boxes', that is saved and restored by resume.py.


Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/pyjitpl.py	Sun Dec  6 17:13:47 2009
@@ -890,11 +890,6 @@
     def opimpl_virtual_ref(self, box):
         obj = box.getref_base()
         vref = virtualref.virtual_ref_during_tracing(obj)
-        #
-        if self.metainterp.all_virtual_refs is None:
-            self.metainterp.all_virtual_refs = []
-        self.metainterp.all_virtual_refs.append(vref)
-        #
         resbox = history.BoxPtr(vref)
         self.metainterp.history.record(rop.VIRTUAL_REF, [box], resbox)
         # Note: we allocate a JIT_VIRTUAL_REF here
@@ -904,15 +899,17 @@
         # as a no-op.  The point is that the backend should not really see
         # it in practice, as optimizeopt.py should either kill it or
         # replace it with a NEW_WITH_VTABLE followed by SETFIELD_GCs.
+        self.metainterp.virtualref_boxes.append(box)
+        self.metainterp.virtualref_boxes.append(resbox)
         self.make_result_box(resbox)
 
     @arguments("box")
-    def opimpl_virtual_ref_finish(self, box):
+    def opimpl_virtual_ref_finish(self, vrefbox):
         # virtual_ref_finish() assumes that we have a stack-like, last-in
         # first-out order.
-        if not self.metainterp.is_blackholing():
-            lastitem = self.metainterp.all_virtual_refs.pop()
-            assert box.getref_base() == lastitem
+        lastvrefbox = self.metainterp.virtualref_boxes.pop()
+        assert vrefbox.getref_base() == lastvrefbox.getref_base()
+        self.metainterp.virtualref_boxes.pop()
 
     # ------------------------------
 
@@ -975,7 +972,7 @@
         if metainterp.staticdata.virtualizable_info is not None:
             virtualizable_boxes = metainterp.virtualizable_boxes
         resume.capture_resumedata(metainterp.framestack, virtualizable_boxes,
-                                  resumedescr)
+                                  metainterp.virtualref_boxes, resumedescr)
         self.metainterp.staticdata.profiler.count_ops(opnum, GUARDS)
         # count
         metainterp.attach_debug_info(guard_op)
@@ -1222,7 +1219,6 @@
 
 class MetaInterp(object):
     in_recursion = 0
-    all_virtual_refs = None
     _already_allocated_resume_virtuals = None
 
     def __init__(self, staticdata):
@@ -1230,6 +1226,7 @@
         self.cpu = staticdata.cpu
         self.portal_trace_positions = []
         self.greenkey_of_huge_function = None
+        self.virtualref_boxes = []
 
     def is_blackholing(self):
         return self.history is None
@@ -1786,10 +1783,11 @@
             self.load_fields_from_virtualizable()
 
     def virtual_after_residual_call(self):
-        if self.is_blackholing() or self.all_virtual_refs is None:
+        if self.is_blackholing():
             return
-        for vr in self.all_virtual_refs:
-            if virtualref.was_forced(vr):
+        for i in range(1, len(self.virtualref_boxes), 2):
+            vrefbox = self.virtualref_boxes[i]
+            if virtualref.was_forced(vrefbox.getref_base()):
                 break
         else:
             return
@@ -1831,7 +1829,9 @@
         vinfo = self.staticdata.virtualizable_info
         self.framestack = []
         expect_virtualizable = vinfo is not None
-        virtualizable_boxes = resume.rebuild_from_resumedata(self, newboxes, resumedescr, expect_virtualizable)
+        virtualizable_boxes, virtualref_boxes = resume.rebuild_from_resumedata(
+            self, newboxes, resumedescr, expect_virtualizable)
+        self.virtualref_boxes = virtualref_boxes
         if expect_virtualizable:
             self.virtualizable_boxes = virtualizable_boxes
             if self._already_allocated_resume_virtuals is not None:
@@ -1840,8 +1840,8 @@
                 self.load_fields_from_virtualizable()
                 return
             # just jumped away from assembler (case 4 in the comment in
-            # virtualizable.py) into tracing (case 2); check that vable_rti
-            # is and stays NULL.
+            # virtualizable.py) into tracing (case 2); check that vable_token
+            # is and stays 0.
             virtualizable_box = self.virtualizable_boxes[-1]
             virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
             assert not virtualizable.vable_token

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/resume.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/resume.py	Sun Dec  6 17:13:47 2009
@@ -47,7 +47,8 @@
                                          back.parent_resumedata_snapshot,
                                          back.env[:])
 
-def capture_resumedata(framestack, virtualizable_boxes, storage):
+def capture_resumedata(framestack, virtualizable_boxes, virtualref_boxes,
+                       storage):
     n = len(framestack)-1
     top = framestack[n]
     _ensure_parent_resumedata(framestack, n)
@@ -55,6 +56,7 @@
                                 top)
     storage.rd_frame_info_list = frame_info_list
     snapshot = Snapshot(top.parent_resumedata_snapshot, top.env[:])
+    snapshot = Snapshot(snapshot, virtualref_boxes[:]) # xxx for now
     if virtualizable_boxes is not None:
         snapshot = Snapshot(snapshot, virtualizable_boxes[:]) # xxx for now
     storage.rd_snapshot = snapshot
@@ -444,6 +446,7 @@
     virtualizable_boxes = None
     if expects_virtualizables:
         virtualizable_boxes = resumereader.consume_boxes()
+    virtualref_boxes = resumereader.consume_boxes()
     frameinfo = storage.rd_frame_info_list
     while True:
         env = resumereader.consume_boxes()
@@ -453,7 +456,7 @@
         if frameinfo is None:
             break
     metainterp.framestack.reverse()
-    return virtualizable_boxes
+    return virtualizable_boxes, virtualref_boxes
 
 def force_from_resumedata(metainterp, newboxes, storage):
     resumereader = ResumeDataReader(storage, newboxes, metainterp)

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_resume.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_resume.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_resume.py	Sun Dec  6 17:13:47 2009
@@ -203,29 +203,32 @@
     fs = [FakeFrame("code0", 0, -1, b1, c1, b2)]
 
     storage = Storage()
-    capture_resumedata(fs, None, storage)
+    capture_resumedata(fs, None, [], storage)
 
     assert fs[0].parent_resumedata_snapshot is None
     assert fs[0].parent_resumedata_frame_info_list is None
 
     assert storage.rd_frame_info_list.prev is None
     assert storage.rd_frame_info_list.jitcode == 'code0'
-    assert storage.rd_snapshot.prev is None
-    assert storage.rd_snapshot.boxes == fs[0].env
-    assert storage.rd_snapshot.boxes is not fs[0].env
+    assert storage.rd_snapshot.boxes == []    # for virtualrefs
+    snapshot = storage.rd_snapshot.prev
+    assert snapshot.prev is None
+    assert snapshot.boxes == fs[0].env
+    assert snapshot.boxes is not fs[0].env
 
     storage = Storage()
     fs = [FakeFrame("code0", 0, -1, b1, c1, b2),
           FakeFrame("code1", 3, 7, b3, c2, b1),
           FakeFrame("code2", 9, -1, c3, b2)]
-    capture_resumedata(fs, None, storage)
+    capture_resumedata(fs, None, [], storage)
 
     frame_info_list = storage.rd_frame_info_list
     assert frame_info_list.prev is fs[2].parent_resumedata_frame_info_list
     assert frame_info_list.jitcode == 'code2'
     assert frame_info_list.pc == 9
 
-    snapshot = storage.rd_snapshot
+    assert storage.rd_snapshot.boxes == []    # for virtualrefs
+    snapshot = storage.rd_snapshot.prev
     assert snapshot.prev is fs[2].parent_resumedata_snapshot
     assert snapshot.boxes == fs[2].env
     assert snapshot.boxes is not fs[2].env
@@ -249,8 +252,9 @@
     fs[2].env = [b2, b3]
     fs[2].pc = 15
     vbs = [b1, b2]
-    capture_resumedata(fs, vbs, storage)
-       
+    vrs = [b3]
+    capture_resumedata(fs, vbs, vrs, storage)
+
     frame_info_list = storage.rd_frame_info_list
     assert frame_info_list.prev is fs[2].parent_resumedata_frame_info_list
     assert frame_info_list.jitcode == 'code2'
@@ -261,6 +265,10 @@
     assert snapshot.boxes is not vbs
 
     snapshot = snapshot.prev
+    assert snapshot.boxes == vrs
+    assert snapshot.boxes is not vrs
+
+    snapshot = snapshot.prev
     assert snapshot.prev is fs[2].parent_resumedata_snapshot
     assert snapshot.boxes == fs[2].env
 
@@ -278,7 +286,7 @@
     fs = [FakeFrame("code0", 0, -1, b1, c1, b2),
           FakeFrame("code1", 3, 7, b3, c2, b1),
           FakeFrame("code2", 9, -1, c3, b2)]
-    capture_resumedata(fs, None, storage)
+    capture_resumedata(fs, None, [], storage)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     modifier = ResumeDataVirtualAdder(storage, memo)
     liveboxes = modifier.finish({})
@@ -289,7 +297,7 @@
 
     result = rebuild_from_resumedata(metainterp, newboxes, storage,
                                      False)
-    assert result is None
+    assert result == (None, [])
     fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t),
            FakeFrame("code1", 3, 7, b3t, c2, b1t),
            FakeFrame("code2", 9, -1, c3, b2t)]
@@ -302,7 +310,7 @@
     fs = [FakeFrame("code0", 0, -1, b1, c1, b2),
           FakeFrame("code1", 3, 7, b3, c2, b1),
           FakeFrame("code2", 9, -1, c3, b2)]
-    capture_resumedata(fs, [b4], storage)
+    capture_resumedata(fs, [b4], [], storage)
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     modifier = ResumeDataVirtualAdder(storage, memo)
     liveboxes = modifier.finish({})
@@ -313,7 +321,7 @@
 
     result = rebuild_from_resumedata(metainterp, newboxes, storage,
                                      True)
-    assert result == [b4t]
+    assert result == ([b4t], [])
     fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t),
            FakeFrame("code1", 3, 7, b3t, c2, b1t),
            FakeFrame("code2", 9, -1, c3, b2t)]
@@ -326,10 +334,10 @@
     fs = [FakeFrame("code0", 0, -1, b1, c1, b2),
           FakeFrame("code1", 3, 7, b3, c2, b1),
           FakeFrame("code2", 9, -1, c3, b2)]
-    capture_resumedata(fs, None, storage)
+    capture_resumedata(fs, None, [], storage)
     storage2 = Storage()
     fs = fs[:-1] + [FakeFrame("code2", 10, -1, c3, b2, b4)]
-    capture_resumedata(fs, None, storage2)
+    capture_resumedata(fs, None, [], storage2)
     
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     modifier = ResumeDataVirtualAdder(storage, memo)
@@ -345,7 +353,7 @@
 
     result = rebuild_from_resumedata(metainterp, newboxes, storage,
                                      False)
-    assert result is None
+    assert result == (None, [])
     fs2 = [FakeFrame("code0", 0, -1, b1t, c1, b2t),
            FakeFrame("code1", 3, 7, b3t, c2, b1t),
            FakeFrame("code2", 9, -1, c3, b2t)]
@@ -356,7 +364,7 @@
     metainterp.framestack = []
     result = rebuild_from_resumedata(metainterp, newboxes, storage2,
                                      False)
-    assert result is None
+    assert result == (None, [])
     fs2 = fs2[:-1] + [FakeFrame("code2", 10, -1, c3, b2t, b4t)]
     assert metainterp.framestack == fs2
 
@@ -384,10 +392,10 @@
     fs = [FakeFrame("code0", 0, -1, b1, c1, b2),
           FakeFrame("code1", 3, 7, b3, c2, b1),
           FakeFrame("code2", 9, -1, c3, b2)]
-    capture_resumedata(fs, None, storage)
+    capture_resumedata(fs, None, [], storage)
     storage2 = Storage()
     fs = fs[:-1] + [FakeFrame("code2", 10, -1, c3, b2, b4)]
-    capture_resumedata(fs, None, storage2)
+    capture_resumedata(fs, None, [], storage2)
     
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     values = {b2: virtual_value(b2, b5, c4)}
@@ -443,7 +451,7 @@
                       LLtypeMixin.nodebox.constbox()]
     storage = Storage()
     fs = [FakeFrame("code0", 0, -1, c1, b2, b3)]
-    capture_resumedata(fs, None, storage)
+    capture_resumedata(fs, None, [], storage)
     
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     values = {b2: virtual_value(b2, b5, c4)}
@@ -455,7 +463,7 @@
 
     storage2 = Storage()
     fs = [FakeFrame("code0", 0, -1, b1, b4, b2)]
-    capture_resumedata(fs, None, storage2)
+    capture_resumedata(fs, None, [], storage2)
     values[b4] = virtual_value(b4, b6, c4)
     modifier = ResumeDataVirtualAdder(storage2, memo)
     liveboxes = modifier.finish(values)
@@ -468,7 +476,7 @@
     b1, b2, b3 = [BoxPtr(), BoxPtr(), BoxInt()]
     storage = Storage()
     fs = [FakeFrame("code0", 0, -1, b1, b2)]
-    capture_resumedata(fs, None, storage)
+    capture_resumedata(fs, None, [], storage)
     
     memo = ResumeDataLoopMemo(FakeMetaInterpStaticData())
     v1 = virtual_value(b1, b3, None)

Modified: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualizable.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualizable.py	Sun Dec  6 17:13:47 2009
@@ -1160,8 +1160,7 @@
         self.check_loops(getfield_gc=0, setfield_gc=0)
 
     def test_blackhole_should_not_reenter(self):
-        from pypy.jit.backend.test.support import BaseCompiledMixin
-        if isinstance(self, BaseCompiledMixin):
+        if not self.basic:
             py.test.skip("purely frontend test")
 
         myjitdriver = JitDriver(greens = [], reds = ['frame', 'fail'],

Copied: pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualref.py (from r69909, pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_vref.py)
==============================================================================
--- pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_vref.py	(original)
+++ pypy/branch/virtual-forcing/pypy/jit/metainterp/test/test_virtualref.py	Sun Dec  6 17:13:47 2009
@@ -1,8 +1,12 @@
 import py
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rlib.jit import JitDriver, dont_look_inside
 from pypy.rlib.jit import virtual_ref, virtual_ref_finish
 from pypy.rlib.objectmodel import compute_unique_id
 from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
+from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.metainterp import history
+from pypy.jit.metainterp.virtualref import JIT_VIRTUAL_REF
 
 
 class VRefTests:
@@ -23,6 +27,56 @@
         self.interp_operations(f, [])
         self.check_operations_history(virtual_ref=1)
 
+    def test_make_vref_guard(self):
+        if not self.basic:
+            py.test.skip("purely frontend test")
+        #
+        class X:
+            def __init__(self, n):
+                self.n = n
+        class ExCtx:
+            pass
+        exctx = ExCtx()
+        #
+        @dont_look_inside
+        def external(n):
+            if n > 100:
+                return exctx.topframeref().n
+            return n
+        def enter(n):
+            exctx.topframeref = virtual_ref(X(n + 10))
+        def leave():
+            virtual_ref_finish(exctx.topframeref)
+            exctx.topframeref = None
+        def f(n):
+            enter(n)
+            n = external(n)
+            # ^^^ the point is that X() should be kept alive here
+            leave()
+            return n
+        #
+        res = self.interp_operations(f, [5])
+        assert res == 5
+        self.check_operations_history(virtual_ref=1, guard_not_forced=1)
+        #
+        [guard_op] = [op for op in self.metainterp.history.operations
+                         if op.opnum == rop.GUARD_NOT_FORCED]
+        bxs1 = [box for box in guard_op.fail_args
+                 if isinstance(box, history.BoxPtr) and
+                  lltype.typeOf(box.value._obj.container)._name.endswith('.X')]
+        assert len(bxs1) == 1
+        bxs2 = [box for box in guard_op.fail_args
+                 if isinstance(box, history.BoxPtr) and
+                  lltype.typeOf(box.value._obj.container) == JIT_VIRTUAL_REF]
+        assert len(bxs2) == 1
+        #
+        self.metainterp.rebuild_state_after_failure(guard_op.descr,
+                                                    guard_op.fail_args[:])
+        assert len(self.metainterp.framestack) == 1
+        assert len(self.metainterp.virtualref_boxes) == 2
+        assert self.metainterp.virtualref_boxes[0].value == bxs1[0].value
+        assert self.metainterp.virtualref_boxes[1].value == bxs2[0].value
+
     def test_make_vref_and_force(self):
         jitdriver = JitDriver(greens = [], reds = ['total', 'n'])
         #
@@ -45,8 +99,8 @@
                 x.n = n + 123
                 exctx.topframeref = virtual_ref(x)
                 total += force_me() - 100
+                virtual_ref_finish(exctx.topframeref)
                 exctx.topframeref = None
-                virtual_ref_finish(x)
             return total
         #
         res = self.meta_interp(f, [-4])



More information about the Pypy-commit mailing list