File tree Expand file tree Collapse file tree 6 files changed +49
-38
lines changed
Expand file tree Collapse file tree 6 files changed +49
-38
lines changed Original file line number Diff line number Diff line change @@ -196,25 +196,6 @@ extern void _PyEval_DeactivateOpCache(void);
196196
197197/* --- _Py_EnterRecursiveCall() ----------------------------------------- */
198198
199- #if !_Py__has_builtin (__builtin_frame_address ) && !defined(_MSC_VER )
200- static uintptr_t return_pointer_as_int (char * p ) {
201- return (uintptr_t )p ;
202- }
203- #endif
204-
205- static inline uintptr_t
206- _Py_get_machine_stack_pointer (void ) {
207- #if _Py__has_builtin (__builtin_frame_address )
208- return (uintptr_t )__builtin_frame_address (0 );
209- #elif defined(_MSC_VER )
210- return (uintptr_t )_AddressOfReturnAddress ();
211- #else
212- char here ;
213- /* Avoid compiler warning about returning stack address */
214- return return_pointer_as_int (& here );
215- #endif
216- }
217-
218199static inline int _Py_MakeRecCheck (PyThreadState * tstate ) {
219200 uintptr_t here_addr = _Py_get_machine_stack_pointer ();
220201 _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
@@ -249,12 +230,7 @@ PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState *tstate);
249230static inline int _Py_ReachedRecursionLimit (PyThreadState * tstate ) {
250231 uintptr_t here_addr = _Py_get_machine_stack_pointer ();
251232 _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
252- if (here_addr > _tstate -> c_stack_soft_limit ) {
253- return 0 ;
254- }
255- if (_tstate -> c_stack_hard_limit == 0 ) {
256- _Py_InitializeRecursionLimits (tstate );
257- }
233+ assert (_tstate -> c_stack_hard_limit != 0 );
258234 return here_addr <= _tstate -> c_stack_soft_limit ;
259235}
260236
Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ extern "C" {
99#endif
1010
1111#include "pycore_typedefs.h" // _PyRuntimeState
12+ #include "pycore_tstate.h"
1213
1314
1415// Values for PyThreadState.state. A thread must be in the "attached" state
@@ -296,6 +297,34 @@ _Py_AssertHoldsTstateFunc(const char *func)
296297#define _Py_AssertHoldsTstate ()
297298#endif
298299
300+ #if !_Py__has_builtin (__builtin_frame_address ) && !defined(_MSC_VER )
301+ static uintptr_t return_pointer_as_int (char * p ) {
302+ return (uintptr_t )p ;
303+ }
304+ #endif
305+
306+ static inline uintptr_t
307+ _Py_get_machine_stack_pointer (void ) {
308+ #if _Py__has_builtin (__builtin_frame_address )
309+ return (uintptr_t )__builtin_frame_address (0 );
310+ #elif defined(_MSC_VER )
311+ return (uintptr_t )_AddressOfReturnAddress ();
312+ #else
313+ char here ;
314+ /* Avoid compiler warning about returning stack address */
315+ return return_pointer_as_int (& here );
316+ #endif
317+ }
318+
319+ static inline intptr_t
320+ _Py_RecursionLimit_GetMargin (PyThreadState * tstate )
321+ {
322+ _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
323+ assert (_tstate -> c_stack_hard_limit != 0 );
324+ intptr_t here_addr = _Py_get_machine_stack_pointer ();
325+ return Py_ARITHMETIC_RIGHT_SHIFT (intptr_t , here_addr - (intptr_t )_tstate -> c_stack_soft_limit , PYOS_STACK_MARGIN_SHIFT );
326+ }
327+
299328#ifdef __cplusplus
300329}
301330#endif
Original file line number Diff line number Diff line change @@ -26,17 +26,25 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void);
2626 * apart. In practice, that means it must be larger than the C
2727 * stack consumption of PyEval_EvalDefault */
2828#if defined(_Py_ADDRESS_SANITIZER ) || defined(_Py_THREAD_SANITIZER )
29- # define PYOS_STACK_MARGIN 4096
29+ # define PYOS_LOG_STACK_MARGIN 12
3030#elif defined(Py_DEBUG ) && defined(WIN32 )
31- # define PYOS_STACK_MARGIN 4096
31+ # define PYOS_LOG_STACK_MARGIN 12
3232#elif defined(__wasi__ )
3333 /* Web assembly has two stacks, so this isn't really a size */
34- # define PYOS_STACK_MARGIN 500
34+ # define PYOS_LOG_STACK_MARGIN 9
3535#else
36- # define PYOS_STACK_MARGIN 2048
36+ # define PYOS_LOG_STACK_MARGIN 11
3737#endif
38+ #define PYOS_STACK_MARGIN (1 << PYOS_LOG_STACK_MARGIN)
3839#define PYOS_STACK_MARGIN_BYTES (PYOS_STACK_MARGIN * sizeof(void *))
3940
41+ #if SIZEOF_VOID_P == 8
42+ #define PYOS_STACK_MARGIN_SHIFT (PYOS_LOG_STACK_MARGIN + 3)
43+ #else
44+ #define PYOS_STACK_MARGIN_SHIFT (PYOS_LOG_STACK_MARGIN + 2)
45+ #endif
46+
47+
4048#if defined(WIN32 )
4149#define USE_STACKCHECK
4250#endif
Original file line number Diff line number Diff line change @@ -3015,7 +3015,8 @@ _Py_Dealloc(PyObject *op)
30153015 PyTypeObject * type = Py_TYPE (op );
30163016 destructor dealloc = type -> tp_dealloc ;
30173017 PyThreadState * tstate = _PyThreadState_GET ();
3018- if (_Py_ReachedRecursionLimitWithMargin (tstate , 2 )) {
3018+ intptr_t margin = _Py_RecursionLimit_GetMargin (tstate );
3019+ if (margin < 2 ) {
30193020 _PyTrash_thread_deposit_object (tstate , (PyObject * )op );
30203021 return ;
30213022 }
@@ -3061,7 +3062,7 @@ _Py_Dealloc(PyObject *op)
30613062 Py_XDECREF (old_exc );
30623063 Py_DECREF (type );
30633064#endif
3064- if (tstate -> delete_later && ! _Py_ReachedRecursionLimitWithMargin ( tstate , 4 ) ) {
3065+ if (tstate -> delete_later && margin >= 4 ) {
30653066 _PyTrash_thread_destroy_chain (tstate );
30663067 }
30673068}
Original file line number Diff line number Diff line change @@ -476,12 +476,6 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
476476 _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
477477 uintptr_t here_addr = _Py_get_machine_stack_pointer ();
478478 assert (_tstate -> c_stack_soft_limit != 0 );
479- if (_tstate -> c_stack_hard_limit == 0 ) {
480- _Py_InitializeRecursionLimits (tstate );
481- }
482- if (here_addr >= _tstate -> c_stack_soft_limit ) {
483- return 0 ;
484- }
485479 assert (_tstate -> c_stack_hard_limit != 0 );
486480 if (here_addr < _tstate -> c_stack_hard_limit ) {
487481 /* Overflowing while handling an overflow. Give up. */
Original file line number Diff line number Diff line change @@ -2132,7 +2132,10 @@ _PyThreadState_Attach(PyThreadState *tstate)
21322132 if (current_fast_get () != NULL ) {
21332133 Py_FatalError ("non-NULL old thread state" );
21342134 }
2135-
2135+ _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
2136+ if (_tstate -> c_stack_hard_limit == 0 ) {
2137+ _Py_InitializeRecursionLimits (tstate );
2138+ }
21362139
21372140 while (1 ) {
21382141 _PyEval_AcquireLock (tstate );
You can’t perform that action at this time.
0 commit comments