GH-130396: Use computed stack limits on linux (GH-130398) · python/cpython@0142236

GitHub

@@ -193,18 +193,28 @@ extern void _PyEval_DeactivateOpCache(void);

193193194194/* --- _Py_EnterRecursiveCall() ----------------------------------------- */

195195196-#ifdefUSE_STACKCHECK

197-/* With USE_STACKCHECK macro defined, trigger stack checks in

198- _Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */

199-staticinlineint_Py_MakeRecCheck(PyThreadState*tstate) {

200-return (tstate->c_recursion_remaining--<0

201-|| (tstate->c_recursion_remaining&63) ==0);

196+#if !_Py__has_builtin(__builtin_frame_address)

197+staticuintptr_treturn_pointer_as_int(char*p) {

198+return (uintptr_t)p;

202199}

200+#endif

201+202+staticinlineuintptr_t

203+_Py_get_machine_stack_pointer(void) {

204+#if_Py__has_builtin(__builtin_frame_address)

205+return (uintptr_t)__builtin_frame_address(0);

203206#else

204-staticinlineint_Py_MakeRecCheck(PyThreadState*tstate) {

205-returntstate->c_recursion_remaining--<0;

206-}

207+charhere;

208+/* Avoid compiler warning about returning stack address */

209+returnreturn_pointer_as_int(&here);

207210#endif

211+}

212+213+staticinlineint_Py_MakeRecCheck(PyThreadState*tstate) {

214+uintptr_there_addr=_Py_get_machine_stack_pointer();

215+_PyThreadStateImpl*_tstate= (_PyThreadStateImpl*)tstate;

216+returnhere_addr<_tstate->c_stack_soft_limit;

217+}

208218209219// Export for '_json' shared extension, used via _Py_EnterRecursiveCall()

210220// static inline function.

@@ -220,23 +230,30 @@ static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate,

220230return (_Py_MakeRecCheck(tstate) &&_Py_CheckRecursiveCall(tstate, where));

221231}

222232223-staticinlinevoid_Py_EnterRecursiveCallTstateUnchecked(PyThreadState*tstate) {

224-assert(tstate->c_recursion_remaining>0);

225-tstate->c_recursion_remaining--;

226-}

227-228233staticinlineint_Py_EnterRecursiveCall(constchar*where) {

229234PyThreadState*tstate=_PyThreadState_GET();

230235return_Py_EnterRecursiveCallTstate(tstate, where);

231236}

232237233-staticinlinevoid_Py_LeaveRecursiveCallTstate(PyThreadState*tstate) {

234-tstate->c_recursion_remaining++;

238+staticinlinevoid_Py_LeaveRecursiveCallTstate(PyThreadState*tstate) {

239+ (void)tstate;

240+}

241+242+PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState*tstate);

243+244+staticinlineint_Py_ReachedRecursionLimit(PyThreadState*tstate) {

245+uintptr_there_addr=_Py_get_machine_stack_pointer();

246+_PyThreadStateImpl*_tstate= (_PyThreadStateImpl*)tstate;

247+if (here_addr>_tstate->c_stack_soft_limit) {

248+return0;

249+ }

250+if (_tstate->c_stack_hard_limit==0) {

251+_Py_InitializeRecursionLimits(tstate);

252+ }

253+returnhere_addr <= _tstate->c_stack_soft_limit;

235254}

236255237256staticinlinevoid_Py_LeaveRecursiveCall(void) {

238-PyThreadState*tstate=_PyThreadState_GET();

239-_Py_LeaveRecursiveCallTstate(tstate);

240257}

241258242259externstruct_PyInterpreterFrame*_PyEval_GetFrame(void);

@@ -327,7 +344,6 @@ void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);

327344328345PyAPI_FUNC(PyObject*) _PyFloat_FromDouble_ConsumeInputs(_PyStackRefleft, _PyStackRefright, doublevalue);

329346330-331347#ifdef__cplusplus

332348}

333349#endif