@@ -424,31 +424,26 @@ int pthread_attr_destroy(pthread_attr_t *a)
424424
425425#endif
426426
427-
428- void
429- _Py_InitializeRecursionLimits (PyThreadState * tstate )
427+ static void
428+ hardware_stack_limits (uintptr_t * top , uintptr_t * base )
430429{
431- _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
432430#ifdef WIN32
433431 ULONG_PTR low , high ;
434432 GetCurrentThreadStackLimits (& low , & high );
435- _tstate -> c_stack_top = (uintptr_t )high ;
433+ * top = (uintptr_t )high ;
436434 ULONG guarantee = 0 ;
437435 SetThreadStackGuarantee (& guarantee );
438- _tstate -> c_stack_hard_limit = ((uintptr_t )low ) + guarantee + _PyOS_STACK_MARGIN_BYTES ;
439- _tstate -> c_stack_soft_limit = _tstate -> c_stack_hard_limit + _PyOS_STACK_MARGIN_BYTES ;
436+ * base = (uintptr_t )low + guarantee ;
440437#elif defined(__APPLE__ )
441438 pthread_t this_thread = pthread_self ();
442439 void * stack_addr = pthread_get_stackaddr_np (this_thread ); // top of the stack
443440 size_t stack_size = pthread_get_stacksize_np (this_thread );
444- _tstate -> c_stack_top = (uintptr_t )stack_addr ;
445- _tstate -> c_stack_hard_limit = _tstate -> c_stack_top - stack_size ;
446- _tstate -> c_stack_soft_limit = _tstate -> c_stack_hard_limit + _PyOS_STACK_MARGIN_BYTES ;
441+ * top = (uintptr_t )stack_addr ;
442+ * base = ((uintptr_t )stack_addr ) - stack_size ;
447443#else
448- uintptr_t here_addr = _Py_get_machine_stack_pointer ();
449- /// XXX musl supports HAVE_PTHRED_GETATTR_NP, but the resulting stack size
450- /// (on alpine at least) is much smaller than expected and imposes undue limits
451- /// compared to the old stack size estimation. (We assume musl is not glibc.)
444+ /// XXX musl supports HAVE_PTHRED_GETATTR_NP, but the resulting stack size
445+ /// (on alpine at least) is much smaller than expected and imposes undue limits
446+ /// compared to the old stack size estimation. (We assume musl is not glibc.)
452447# if defined(HAVE_PTHREAD_GETATTR_NP ) && !defined(_AIX ) && \
453448 !defined(__NetBSD__ ) && (defined(__GLIBC__ ) || !defined(__linux__ ))
454449 size_t stack_size , guard_size ;
@@ -461,26 +456,35 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
461456 err |= pthread_attr_destroy (& attr );
462457 }
463458 if (err == 0 ) {
464- uintptr_t base = ((uintptr_t )stack_addr ) + guard_size ;
465- _tstate -> c_stack_top = base + stack_size ;
466- #ifdef _Py_THREAD_SANITIZER
467- // Thread sanitizer crashes if we use a bit more than half the stack.
468- _tstate -> c_stack_soft_limit = base + (stack_size / 2 );
469- #else
470- _tstate -> c_stack_soft_limit = base + _PyOS_STACK_MARGIN_BYTES * 2 ;
471- #endif
472- _tstate -> c_stack_hard_limit = base + _PyOS_STACK_MARGIN_BYTES ;
473- assert (_tstate -> c_stack_soft_limit < here_addr );
474- assert (here_addr < _tstate -> c_stack_top );
459+ * base = ((uintptr_t )stack_addr ) + guard_size ;
460+ * top = (uintptr_t )stack_addr + stack_size ;
475461 return ;
476462 }
477463# endif
478- _tstate -> c_stack_top = _Py_SIZE_ROUND_UP (here_addr , 4096 );
479- _tstate -> c_stack_soft_limit = _tstate -> c_stack_top - Py_C_STACK_SIZE ;
480- _tstate -> c_stack_hard_limit = _tstate -> c_stack_top - (Py_C_STACK_SIZE + _PyOS_STACK_MARGIN_BYTES );
464+ uintptr_t here_addr = _Py_get_machine_stack_pointer ();
465+ uintptr_t top_addr = _Py_SIZE_ROUND_UP (here_addr , 4096 );
466+ * top = top_addr ;
467+ * base = top_addr - Py_C_STACK_SIZE ;
481468#endif
482469}
483470
471+ void
472+ _Py_InitializeRecursionLimits (PyThreadState * tstate )
473+ {
474+ uintptr_t top ;
475+ uintptr_t base ;
476+ hardware_stack_limits (& top , & base );
477+ #ifdef _Py_THREAD_SANITIZER
478+ // Thread sanitizer crashes if we use more than half the stack.
479+ uintptr_t stacksize = top - base ;
480+ base += stacksize /2 ;
481+ #endif
482+ _PyThreadStateImpl * _tstate = (_PyThreadStateImpl * )tstate ;
483+ _tstate -> c_stack_top = top ;
484+ _tstate -> c_stack_hard_limit = base + _PyOS_STACK_MARGIN_BYTES ;
485+ _tstate -> c_stack_soft_limit = base + _PyOS_STACK_MARGIN_BYTES * 2 ;
486+ }
487+
484488/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
485489 if the recursion_depth reaches recursion_limit. */
486490int
0 commit comments