Commit 715ace3a authored by Kevin Modzelewski's avatar Kevin Modzelewski Committed by Kevin Modzelewski

Improve recursion-depth checking a bit

Main difference is lowering the recursion-depth on unoptimized
builds, since we need more stack space per python frame.
parent 332539dd
...@@ -452,6 +452,8 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b ...@@ -452,6 +452,8 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
Box* ASTInterpreter::execute(ASTInterpreter& interpreter, CFGBlock* start_block, BST_stmt* start_at) { Box* ASTInterpreter::execute(ASTInterpreter& interpreter, CFGBlock* start_block, BST_stmt* start_at) {
UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_interpreter"); UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_interpreter");
RECURSIVE_BLOCK(CXX, " in function call");
return executeInnerAndSetupFrame(interpreter, start_block, start_at); return executeInnerAndSetupFrame(interpreter, start_block, start_at);
} }
......
...@@ -628,7 +628,15 @@ extern "C" PyObject* PyExceptionInstance_Class(PyObject* o) noexcept { ...@@ -628,7 +628,15 @@ extern "C" PyObject* PyExceptionInstance_Class(PyObject* o) noexcept {
return PyInstance_Check(o) ? (Box*)static_cast<BoxedInstance*>(o)->inst_cls : o->cls; return PyInstance_Check(o) ? (Box*)static_cast<BoxedInstance*>(o)->inst_cls : o->cls;
} }
// With optimizations turned off, we can handle much fewer Python stack frames
// in the same amount of C-stack space.
// Use NDEBUG as a proxy for whether optimizations are turned on.
#ifndef NDEBUG
#define Py_DEFAULT_RECURSION_LIMIT 300
#else
#define Py_DEFAULT_RECURSION_LIMIT 1000 #define Py_DEFAULT_RECURSION_LIMIT 1000
#endif
static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT; static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
extern "C" { extern "C" {
int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT; int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
......
...@@ -4747,7 +4747,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe ...@@ -4747,7 +4747,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
template <ExceptionStyle S> template <ExceptionStyle S>
static Box* callChosenCF(CompiledFunction* chosen_cf, BoxedClosure* closure, BoxedGenerator* generator, Box* globals, static Box* callChosenCF(CompiledFunction* chosen_cf, BoxedClosure* closure, BoxedGenerator* generator, Box* globals,
Box* oarg1, Box* oarg2, Box* oarg3, Box** oargs) noexcept(S == CAPI) { Box* oarg1, Box* oarg2, Box* oarg3, Box** oargs) noexcept(S == CAPI) {
// TODO: this should be done in the rewrite as well // TODO: this should go into the emitted code
RECURSIVE_BLOCK(S, " in function call"); RECURSIVE_BLOCK(S, " in function call");
if (S != chosen_cf->exception_style) { if (S != chosen_cf->exception_style) {
......
# skip-if: '-n' not in EXTRA_JIT_ARGS and '-O' not in EXTRA_JIT_ARGS
# disable this test because the interpreter (with disabled bjit) currently uses too much stack
# Make sure we can recurse at least 900 times on the three different types # Make sure we can recurse at least 900 times on the three different types
# of stacks that we have: # of stacks that we have:
import sys
TEST_DEPTH = sys.getrecursionlimit() - 20
def recurse(n): def recurse(n):
print n
if n > 0: if n > 0:
return recurse(n - 1) return recurse(n - 1)
return n return n
print "Recursing on main thread..." print "Recursing on main thread..."
recurse(900) recurse(TEST_DEPTH)
print "Recursing in a generator..." print "Recursing in a generator..."
def gen(): def gen():
yield recurse(900) yield recurse(TEST_DEPTH)
print list(gen()) print list(gen())
print "Recursing in a thread..." print "Recursing in a thread..."
...@@ -26,10 +25,17 @@ done = 0 ...@@ -26,10 +25,17 @@ done = 0
def thread_target(): def thread_target():
global done global done
recurse(900) recurse(TEST_DEPTH)
done = 1 done = 1
start_new_thread(thread_target, ()) start_new_thread(thread_target, ())
while not done: while not done:
time.sleep(0.001) time.sleep(0.001)
s = """
if depth < TEST_DEPTH:
depth += 1
exec s
"""
exec s in {'depth': 0, 's': s, 'TEST_DEPTH': TEST_DEPTH}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment