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);
196
196
197
197
/* --- _Py_EnterRecursiveCall() ----------------------------------------- */
198
198
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
-
218
199
static inline int _Py_MakeRecCheck (PyThreadState * tstate ) {
219
200
uintptr_t here_addr = _Py_get_machine_stack_pointer ();
220
201
_PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
@@ -249,12 +230,7 @@ PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState *tstate);
249
230
static inline int _Py_ReachedRecursionLimit (PyThreadState * tstate ) {
250
231
uintptr_t here_addr = _Py_get_machine_stack_pointer ();
251
232
_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 );
258
234
return here_addr <= _tstate -> c_stack_soft_limit ;
259
235
}
260
236
Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ extern "C" {
9
9
#endif
10
10
11
11
#include "pycore_typedefs.h" // _PyRuntimeState
12
+ #include "pycore_tstate.h"
12
13
13
14
14
15
// Values for PyThreadState.state. A thread must be in the "attached" state
@@ -296,6 +297,34 @@ _Py_AssertHoldsTstateFunc(const char *func)
296
297
#define _Py_AssertHoldsTstate ()
297
298
#endif
298
299
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
+
299
328
#ifdef __cplusplus
300
329
}
301
330
#endif
Original file line number Diff line number Diff line change @@ -26,17 +26,25 @@ PyAPI_DATA(int) (*PyOS_InputHook)(void);
26
26
* apart. In practice, that means it must be larger than the C
27
27
* stack consumption of PyEval_EvalDefault */
28
28
#if defined(_Py_ADDRESS_SANITIZER ) || defined(_Py_THREAD_SANITIZER )
29
- # define PYOS_STACK_MARGIN 4096
29
+ # define PYOS_LOG_STACK_MARGIN 12
30
30
#elif defined(Py_DEBUG ) && defined(WIN32 )
31
- # define PYOS_STACK_MARGIN 4096
31
+ # define PYOS_LOG_STACK_MARGIN 12
32
32
#elif defined(__wasi__ )
33
33
/* 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
35
35
#else
36
- # define PYOS_STACK_MARGIN 2048
36
+ # define PYOS_LOG_STACK_MARGIN 11
37
37
#endif
38
+ #define PYOS_STACK_MARGIN (1 << PYOS_LOG_STACK_MARGIN)
38
39
#define PYOS_STACK_MARGIN_BYTES (PYOS_STACK_MARGIN * sizeof(void *))
39
40
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
+
40
48
#if defined(WIN32 )
41
49
#define USE_STACKCHECK
42
50
#endif
Original file line number Diff line number Diff line change @@ -3015,7 +3015,8 @@ _Py_Dealloc(PyObject *op)
3015
3015
PyTypeObject * type = Py_TYPE (op );
3016
3016
destructor dealloc = type -> tp_dealloc ;
3017
3017
PyThreadState * tstate = _PyThreadState_GET ();
3018
- if (_Py_ReachedRecursionLimitWithMargin (tstate , 2 )) {
3018
+ intptr_t margin = _Py_RecursionLimit_GetMargin (tstate );
3019
+ if (margin < 2 ) {
3019
3020
_PyTrash_thread_deposit_object (tstate , (PyObject * )op );
3020
3021
return ;
3021
3022
}
@@ -3061,7 +3062,7 @@ _Py_Dealloc(PyObject *op)
3061
3062
Py_XDECREF (old_exc );
3062
3063
Py_DECREF (type );
3063
3064
#endif
3064
- if (tstate -> delete_later && ! _Py_ReachedRecursionLimitWithMargin ( tstate , 4 ) ) {
3065
+ if (tstate -> delete_later && margin >= 4 ) {
3065
3066
_PyTrash_thread_destroy_chain (tstate );
3066
3067
}
3067
3068
}
Original file line number Diff line number Diff line change @@ -476,12 +476,6 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
476
476
_PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
477
477
uintptr_t here_addr = _Py_get_machine_stack_pointer ();
478
478
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
- }
485
479
assert (_tstate -> c_stack_hard_limit != 0 );
486
480
if (here_addr < _tstate -> c_stack_hard_limit ) {
487
481
/* 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)
2132
2132
if (current_fast_get () != NULL ) {
2133
2133
Py_FatalError ("non-NULL old thread state" );
2134
2134
}
2135
-
2135
+ _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
2136
+ if (_tstate -> c_stack_hard_limit == 0 ) {
2137
+ _Py_InitializeRecursionLimits (tstate );
2138
+ }
2136
2139
2137
2140
while (1 ) {
2138
2141
_PyEval_AcquireLock (tstate );
You can’t perform that action at this time.
0 commit comments