Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

#include "pycore_pythonrun.h" // _PYOS_STACK_MARGIN_SHIFT
#include "pycore_typedefs.h" // _PyRuntimeState
#include "pycore_tstate.h"

Expand Down Expand Up @@ -325,7 +326,7 @@ _Py_RecursionLimit_GetMargin(PyThreadState *tstate)
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
assert(_tstate->c_stack_hard_limit != 0);
intptr_t here_addr = _Py_get_machine_stack_pointer();
return Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, here_addr - (intptr_t)_tstate->c_stack_soft_limit, PYOS_STACK_MARGIN_SHIFT);
return Py_ARITHMETIC_RIGHT_SHIFT(intptr_t, here_addr - (intptr_t)_tstate->c_stack_soft_limit, _PYOS_STACK_MARGIN_SHIFT);
}

#ifdef __cplusplus
Expand Down
22 changes: 22 additions & 0 deletions Include/internal/pycore_pythonrun.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,28 @@ extern const char* _Py_SourceAsString(
PyCompilerFlags *cf,
PyObject **cmd_copy);


/* Stack size, in "pointers". This must be large enough, so
* no two calls to check recursion depth are more than this far
* apart. In practice, that means it must be larger than the C
* stack consumption of PyEval_EvalDefault */
#if defined(_Py_ADDRESS_SANITIZER) || defined(_Py_THREAD_SANITIZER)
# define _PYOS_LOG2_STACK_MARGIN 12
#elif defined(Py_DEBUG) && defined(WIN32)
# define _PYOS_LOG2_STACK_MARGIN 12
#else
# define _PYOS_LOG2_STACK_MARGIN 11
#endif
#define _PYOS_STACK_MARGIN (1 << _PYOS_LOG2_STACK_MARGIN)
#define _PYOS_STACK_MARGIN_BYTES (_PYOS_STACK_MARGIN * sizeof(void *))

#if SIZEOF_VOID_P == 8
# define _PYOS_STACK_MARGIN_SHIFT (_PYOS_LOG2_STACK_MARGIN + 3)
#else
# define _PYOS_STACK_MARGIN_SHIFT (_PYOS_LOG2_STACK_MARGIN + 2)
#endif


#ifdef __cplusplus
}
#endif
Expand Down
25 changes: 2 additions & 23 deletions Include/pythonrun.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,15 @@ PyAPI_FUNC(void) PyErr_DisplayException(PyObject *);
/* Stuff with no proper home (yet) */
PyAPI_DATA(int) (*PyOS_InputHook)(void);

/* Stack size, in "pointers". This must be large enough, so
* no two calls to check recursion depth are more than this far
* apart. In practice, that means it must be larger than the C
* stack consumption of PyEval_EvalDefault */
#if defined(_Py_ADDRESS_SANITIZER) || defined(_Py_THREAD_SANITIZER)
# define PYOS_LOG2_STACK_MARGIN 12
#elif defined(Py_DEBUG) && defined(WIN32)
# define PYOS_LOG2_STACK_MARGIN 12
#else
# define PYOS_LOG2_STACK_MARGIN 11
#endif
#define PYOS_STACK_MARGIN (1 << PYOS_LOG2_STACK_MARGIN)
#define PYOS_STACK_MARGIN_BYTES (PYOS_STACK_MARGIN * sizeof(void *))

#if SIZEOF_VOID_P == 8
#define PYOS_STACK_MARGIN_SHIFT (PYOS_LOG2_STACK_MARGIN + 3)
#else
#define PYOS_STACK_MARGIN_SHIFT (PYOS_LOG2_STACK_MARGIN + 2)
#endif


#if defined(WIN32)
#define USE_STACKCHECK
# define USE_STACKCHECK
#endif

#ifdef USE_STACKCHECK
/* Check that we aren't overflowing our stack */
PyAPI_FUNC(int) PyOS_CheckStack(void);
#endif


#ifndef Py_LIMITED_API
# define Py_CPYTHON_PYTHONRUN_H
# include "cpython/pythonrun.h"
Expand Down
2 changes: 1 addition & 1 deletion Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ get_c_recursion_remaining(PyObject *self, PyObject *Py_UNUSED(args))
PyThreadState *tstate = _PyThreadState_GET();
uintptr_t here_addr = _Py_get_machine_stack_pointer();
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
int remaining = (int)((here_addr - _tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50);
int remaining = (int)((here_addr - _tstate->c_stack_soft_limit) / _PYOS_STACK_MARGIN_BYTES * 50);
return PyLong_FromLong(remaining);
}

Expand Down
14 changes: 7 additions & 7 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,13 @@ _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count)
{
uintptr_t here_addr = _Py_get_machine_stack_pointer();
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
if (here_addr > _tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) {
if (here_addr > _tstate->c_stack_soft_limit + margin_count * _PYOS_STACK_MARGIN_BYTES) {
return 0;
}
if (_tstate->c_stack_hard_limit == 0) {
_Py_InitializeRecursionLimits(tstate);
}
return here_addr <= _tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES;
return here_addr <= _tstate->c_stack_soft_limit + margin_count * _PYOS_STACK_MARGIN_BYTES;
}

void
Expand Down Expand Up @@ -448,8 +448,8 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
_tstate->c_stack_top = (uintptr_t)high;
ULONG guarantee = 0;
SetThreadStackGuarantee(&guarantee);
_tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + PYOS_STACK_MARGIN_BYTES;
_tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES;
_tstate->c_stack_hard_limit = ((uintptr_t)low) + guarantee + _PYOS_STACK_MARGIN_BYTES;
_tstate->c_stack_soft_limit = _tstate->c_stack_hard_limit + _PYOS_STACK_MARGIN_BYTES;
#else
uintptr_t here_addr = _Py_get_machine_stack_pointer();
# if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(_AIX) && !defined(__NetBSD__)
Expand All @@ -469,17 +469,17 @@ _Py_InitializeRecursionLimits(PyThreadState *tstate)
// Thread sanitizer crashes if we use a bit more than half the stack.
_tstate->c_stack_soft_limit = base + (stack_size / 2);
#else
_tstate->c_stack_soft_limit = base + PYOS_STACK_MARGIN_BYTES * 2;
_tstate->c_stack_soft_limit = base + _PYOS_STACK_MARGIN_BYTES * 2;
#endif
_tstate->c_stack_hard_limit = base + PYOS_STACK_MARGIN_BYTES;
_tstate->c_stack_hard_limit = base + _PYOS_STACK_MARGIN_BYTES;
assert(_tstate->c_stack_soft_limit < here_addr);
assert(here_addr < _tstate->c_stack_top);
return;
}
# endif
_tstate->c_stack_top = _Py_SIZE_ROUND_UP(here_addr, 4096);
_tstate->c_stack_soft_limit = _tstate->c_stack_top - Py_C_STACK_SIZE;
_tstate->c_stack_hard_limit = _tstate->c_stack_top - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES);
_tstate->c_stack_hard_limit = _tstate->c_stack_top - (Py_C_STACK_SIZE + _PYOS_STACK_MARGIN_BYTES);
#endif
}

Expand Down
Loading