[pypy-commit] pypy default: Hard to test: add rstack.stack_almost_full() and use it:
arigo
pypy.commits at gmail.com
Thu Feb 2 08:35:27 EST 2017
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r89898:c48c3b08c41f
Date: 2017-02-02 14:34 +0100
http://bitbucket.org/pypy/pypy/changeset/c48c3b08c41f/
Log: Hard to test: add rstack.stack_almost_full() and use it:
* to not start JITting when the stack is almost full
* to propagate (instead of catching) a RuntimeError caused by stack
overflow as long as the stack is still almost full
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -7,7 +7,7 @@
from rpython.rlib import jit
from rpython.rlib.objectmodel import we_are_translated, specialize
-from rpython.rlib import rstackovf
+from rpython.rlib import rstack, rstackovf
from pypy.interpreter import debug
@@ -55,6 +55,7 @@
"Check if this is an exception that should better not be caught."
return (self.match(space, space.w_SystemExit) or
self.match(space, space.w_KeyboardInterrupt))
+ # note: an extra case is added in OpErrFmtNoArgs
def __str__(self):
"NOT_RPYTHON: Convenience for tracebacks."
@@ -387,6 +388,16 @@
def _compute_value(self, space):
return self._value
+ def async(self, space):
+ # also matches a RuntimeError("maximum rec.") if the stack is
+ # still almost full, because in this case it might be a better
+ # idea to propagate the exception than eat it
+ if (self.w_type is space.w_RuntimeError and
+ self._value == "maximum recursion depth exceeded" and
+ rstack.stack_almost_full()):
+ return True
+ return OperationError.async(self, space)
+
@specialize.memo()
def get_operr_class(valuefmt):
try:
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -88,6 +88,7 @@
'interp_magic.save_module_content_for_future_reload',
'decode_long' : 'interp_magic.decode_long',
'_promote' : 'interp_magic._promote',
+ 'stack_almost_full' : 'interp_magic.stack_almost_full',
}
if sys.platform == 'win32':
interpleveldefs['get_console_cp'] = 'interp_magic.get_console_cp'
diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -9,7 +9,7 @@
from pypy.objspace.std.setobject import W_BaseSetObject
from pypy.objspace.std.typeobject import MethodCache
from pypy.objspace.std.mapdict import MapAttrCache
-from rpython.rlib import rposix, rgc
+from rpython.rlib import rposix, rgc, rstack
def internal_repr(space, w_object):
@@ -190,3 +190,7 @@
else:
jit.promote(w_obj)
return w_obj
+
+def stack_almost_full(space):
+ """Return True if the stack is more than 15/16th full."""
+ return space.wrap(rstack.stack_almost_full())
diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -732,7 +732,8 @@
TY_FLOAT = 0x06
def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd):
- if self.must_compile(deadframe, metainterp_sd, jitdriver_sd):
+ if (self.must_compile(deadframe, metainterp_sd, jitdriver_sd)
+ and not rstack.stack_almost_full()):
self.start_compiling()
try:
self._trace_and_compile_from_bridge(deadframe, metainterp_sd,
diff --git a/rpython/jit/metainterp/warmstate.py b/rpython/jit/metainterp/warmstate.py
--- a/rpython/jit/metainterp/warmstate.py
+++ b/rpython/jit/metainterp/warmstate.py
@@ -11,6 +11,7 @@
from rpython.rlib.objectmodel import specialize, we_are_translated, r_dict
from rpython.rlib.rarithmetic import intmask, r_uint
from rpython.rlib.unroll import unrolling_iterable
+from rpython.rlib import rstack
from rpython.rtyper.annlowlevel import (hlstr, cast_base_ptr_to_instance,
cast_object_to_ptr)
from rpython.rtyper.lltypesystem import lltype, llmemory, rstr, rffi
@@ -415,6 +416,8 @@
if not confirm_enter_jit(*args):
return
jitcounter.decay_all_counters()
+ if rstack.stack_almost_full():
+ return
# start tracing
from rpython.jit.metainterp.pyjitpl import MetaInterp
metainterp = MetaInterp(metainterp_sd, jitdriver_sd)
diff --git a/rpython/rlib/rstack.py b/rpython/rlib/rstack.py
--- a/rpython/rlib/rstack.py
+++ b/rpython/rlib/rstack.py
@@ -69,3 +69,22 @@
raise _StackOverflow
stack_check_slowpath._dont_inline_ = True
stack_check_slowpath._dont_insert_stackcheck_ = True
+
+def stack_almost_full():
+ """Return True if the stack is more than 15/16th full."""
+ if not we_are_translated():
+ return False
+ # see stack_check()
+ current = llop.stack_current(lltype.Signed)
+ end = _stack_get_end()
+ length = 15 * (r_uint(_stack_get_length()) >> 4)
+ ofs = r_uint(end - current)
+ if ofs <= length:
+ return False # fine
+ else:
+ _stack_too_big_slowpath(current) # this might update the stack end
+ end = _stack_get_end()
+ ofs = r_uint(end - current)
+ return ofs > length
+stack_almost_full._dont_insert_stackcheck_ = True
+stack_almost_full._jit_look_inside_ = False
More information about the pypy-commit
mailing list