[pypy-svn] r69494 - in pypy/branch/faster-raise/pypy/interpreter: . test

arigo at codespeak.net arigo at codespeak.net
Sat Nov 21 18:32:14 CET 2009


Author: arigo
Date: Sat Nov 21 18:32:13 2009
New Revision: 69494

Modified:
   pypy/branch/faster-raise/pypy/interpreter/executioncontext.py
   pypy/branch/faster-raise/pypy/interpreter/test/test_executioncontext.py
Log:
(pedronis, arigo)
Rename yet again the flag, and change subtle its meaning yet again.
Fixes an issue, described by the new test.


Modified: pypy/branch/faster-raise/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/branch/faster-raise/pypy/interpreter/executioncontext.py	(original)
+++ pypy/branch/faster-raise/pypy/interpreter/executioncontext.py	Sat Nov 21 18:32:13 2009
@@ -124,13 +124,15 @@
         sys.exc_info() and similar places that expose the traceback to app-
         level, this is done by OperationError.wrap_application_traceback().
 
-        The 'f_no_forward_from_there' flag on PyFrame is an optimization:
-        it is set to True when we are sure that f_forward is None on frame and
-        on any of its f_backs.
+        The 'f_back_is_correct' flag on PyFrame means 'the f_back_some is
+        actually really my f_back'.  If not set, we must check
+        'f_back_some.f_forward' to access the real f_back.  Note that we
+        guarantee that if f_back_is_correct is set on a frame in the frame
+        chain, then it is also set on all older frames.
         """ 
         frame.f_back_some = None
         frame.f_forward = None
-        frame.f_no_forward_from_there = False
+        frame.f_back_is_correct = False
 
     def _chain(self, frame):
         self.framestackdepth += 1
@@ -144,8 +146,7 @@
             self.top_real_frame = frame
 
     def _unchain(self, frame):
-        if not we_are_translated():
-            assert frame is self.gettopframe() # slowish
+        assert frame is self.gettopframe() # slowish, XXX disable me again
         if self.top_real_frame is frame:
             self.top_real_frame = frame.f_back_some
         else:
@@ -169,7 +170,7 @@
     @jit.unroll_safe
     def _extract_back_from_frame(frame):
         back_some = frame.f_back_some
-        if frame.f_no_forward_from_there:
+        if frame.f_back_is_correct:
             # don't check back_some.f_forward in this case
             return back_some
         if back_some is None:
@@ -183,27 +184,30 @@
     def force_frame_chain(self):
         frame = self.gettopframe()
         self.top_real_frame = frame
-        while frame is not None and not frame.f_no_forward_from_there:
+        if frame is None:
+            return
+        while not frame.f_back_is_correct:
             f_back = ExecutionContext._extract_back_from_frame(frame)
             frame.f_back_some = f_back
+            frame.f_back_is_correct = True
             # now that we force the whole chain, we also have to set the
             # forward links to None
-            frame.f_forward = None
-            frame.f_no_forward_from_there = True
+            if f_back is None:
+                break
+            f_back.f_forward = None
             frame = f_back
 
     def escape_frame_via_traceback(self, topframe):
         # The topframe escapes via a traceback.  There are two cases: either
         # this topframe is a virtual frame, or not.
-        if not we_are_translated():
-            assert topframe is self.gettopframe()
+        assert topframe is self.gettopframe()
         if self.top_real_frame is not topframe:
             # Case of a virtual frame: set the f_back_some pointer on the
-            # frame to the real back, and set f_no_forward_from_there as a
+            # frame to the real back, and set f_back_is_correct as a
             # way to ensure that the correct thing will happen in
             # _extract_back_from_frame(), should it ever be called.
             topframe.f_back_some = topframe.f_back()
-            topframe.f_no_forward_from_there = True
+            topframe.f_back_is_correct = True
         else:
             # Normal case
             self.force_frame_chain()

Modified: pypy/branch/faster-raise/pypy/interpreter/test/test_executioncontext.py
==============================================================================
--- pypy/branch/faster-raise/pypy/interpreter/test/test_executioncontext.py	(original)
+++ pypy/branch/faster-raise/pypy/interpreter/test/test_executioncontext.py	Sat Nov 21 18:32:13 2009
@@ -438,7 +438,7 @@
         assert frame.f_forward is None
         assert frame2.f_forward is None
         ec.force_frame_chain()
-        assert frame.f_no_forward_from_there
+        assert frame.f_back_is_correct
         assert ec.gettopframe() is frame2
         assert ec._extract_back_from_frame(frame2) is frame
         assert ec._extract_back_from_frame(frame) is None
@@ -827,12 +827,21 @@
         ec.escape_frame_via_traceback(frame4)      # not forced
         ec._unchain(frame4)
         assert frame._f_forward is frame2
-        assert not frame.f_no_forward_from_there
-        assert not frame2.f_no_forward_from_there
+        assert not frame.f_back_is_correct
+        assert not frame2.f_back_is_correct
         #
         ec.escape_frame_via_traceback(frame3)      # calls force_frame_chain()
         ec._unchain(frame3)
-        assert frame2.f_no_forward_from_there
+        assert frame2.f_back_is_correct
         assert frame2._f_forward is None
-        assert frame.f_no_forward_from_there
+        assert frame.f_back_is_correct
+        assert frame._f_forward is None
+
+    def test_force_frame_chain_bug(self):
+        ec, frame, frame2 = self.enter_two_jitted_levels()
+        ec.force_frame_chain()
+        frame3 = self.Frame(ec, frame2)
+        ec._chain(frame3)
+        ec.force_frame_chain()
+        assert frame2._f_forward is None    # because we just forced
         assert frame._f_forward is None



More information about the Pypy-commit mailing list