Author: fijal Branch: Changeset: r83486:56c0228015a1 Date: 2016-04-01 12:01 +0200 http://bitbucket.org/pypy/pypy/changeset/56c0228015a1/
Log: backout the merge of the branch we need to think more about diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -277,9 +277,18 @@ raise NotImplementedError def get_traceback(self): - """Get the PyTraceback object, for app-level Python code. + """Calling this marks the PyTraceback as escaped, i.e. it becomes + accessible and inspectable by app-level Python code. For the JIT. + Note that this has no effect if there are already several traceback + frames recorded, because in this case they are already marked as + escaping by executioncontext.leave() being called with + got_exception=True. """ - return self._application_traceback + from pypy.interpreter.pytraceback import PyTraceback + tb = self._application_traceback + if tb is not None and isinstance(tb, PyTraceback): + tb.frame.mark_as_escaped() + return tb def set_traceback(self, traceback): """Set the current traceback.""" diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -74,6 +74,15 @@ finally: frame_vref = self.topframeref self.topframeref = frame.f_backref + if frame.escaped or got_exception: + # if this frame escaped to applevel, we must ensure that also + # f_back does + f_back = frame.f_backref() + if f_back: + f_back.mark_as_escaped() + # force the frame (from the JIT point of view), so that it can + # be accessed also later + frame_vref() jit.virtual_ref_finish(frame_vref, frame) # ________________________________________________________________ diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -65,6 +65,7 @@ last_exception = None f_backref = jit.vref_None + escaped = False # see mark_as_escaped() debugdata = None pycode = None # code object executed by that frame @@ -151,6 +152,15 @@ assert isinstance(cell, Cell) return cell + def mark_as_escaped(self): + """ + Must be called on frames that are exposed to applevel, e.g. by + sys._getframe(). This ensures that the virtualref holding the frame + is properly forced by ec.leave(), and thus the frame will be still + accessible even after the corresponding C stack died. + """ + self.escaped = True + def append_block(self, block): assert block.previous is self.lastblock self.lastblock = block diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -37,6 +37,7 @@ raise OperationError(space.w_ValueError, space.wrap("call stack is not deep enough")) if depth == 0: + f.mark_as_escaped() return space.wrap(f) depth -= 1 f = ec.getnextframe_nohidden(f) diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py --- a/rpython/rlib/jit.py +++ b/rpython/rlib/jit.py @@ -475,6 +475,8 @@ def __call__(self): if self._state == 'non-forced': self._state = 'forced' + elif self._state == 'invalid': + raise InvalidVirtualRef return self._x @property @@ -485,7 +487,7 @@ def _finish(self): if self._state == 'non-forced': - self._state = 'forgotten' + self._state = 'invalid' class DirectJitVRef(DirectVRef): def __init__(self, x): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit