8000 Perform lazy initialization of c recursion check · python/cpython@dbcf6f0 · GitHub
[go: up one dir, main page]

Skip to content

Commit dbcf6f0

Browse files
committed
Perform lazy initialization of c recursion check
1 parent a802ff6 commit dbcf6f0

File tree

2 files changed

+39
-23
lines changed

2 files changed

+39
-23
lines changed

Include/internal/pycore_ceval.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,19 @@ static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) {
222222
(void)tstate;
223223
}
224224

225+
PyAPI_FUNC(void) _Py_InitializeRecursionCheck(PyThreadState *tstate);
226+
225227
static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate, int margin_count) {
226228
assert(tstate->c_stack_soft_limit != UINTPTR_MAX);
227229
char here;
228230
uintptr_t here_addr = (uintptr_t)&here;
229-
return here_addr <= tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES;
231+
if (here_addr > tstate->c_stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES) {
232+
return 0;
233+
}
234+
if (tstate->c_stack_hard_limit == 0) {
235+
_Py_InitializeRecursionCheck(tstate);
236+
}
237+
return here_addr <= stack_soft_limit + margin_count * PYOS_STACK_MARGIN_BYTES;
230238
}
231239

232240
static inline void _Py_LeaveRecursiveCall(void) {

Python/ceval.c

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,35 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate)
318318
}
319319
}
320320

321+
void
322+
_Py_InitializeRecursionCheck(PyThreadState *tstate)
323+
{
324+
char here;
325+
uintptr_t here_addr = (uintptr_t)&here;
326+
#ifdef USE_STACKCHECK
327+
if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) {
328+
tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES;
329+
return 0;
330+
}
331+
int margin = PYOS_STACK_MARGIN;
332+
assert(tstate->c_stack_soft_limit != UINTPTR_MAX);
333+
if (_PyOS_CheckStack(margin)) {
334+
margin = PYOS_STACK_MARGIN/2;
335+
}
336+
else {
337+
if (_PyOS_CheckStack(PYOS_STACK_MARGIN*3/2) == 0) {
338+
margin = PYOS_STACK_MARGIN*3/2;
339+
}
340+
}
341+
tstate->c_stack_hard_limit = here_addr - margin * sizeof(void *);
342+
tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES;
343+
#else
344+
assert(tstate->c_stack_soft_limit == UINTPTR_MAX);
345+
tstate->c_stack_soft_limit = here_addr - Py_C_STACK_SIZE;
346+
tstate->c_stack_hard_limit = here_addr - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES);
347+
#endif
348+
}
349+
321350
/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
322351
if the recursion_depth reaches recursion_limit. */
323352
int
@@ -327,28 +356,7 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
327356
uintptr_t here_addr = (uintptr_t)&here;
328357
assert(tstate->c_stack_soft_limit != 0);
329358
if (tstate->c_stack_hard_limit == 0) {
330-
#ifdef USE_STACKCHECK
331-
if (_PyOS_CheckStack(PYOS_STACK_MARGIN * 2) == 0) {
332-
tstate->c_stack_soft_limit = here_addr - PYOS_STACK_MARGIN_BYTES;
333-
return 0;
334-
}
335-
int margin = PYOS_STACK_MARGIN;
336-
assert(tstate->c_stack_soft_limit != UINTPTR_MAX);
337-
if (_PyOS_CheckStack(margin)) {
338-
margin = PYOS_STACK_MARGIN/2;
339-
}
340-
else {
341-
if (_PyOS_CheckStack(PYOS_STACK_MARGIN*3/2) == 0) {
342-
margin = PYOS_STACK_MARGIN*3/2;
343-
}
344-
}
345-
tstate->c_stack_hard_limit = here_addr - margin * sizeof(void *);
346-
tstate->c_stack_soft_limit = tstate->c_stack_hard_limit + PYOS_STACK_MARGIN_BYTES;
347-
#else
348-
assert(tstate->c_stack_soft_limit == UINTPTR_MAX);
349-
tstate->c_stack_soft_limit = here_addr - Py_C_STACK_SIZE;
350-
tstate->c_stack_hard_limit = here_addr - (Py_C_STACK_SIZE + PYOS_STACK_MARGIN_BYTES);
351-
#endif
359+
_Py_InitializeRecursionCheck(tstate);
352360
}
353361
if (here_addr >= tstate->c_stack_soft_limit) {
354362
return 0;

0 commit comments

Comments
 (0)
0