[pypy-svn] r69959 - in pypy/branch/virtual-forcing/pypy: interpreter interpreter/test module/_stackless module/pypyjit module/sys objspace/flow

arigo at codespeak.net arigo at codespeak.net
Mon Dec 7 23:34:48 CET 2009


Author: arigo
Date: Mon Dec  7 23:34:47 2009
New Revision: 69959

Modified:
   pypy/branch/virtual-forcing/pypy/interpreter/executioncontext.py
   pypy/branch/virtual-forcing/pypy/interpreter/generator.py
   pypy/branch/virtual-forcing/pypy/interpreter/pyframe.py
   pypy/branch/virtual-forcing/pypy/interpreter/pytraceback.py
   pypy/branch/virtual-forcing/pypy/interpreter/test/test_executioncontext.py
   pypy/branch/virtual-forcing/pypy/module/_stackless/interp_coroutine.py
   pypy/branch/virtual-forcing/pypy/module/pypyjit/interp_jit.py
   pypy/branch/virtual-forcing/pypy/module/sys/vm.py
   pypy/branch/virtual-forcing/pypy/objspace/flow/flowcontext.py
Log:
Revert the 'f_forward' hack everywhere.  Replace it with
virtual_refs: the 'f_back' field is now called 'f_backref',
and 'topframe' is called 'topframeref' to make it clear.

In-progress.


Modified: pypy/branch/virtual-forcing/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/interpreter/executioncontext.py	(original)
+++ pypy/branch/virtual-forcing/pypy/interpreter/executioncontext.py	Mon Dec  7 23:34:47 2009
@@ -17,7 +17,8 @@
 
     def __init__(self, space):
         self.space = space
-        self._init_frame_chain()
+        self.topframeref = jit.vref_None
+        self.framestackdepth = 0
         # tracing: space.frame_trace_action.fire() must be called to ensure
         # that tracing occurs whenever self.w_tracefunc or self.is_tracing
         # is modified.
@@ -27,169 +28,43 @@
         self.profilefunc = None
         self.w_profilefuncarg = None
 
+    def gettopframe(self):
+        return self.topframeref()
+
     def gettopframe_nohidden(self):
-        frame = self.gettopframe()
-        # I guess this should just use getnextframe_nohidden XXX
+        frame = self.topframeref()
         while frame and frame.hide():
-            frame = frame.f_back()
+            frame = frame.f_backref()
         return frame
 
     @staticmethod
     def getnextframe_nohidden(frame):
-        frame = frame.f_back()
+        frame = frame.f_backref()
         while frame and frame.hide():
-            frame = frame.f_back()
+            frame = frame.f_backref()
         return frame
 
     def enter(self, frame):
         if self.framestackdepth > self.space.sys.recursionlimit:
             raise OperationError(self.space.w_RuntimeError,
                                  self.space.wrap("maximum recursion depth exceeded"))
-        self._chain(frame)
+        self.framestackdepth += 1
+        frame.f_backref = self.topframeref
+        self.topframeref = jit.virtual_ref(frame)
 
     def leave(self, frame):
-        if self.profilefunc:
-            self._trace(frame, 'leaveframe', self.space.w_None)
+        try:
+            if self.profilefunc:
+                self._trace(frame, 'leaveframe', self.space.w_None)
+        finally:
+            self.topframeref = frame.f_backref
+            self.framestackdepth -= 1
+            jit.virtual_ref_finish(frame)
 
-        self._unchain(frame)
-        
         if self.w_tracefunc is not None and not frame.hide():
             self.space.frame_trace_action.fire()
 
     # ________________________________________________________________
-    # the methods below are used for chaining frames in JIT-friendly way
-    # part of that stuff is obscure
-
-    @jit.unroll_safe
-    def gettopframe(self):
-        frame = self.some_frame
-        if frame is not None:
-            while frame.f_forward is not None:
-                frame = frame.f_forward
-        return frame
-
-    def _init_frame_chain(self):
-        # 'some_frame' points to any frame from this thread's frame stack
-        # (although in general it should point to the top one).
-        # XXX not true: some_frame must point to a frame from which we can
-        # reach the top frame by following the chain of f_forward
-        self.some_frame = None
-        self.framestackdepth = 0
-
-    @staticmethod
-    def _init_chaining_attributes(frame):
-        """
-        explanation of the f_back handling:
-        -----------------------------------
-
-        in the non-JIT case, the frames simply form a doubly linked list via the
-        attributes f_back_some and f_forward.
-
-        When the JIT is used, things become more complex, as functions can be
-        inlined into each other. In this case a frame chain can look like this:
-
-        +---------------+
-        | real_frame    |
-        +---------------+
-           |      
-           | f_back_some
-           |      
-           |      
-           |  +--------------+
-           |  | virtual frame|
-           |  +--------------+
-           |      ^ 
-           |      | f_forward
-           |  +--------------+
-           |  | virtual frame|
-           |  +--------------+
-           |      ^
-           |      |
-           v      | f_forward
-        +---------------+
-        | real_frame    |
-        +---------------+
-           |
-           |
-           v
-          ...
-        
-        This ensures that the virtual frames don't escape via the f_back of the
-        real frames. For the same reason, the executioncontext's some_frame
-        attribute should only point to real frames.
-
-        All places where a frame can become accessed from applevel-code (like
-        sys._getframe and traceback catching) need to call force_f_back to ensure
-        that the intermediate virtual frames are forced to be real ones.
-
-        """ 
-        frame.f_back_some = None
-        frame.f_forward = None
-        frame.f_back_forced = False
-
-    def _chain(self, frame):
-        self.framestackdepth += 1
-        #
-        frame.f_back_some = self.some_frame
-        if self._we_are_jitted():
-            curtopframe = self.gettopframe()
-            assert curtopframe is not None
-            curtopframe.f_forward = frame
-        else:
-            self.some_frame = frame
-
-    def _unchain(self, frame):
-        #assert frame is self.gettopframe() --- slowish
-        if self.some_frame is frame:
-            self.some_frame = frame.f_back_some
-        else:
-            f_back = frame.f_back()
-            if f_back is not None:
-                f_back.f_forward = None
-
-        self.framestackdepth -= 1
-
-    @staticmethod
-    def _jit_rechain_frame(ec, frame):
-        # this method is called after the jit has seen enter (and thus _chain)
-        # of a frame, but then does not actually inline it. This method thus
-        # needs to make sure that the state is as if the _chain method had been
-        # executed outside of the jit. Note that this makes it important that
-        # _unchain does not call we_are_jitted
-        frame.f_back().f_forward = None
-        ec.some_frame = frame
-
-    @staticmethod
-    @jit.unroll_safe
-    def _extract_back_from_frame(frame):
-        back_some = frame.f_back_some
-        if frame.f_back_forced:
-            # don't check back_some.f_forward in this case
-            return back_some
-        if back_some is None:
-            return None
-        while True:
-            f_forward = back_some.f_forward
-            if f_forward is frame or f_forward is None:
-                return back_some
-            back_some = f_forward
-
-    @staticmethod
-    def _force_back_of_frame(frame):
-        orig_frame = frame
-        while frame is not None and not frame.f_back_forced:
-            frame.f_back_some = f_back = ExecutionContext._extract_back_from_frame(frame)
-            frame.f_back_forced = True
-            # now that we force the whole chain, we also have to set the
-            # forward links to None
-            frame.f_forward = None
-            frame = f_back
-        return orig_frame.f_back_some
-
-    _we_are_jitted = staticmethod(we_are_jitted) # indirection for testing
-    
-    # the methods above are used for chaining frames in JIT-friendly way
-    # ________________________________________________________________
 
 
     class Subcontext(object):
@@ -204,7 +79,7 @@
             self.is_tracing = 0
 
         def enter(self, ec):
-            ec.some_frame = self.topframe
+            ec.topframeref = jit.non_virtual_ref(self.topframe)
             ec.framestackdepth = self.framestackdepth
             ec.w_tracefunc = self.w_tracefunc
             ec.profilefunc = self.profilefunc
@@ -247,7 +122,7 @@
             while index > 0:
                 index -= 1
                 lst[index] = f
-                f = f.f_back()
+                f = f.f_backref()
             assert f is None
             return lst
         # coroutine: I think this is all, folks!

Modified: pypy/branch/virtual-forcing/pypy/interpreter/generator.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/interpreter/generator.py	(original)
+++ pypy/branch/virtual-forcing/pypy/interpreter/generator.py	Mon Dec  7 23:34:47 2009
@@ -2,6 +2,7 @@
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.gateway import NoneNotWrapped
 from pypy.rlib.rarithmetic import intmask
+from pypy.rlib import jit
 from pypy.interpreter.pyopcode import LoopBlock
 
 
@@ -64,7 +65,7 @@
             else:
                 return w_result     # YIELDed
         finally:
-            self.frame.f_back_some = None
+            self.frame.f_backref = jit.vref_None
             self.running = False
 
     def descr_throw(self, w_type, w_val=None, w_tb=None):

Modified: pypy/branch/virtual-forcing/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/interpreter/pyframe.py	(original)
+++ pypy/branch/virtual-forcing/pypy/interpreter/pyframe.py	Mon Dec  7 23:34:47 2009
@@ -34,13 +34,13 @@
      * 'builtin' is the attached built-in module
      * 'valuestack_w', 'blockstack', control the interpretation
     """
-    
 
     __metaclass__ = extendabletype
 
     frame_finished_execution = False
     last_instr               = -1
     last_exception           = None
+    f_backref                = jit.vref_None
     w_f_trace                = None
     # For tracing
     instr_lb                 = 0
@@ -48,6 +48,9 @@
     instr_prev               = -1
     is_being_profiled        = False
 
+    # XXX temporary, kill me
+    f_back = property(lambda: None, lambda: None, lambda: None)   # f_backref!
+
     def __init__(self, space, code, w_globals, closure):
         self = hint(self, access_directly=True, fresh_virtualizable=True)
         assert isinstance(code, pycode.PyCode)
@@ -64,7 +67,6 @@
         self.fastlocals_w = [None]*self.numlocals
         make_sure_not_resized(self.fastlocals_w)
         self.f_lineno = code.co_firstlineno
-        ExecutionContext._init_chaining_attributes(self)
 
     def append_block(self, block):
         block.previous = self.lastblock
@@ -308,7 +310,7 @@
             w_tb = w(self.last_exception.application_traceback)
         
         tup_state = [
-            w(self.f_back()),
+            w(self.f_backref()),
             w(self.get_builtin()),
             w(self.pycode),
             w_valuestack,
@@ -360,8 +362,8 @@
         # do not use the instance's __init__ but the base's, because we set
         # everything like cells from here
         PyFrame.__init__(self, space, pycode, w_globals, closure)
-        new_frame.f_back_some = space.interp_w(PyFrame, w_f_back, can_be_None=True)
-        new_frame.f_back_forced = True
+        f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True)
+        new_frame.f_backref = jit.non_virtual_ref(f_back)
 
         new_frame.builtin = space.interp_w(Module, w_builtin)
         new_frame.set_blocklist([unpickle_block(space, w_blk)
@@ -431,12 +433,6 @@
     def _setcellvars(self, cellvars):
         pass
 
-    def f_back(self):
-        return ExecutionContext._extract_back_from_frame(self)
-
-    def force_f_back(self):
-        return ExecutionContext._force_back_of_frame(self)
-
     ### line numbers ###
 
     # for f*_f_* unwrapping through unwrap_spec in typedef.py
@@ -584,7 +580,7 @@
         return self.get_builtin().getdict()
 
     def fget_f_back(space, self):
-        return self.space.wrap(self.f_back())
+        return self.space.wrap(self.f_backref())
 
     def fget_f_lasti(space, self):
         return self.space.wrap(self.last_instr)
@@ -605,27 +601,27 @@
 
     def fget_f_exc_type(space, self):
         if self.last_exception is not None:
-            f = self.f_back()
+            f = self.f_backref()
             while f is not None and f.last_exception is None:
-                f = f.f_back()
+                f = f.f_backref()
             if f is not None:
                 return f.last_exception.w_type
         return space.w_None
          
     def fget_f_exc_value(space, self):
         if self.last_exception is not None:
-            f = self.f_back()
+            f = self.f_backref()
             while f is not None and f.last_exception is None:
-                f = f.f_back()
+                f = f.f_backref()
             if f is not None:
                 return f.last_exception.w_value
         return space.w_None
 
     def fget_f_exc_traceback(space, self):
         if self.last_exception is not None:
-            f = self.f_back()
+            f = self.f_backref()
             while f is not None and f.last_exception is None:
-                f = f.f_back()
+                f = f.f_backref()
             if f is not None:
                 return space.wrap(f.last_exception.application_traceback)
         return space.w_None

Modified: pypy/branch/virtual-forcing/pypy/interpreter/pytraceback.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/interpreter/pytraceback.py	(original)
+++ pypy/branch/virtual-forcing/pypy/interpreter/pytraceback.py	Mon Dec  7 23:34:47 2009
@@ -49,7 +49,6 @@
         self.next = space.interp_w(PyTraceback, w_next, can_be_None=True)
 
 def record_application_traceback(space, operror, frame, last_instruction):
-    frame.force_f_back()
     if frame.pycode.hidden_applevel:
         return
     tb = operror.application_traceback

Modified: pypy/branch/virtual-forcing/pypy/interpreter/test/test_executioncontext.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/interpreter/test/test_executioncontext.py	(original)
+++ pypy/branch/virtual-forcing/pypy/interpreter/test/test_executioncontext.py	Mon Dec  7 23:34:47 2009
@@ -1,6 +1,5 @@
 import py
 from pypy.interpreter import executioncontext
-from pypy.interpreter.executioncontext import ExecutionContext
 from pypy.conftest import gettestobjspace
 
 class Finished(Exception):
@@ -220,542 +219,3 @@
         """)
         events = space.unwrap(w_events)
         assert [i[0] for i in events] == ['c_call', 'c_return', 'c_call']
-
-
-
-class TestFrameChaining(object):
-    class EC(ExecutionContext):
-        _some_frame = None
-        def __init__(self, jitted=False):
-            self.jitted = jitted
-            self.virtualizable = None
-            self.framestackdepth = 0
-            self._init_frame_chain()
-
-        def _we_are_jitted(self):
-            return self.jitted
-
-        def _get_some_frame(self):
-            if self._some_frame:
-                self._some_frame.look_at()
-            return self._some_frame
-        def _set_some_frame(self, frame):
-            if frame is not None:
-                frame.force()
-            self._some_frame = frame
-        some_frame = property(_get_some_frame, _set_some_frame)
-
-    class Frame(object):
-        _f_back_some = None
-        _f_forward = None
-
-        def __init__(self, ec, virtual_with_base_frame=None):
-            self.ec = ec
-            self.virtual_with_base_frame = virtual_with_base_frame
-            self.escaped = not virtual_with_base_frame
-            ExecutionContext._init_chaining_attributes(self)
-
-        def f_back(self):
-            return ExecutionContext._extract_back_from_frame(self)
-
-        def force_f_back(self):
-            return ExecutionContext._force_back_of_frame(self)
-
-        def force(self):
-            if not self.escaped:
-                self.virtual_with_base_frame = None
-                self.escaped = True
-                if self._f_back_some:
-                    self._f_back_some.force()
-                if self._f_forward:
-                    self._f_back_some.force()
-
-        def look_at(self):
-            if (not self.ec.jitted or
-                self.ec.virtualizable is not self.virtual_with_base_frame):
-                self.force()
-
-        def store_ref_to(self, other):
-            if (other.virtual_with_base_frame is not self and
-                other.virtual_with_base_frame is not self.virtual_with_base_frame):
-                other.force()
-
-        def _get_f_back_some(self):
-            self.look_at()
-            return self._f_back_some
-        def _set_f_back_some(self, frame):
-            self.look_at()
-            if frame:
-                frame.look_at()
-                self.store_ref_to(frame)
-            self._f_back_some = frame
-        f_back_some = property(_get_f_back_some, _set_f_back_some)
-        
-        def _get_f_forward(self):
-            self.look_at()
-            return self._f_forward
-        def _set_f_forward(self, frame):
-            self.look_at()
-            if frame:
-                frame.look_at()
-                self.store_ref_to(frame)
-            self._f_forward = frame
-        f_forward = property(_get_f_forward, _set_f_forward)
-
-    def test_f_back_no_jit(self):
-        ec = self.EC()
-        frame = self.Frame(ec)
-        frame2 = self.Frame(ec)
-        frame2.f_back_some = frame
-
-        frame3 = self.Frame(ec)
-        frame3.f_back_some = frame2
-
-        assert frame3.f_back() is frame2
-        assert frame2.f_back() is frame
-        assert frame.f_back() is None
-
-    def test_f_back_jit(self):
-        ec = self.EC()
-        frame = self.Frame(ec) # real frame
-        frame2 = self.Frame(ec) # virtual frame
-        frame2.f_back_some = frame
-        frame.f_forward = frame2
-
-        frame3 = self.Frame(ec) # virtual frame
-        frame3.f_back_some = frame
-        frame2.f_forward = frame3
-
-        assert frame3.f_back() is frame2
-        assert frame2.f_back() is frame
-        assert frame.f_back() is None
-
-        frame4 = self.Frame(ec) # real frame again
-        frame4.f_back_some = frame
-        assert frame4.f_back() is frame3
-
-    def test_gettopframe_no_jit(self):
-        ec = self.EC()
-        frame = self.Frame(ec)
-        ec.some_frame = frame
-        assert ec.gettopframe() is frame
-
-    def test_gettopframe_jit(self):
-        ec = self.EC()
-        frame = self.Frame(ec) # real frame
-        ec.some_frame = frame
-        assert ec.gettopframe() is frame
-
-        frame2 = self.Frame(ec) # virtual frame
-        frame2.f_back_some = frame
-        frame.f_forward = frame2
-        assert ec.gettopframe() is frame2
-
-        frame3 = self.Frame(ec) # virtual frame
-        frame3.f_back_some = frame
-        frame2.f_forward = frame3
-        assert ec.gettopframe() is frame3
-
-        frame4 = self.Frame(ec) # real frame again
-        frame4.f_back_some = frame
-        ec.some_frame = frame4
-        assert ec.gettopframe() is frame4
-
-    def test_frame_chain(self):
-
-        ec = self.EC()
-
-        assert ec.some_frame is None
-        assert ec.framestackdepth == 0
-
-        frame = self.Frame(ec)
-        ec._chain(frame)
-        assert ec.some_frame is frame
-        assert ec.framestackdepth == 1
-        assert frame.f_back_some is None
-        assert frame.f_forward is None
-        assert ec.gettopframe() is frame
-        assert ec._extract_back_from_frame(frame) is None
-        
-        frame2 = self.Frame(ec)
-        ec._chain(frame2)
-        assert ec.some_frame is frame2
-        assert ec.framestackdepth == 2
-        assert frame2.f_back_some is frame
-        assert frame.f_forward is None
-        assert frame2.f_forward is None
-        assert ec.gettopframe() is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-       
-        frame3 = self.Frame(ec)
-        ec._chain(frame3)
-        assert ec.some_frame is frame3
-        assert frame3.f_back_some is frame2
-        assert frame2.f_forward is None
-        assert ec.gettopframe() is frame3
-        assert ec._extract_back_from_frame(frame3) is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        assert frame3.f_back() is frame2
-        ec._unchain(frame3)
-        assert ec.some_frame is frame2
-        assert ec.framestackdepth == 2
-        assert frame2.f_forward is None
-        assert frame3.f_back_some is frame2
-        assert ec.gettopframe() is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-        
-        assert frame2.f_back() is frame
-        ec._unchain(frame2)
-        assert ec.some_frame is frame
-        assert ec.framestackdepth == 1
-        assert frame.f_forward is None
-        assert frame2.f_back_some is frame
-        assert ec.gettopframe() is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        assert frame.f_back() is None
-        ec._unchain(frame)
-        assert ec.some_frame is None
-        assert ec.framestackdepth == 0
-        assert frame.f_back_some is None
-        assert ec.gettopframe() is None
-
-    def test_frame_chain_forced(self):
-
-        ec = self.EC()
-
-        frame = self.Frame(ec)
-        ec._chain(frame)
-        assert ec.gettopframe() is frame
-        assert ec._extract_back_from_frame(frame) is None
-        
-        frame2 = self.Frame(ec)
-        ec._chain(frame2)
-        assert ec.some_frame is frame2
-        assert ec.framestackdepth == 2
-        assert frame2.f_back_some is frame
-        assert frame.f_forward is None
-        assert frame2.f_forward is None
-        res = frame2.force_f_back()
-        assert res is frame
-        assert frame.f_back_forced
-        assert ec.gettopframe() is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-        
-        frame3 = self.Frame(ec)
-        ec._chain(frame3)
-        assert ec.gettopframe() is frame3
-        assert ec._extract_back_from_frame(frame3) is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        assert frame3.f_back() is frame2
-        ec._unchain(frame3)
-        assert ec.some_frame is frame2
-        assert frame3.f_back_some is frame2
-        assert ec.gettopframe() is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-        
-        assert frame2.f_back() is frame
-        ec._unchain(frame2)
-        assert frame2.f_back_some is frame
-        assert ec.gettopframe() is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        assert frame.f_back() is None
-        ec._unchain(frame)
-        assert ec.some_frame is None
-        assert frame.f_back_some is None
-
-        assert frame2.f_back() is frame
-        assert frame.f_back() is None
-        assert ec.gettopframe() is None
-
-
-    def test_frame_chain_jitted(self):
-
-        ec = self.EC()
-
-        assert ec.some_frame is None
-        assert ec.framestackdepth == 0
-        assert ec.gettopframe() is None
-
-        frame = self.Frame(ec)
-        ec._chain(frame)
-        assert ec.some_frame is frame
-        assert ec.framestackdepth == 1
-        assert frame.f_back_some is None
-        assert frame.f_forward is None
-        assert ec.gettopframe() is frame
-        assert ec._extract_back_from_frame(frame) is None
-        
-        ec.jitted = True
-        ec.virtualizable = frame
-        frame2 = self.Frame(ec, frame)
-        ec._chain(frame2)
-        assert ec.some_frame is frame
-        assert ec.framestackdepth == 2
-        assert frame2.f_back_some is frame
-        assert frame.f_forward is frame2
-        assert frame2.f_forward is None
-        assert ec.gettopframe() is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        # recursive enter/leave seen by the jit
-        frame3 = self.Frame(ec, frame)
-        ec._chain(frame3)
-        assert ec.some_frame is frame
-        assert frame3.f_back_some is frame
-        assert frame2.f_forward is frame3
-        assert ec.gettopframe() is frame3
-        assert ec._extract_back_from_frame(frame3) is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        assert frame3.f_back() is frame2
-        ec._unchain(frame3)
-        assert ec.some_frame is frame
-        assert ec.framestackdepth == 2
-        assert frame2.f_forward is None
-        assert frame3.f_back_some is frame
-        assert not frame3.escaped
-        assert not frame2.escaped
-        assert ec.gettopframe() is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-       
-        # recursive enter/leave not seen by the jit
-        ec.jitted = False
-        ec.virtualizable = None
-        ec._chain(frame3)
-        assert not frame2.escaped
-        assert ec.some_frame is frame3
-        assert frame3.f_back_some is frame
-        assert frame2.f_forward is None
-        assert frame3.escaped
-        assert ec.gettopframe() is frame3
-        assert ec._extract_back_from_frame(frame3) is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        assert frame3.f_back() is frame2
-        ec._unchain(frame3)
-        assert ec.some_frame is frame
-        assert ec.framestackdepth == 2
-        assert frame2.f_forward is None
-        assert frame3.f_back_some is frame
-        assert ec.gettopframe() is frame2
-        assert ec._extract_back_from_frame(frame2) is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        ec.jitted = True
-        ec.virtualizable = frame
-
-        assert frame2.f_back() is frame
-        ec._unchain(frame2)
-        assert ec.some_frame is frame
-        assert ec.framestackdepth == 1
-        assert frame.f_forward is None
-        assert frame2.f_back_some is frame
-        assert ec.gettopframe() is frame
-        assert ec._extract_back_from_frame(frame) is None
-
-        ec.jitted = False
-        assert frame.f_back() is None
-        ec._unchain(frame)
-        assert ec.some_frame is None
-        assert ec.framestackdepth == 0
-        assert frame.f_back_some is None
-        assert ec.gettopframe() is None
-
-    @py.test.mark.xfail
-    def test_frame_chain_jitted_forced(self):
-
-        ec = self.EC()
-
-        assert ec.some_frame is None
-        assert ec.framestackdepth == 0
-
-        frame = self.Frame(ec)
-        ec._chain(frame)
-        
-        ec.jitted = True
-        frame2 = self.Frame(ec)
-        ec._chain(frame2)
-
-        # recursive enter/leave seen by the jit
-        frame3 = self.Frame(ec)
-        ec._chain(frame3)
-        assert ec.gettopframe() is frame3
-        res = frame3.force_f_back()
-        assert res is frame2
-        assert ec.gettopframe() is frame3
-
-        assert frame3.f_back() is frame2
-        ec._unchain(frame3)
-      
-        assert frame2.f_back() is frame
-        ec._unchain(frame2)
-        ec.jitted = False
-        assert frame.f_back() is None
-        ec._unchain(frame)
-
-        assert frame3.f_back() is frame2
-        assert frame2.f_back() is frame
-        assert frame.f_back() is None
-
-    def enter_two_jitted_levels(self):
-        ec = self.EC()
-
-        assert ec.some_frame is None
-        assert ec.framestackdepth == 0
-
-        frame = self.Frame(ec)
-        ec._chain(frame)
-        
-        ec.jitted = True
-        ec.virtualizable = frame
-        frame2 = self.Frame(ec, frame)
-        ec._chain(frame2)
-        assert not frame2.escaped
-        return ec, frame, frame2
-
-    def leave_two_jitted_levels(self, ec, frame, frame2):
-        assert frame2.f_back() is frame
-        ec._unchain(frame2)
-        ec.jitted = False
-        assert frame.f_back() is None
-        ec._unchain(frame)
-
-    
-    def test_check_escaping_all_inlined(self):
-        ec, frame, frame2 = self.enter_two_jitted_levels()
-
-        # recursive enter/leave seen by the jit
-        frame3 = self.Frame(ec, frame)
-        ec._chain(frame3)
-        assert not frame2.escaped
-        assert not frame3.escaped
-
-        assert frame3.f_back() is frame2
-        ec._unchain(frame3)
-        assert not frame2.escaped
-        self.leave_two_jitted_levels(ec, frame, frame2)
-      
-
-    def test_check_escaping_not_all_inlined_enter_leave_not_seen(self):
-        ec, frame, frame2 = self.enter_two_jitted_levels()
-
-        ec.jitted = False
-        # recursive enter/leave not seen by the jit
-        frame3 = self.Frame(ec)
-        ec._chain(frame3)
-
-        assert not frame2.escaped
-        assert frame3.escaped
-
-        ec._unchain(frame3)
-        ec.jitted = True
-        assert not frame2.escaped
-      
-        self.leave_two_jitted_levels(ec, frame, frame2)
-
-    def test_check_escaping_not_all_inlined_enter_leave_seen(self):
-        ec, frame, frame2 = self.enter_two_jitted_levels()
-
-        # recursive enter/leave seen by the jit
-        frame3 = self.Frame(ec, frame)
-        ec._chain(frame3)
-        ExecutionContext._jit_rechain_frame(ec, frame3)
-        ec.jitted = False
-        frame3.look_at()
-        assert not frame2.escaped
-        assert frame3.escaped
-
-        ec.jitted = True
-        assert frame3.f_back() is frame2
-        ec._unchain(frame3)
-        assert not frame2.escaped
-      
-        self.leave_two_jitted_levels(ec, frame, frame2)
-
-
-    def test_check_escaping_multi_non_jitted_levels(self):
-        ec, frame, frame2 = self.enter_two_jitted_levels()
-
-        # recursive enter/leave seen by the jit
-        frame3 = self.Frame(ec, frame)
-        ec._chain(frame3)
-        ExecutionContext._jit_rechain_frame(ec, frame3)
-        ec.jitted = False
-
-        assert frame3.escaped
-        assert not frame2.escaped
-        assert frame3.escaped
-
-        frame4 = self.Frame(ec)
-        ec._chain(frame4)
-        assert ec.framestackdepth == 4
-
-        ec._unchain(frame4)
-        assert frame3.escaped
-        assert not frame2.escaped
-
-        ec.jitted = True
-        assert frame3.f_back() is frame2
-        ec._unchain(frame3)
-        assert not frame2.escaped
-      
-        self.leave_two_jitted_levels(ec, frame, frame2)
-
-    def test_check_escaping_jitted_with_two_different_virtualizables(self):
-        ec, frame, frame2 = self.enter_two_jitted_levels()
-
-        frame3 = self.Frame(ec, frame)
-        ec._chain(frame3)
-        # frame3 is not inlined, but contains a loop itself, for which code has
-        # been generated
-        ExecutionContext._jit_rechain_frame(ec, frame3)
-        ec.virtualizable = frame3
-
-        frame3.look_at()
-        assert not frame2.escaped
-        assert frame3.escaped
-
-        frame4 = self.Frame(ec, frame3)
-        ec._chain(frame4)
-        assert ec.framestackdepth == 4
-        assert not frame4.escaped
-
-        ec._unchain(frame4)
-        assert frame3.escaped
-        assert not frame2.escaped
-
-        ec.virtualizable = frame
-
-        ec._unchain(frame3)
-        assert not frame2.escaped
-
-    def test_frame_top_is_virtualizable(self):
-        ec, frame, frame2 = self.enter_two_jitted_levels()
-        frame3 = self.Frame(ec, frame2)
-        ec.jitted = False
-        ec._chain(frame3)
-        ec.gettopframe()
-        frame3.force_f_back()
-        ec._unchain(frame3)
-        assert not frame2.f_forward
-        assert ec.gettopframe() is frame2
-        ec.jitted = True
-        ec._unchain(frame2)
-        assert not frame.f_forward
-        assert ec.gettopframe() is frame
-        ec._unchain(frame)
-        assert ec.gettopframe() is None

Modified: pypy/branch/virtual-forcing/pypy/module/_stackless/interp_coroutine.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/module/_stackless/interp_coroutine.py	(original)
+++ pypy/branch/virtual-forcing/pypy/module/_stackless/interp_coroutine.py	Mon Dec  7 23:34:47 2009
@@ -275,11 +275,10 @@
         return space.newtuple([])
     items = [None] * index
     f = self.subctx.topframe
-    f.force_f_back()
     while index > 0:
         index -= 1
         items[index] = space.wrap(f)
-        f = f.f_back()
+        f = f.f_backref()
     assert f is None
     return space.newtuple(items)
 

Modified: pypy/branch/virtual-forcing/pypy/module/pypyjit/interp_jit.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/module/pypyjit/interp_jit.py	(original)
+++ pypy/branch/virtual-forcing/pypy/module/pypyjit/interp_jit.py	Mon Dec  7 23:34:47 2009
@@ -21,7 +21,7 @@
 
 PyFrame._virtualizable2_ = ['last_instr', 'pycode',
                             'valuestackdepth', 'valuestack_w[*]',
-                            'fastlocals_w[*]', 'f_forward',
+                            'fastlocals_w[*]',
                             'last_exception',
                             ]
 

Modified: pypy/branch/virtual-forcing/pypy/module/sys/vm.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/module/sys/vm.py	(original)
+++ pypy/branch/virtual-forcing/pypy/module/sys/vm.py	Mon Dec  7 23:34:47 2009
@@ -31,7 +31,6 @@
                              space.wrap("frame index must not be negative"))
     ec = space.getexecutioncontext()
     f = ec.gettopframe_nohidden()
-    f.force_f_back()
     while True:
         if f is None:
             raise OperationError(space.w_ValueError,

Modified: pypy/branch/virtual-forcing/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/branch/virtual-forcing/pypy/objspace/flow/flowcontext.py	(original)
+++ pypy/branch/virtual-forcing/pypy/objspace/flow/flowcontext.py	Mon Dec  7 23:34:47 2009
@@ -5,6 +5,7 @@
 from pypy.interpreter.argument import ArgumentsForTranslation
 from pypy.objspace.flow.model import *
 from pypy.objspace.flow.framestate import FrameState
+from pypy.rlib import jit
 
 
 class OperationThatShouldNotBePropagatedError(OperationError):
@@ -260,8 +261,8 @@
             except StopFlowing:
                 continue   # restarting a dead SpamBlock
             try:
-                old_frame = self.some_frame
-                self.some_frame = frame
+                old_frameref = self.topframeref
+                self.topframeref = jit.non_virtual_ref(frame)
                 self.crnt_frame = frame
                 try:
                     w_result = frame.dispatch(frame.pycode,
@@ -269,7 +270,7 @@
                                               self)
                 finally:
                     self.crnt_frame = None
-                    self.some_frame = old_frame
+                    self.topframeref = old_frameref
 
             except OperationThatShouldNotBePropagatedError, e:
                 raise Exception(



More information about the Pypy-commit mailing list