[3.12] GH-107263: Increase C stack limit for most functions, except _PyEval_EvalFrameDefault() (GH-107535) (#107618)

GH-107263: Increase C stack limit for most functions, except `_PyEval_EvalFrameDefault()` (GH-107535)

* Set C recursion limit to 1500, set cost of eval loop to 2 frames, and compiler mutliply to 2.
(cherry picked from commit fa45958450)

Co-authored-by: Mark Shannon <mark@hotpy.org>
This commit is contained in:
Miss Islington (bot) 2023-08-04 03:25:51 -07:00 committed by GitHub
parent 58af2293c5
commit 98902d6c05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 57 additions and 45 deletions

2
Python/Python-ast.c generated
View file

@ -13074,7 +13074,7 @@ PyObject* PyAST_mod2obj(mod_ty t)
int starting_recursion_depth;
/* Be careful here to prevent overflow. */
int COMPILER_STACK_FRAME_SCALE = 3;
int COMPILER_STACK_FRAME_SCALE = 2;
PyThreadState *tstate = _PyThreadState_GET();
if (!tstate) {
return 0;

View file

@ -1029,7 +1029,7 @@ validate_type_params(struct validator *state, asdl_type_param_seq *tps)
/* See comments in symtable.c. */
#define COMPILER_STACK_FRAME_SCALE 3
#define COMPILER_STACK_FRAME_SCALE 2
int
_PyAST_Validate(mod_ty mod)

View file

@ -1103,7 +1103,7 @@ astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimizeState *stat
#undef CALL_SEQ
/* See comments in symtable.c. */
#define COMPILER_STACK_FRAME_SCALE 3
#define COMPILER_STACK_FRAME_SCALE 2
int
_PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state)

View file

@ -635,7 +635,7 @@ dummy_func(
tstate->cframe = cframe.previous;
assert(tstate->cframe->current_frame == frame->previous);
assert(!_PyErr_Occurred(tstate));
_Py_LeaveRecursiveCallTstate(tstate);
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
return retval;
}

View file

@ -637,6 +637,11 @@ static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) {
# pragma warning(disable:4102)
#endif
/* _PyEval_EvalFrameDefault() is a *big* function,
* so consume 3 units of C stack */
#define PY_EVAL_C_STACK_UNITS 2
PyObject* _Py_HOT_FUNCTION
_PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag)
{
@ -691,6 +696,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
frame->previous = &entry_frame;
cframe.current_frame = frame;
tstate->c_recursion_remaining -= (PY_EVAL_C_STACK_UNITS - 1);
if (_Py_EnterRecursiveCallTstate(tstate, "")) {
tstate->c_recursion_remaining--;
tstate->py_recursion_remaining--;
@ -990,7 +996,7 @@ exit_unwind:
/* Restore previous cframe and exit */
tstate->cframe = cframe.previous;
assert(tstate->cframe->current_frame == frame->previous);
_Py_LeaveRecursiveCallTstate(tstate);
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
return NULL;
}

View file

@ -922,7 +922,7 @@
tstate->cframe = cframe.previous;
assert(tstate->cframe->current_frame == frame->previous);
assert(!_PyErr_Occurred(tstate));
_Py_LeaveRecursiveCallTstate(tstate);
tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS;
return retval;
#line 928 "Python/generated_cases.c.h"
}

View file

@ -282,17 +282,10 @@ symtable_new(void)
return NULL;
}
/* When compiling the use of C stack is probably going to be a lot
lighter than when executing Python code but still can overflow
and causing a Python crash if not checked (e.g. eval("()"*300000)).
Using the current recursion limit for the compiler seems too
restrictive (it caused at least one test to fail) so a factor is
used to allow deeper recursion when compiling an expression.
Using a scaling factor means this should automatically adjust when
/* Using a scaling factor means this should automatically adjust when
the recursion limit is adjusted for small or large C stack allocations.
*/
#define COMPILER_STACK_FRAME_SCALE 3
#define COMPILER_STACK_FRAME_SCALE 2
struct symtable *
_PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future)