[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