Skip to content

Commit 2cf18a4

Browse files
authored
GH-116422: Modify a few uops so that they can be supported by tier 2 with hot/cold splitting (GH-116832)
1 parent a50cf6c commit 2cf18a4

File tree

4 files changed

+52
-55
lines changed

4 files changed

+52
-55
lines changed

Include/internal/pycore_ceval.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,12 @@ extern void _PyEval_DeactivateOpCache(void);
138138
/* With USE_STACKCHECK macro defined, trigger stack checks in
139139
_Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */
140140
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
141-
return (tstate->c_recursion_remaining-- <= 0
141+
return (tstate->c_recursion_remaining-- < 0
142142
|| (tstate->c_recursion_remaining & 63) == 0);
143143
}
144144
#else
145145
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
146-
return tstate->c_recursion_remaining-- <= 0;
146+
return tstate->c_recursion_remaining-- < 0;
147147
}
148148
#endif
149149

@@ -161,6 +161,11 @@ static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate,
161161
return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
162162
}
163163

164+
static inline void _Py_EnterRecursiveCallTstateUnchecked(PyThreadState *tstate) {
165+
assert(tstate->c_recursion_remaining > 0);
166+
tstate->c_recursion_remaining--;
167+
}
168+
164169
static inline int _Py_EnterRecursiveCall(const char *where) {
165170
PyThreadState *tstate = _PyThreadState_GET();
166171
return _Py_EnterRecursiveCallTstate(tstate, where);

Python/bytecodes.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,14 +3376,12 @@ dummy_func(
33763376
DEOPT_IF(total_args != 1);
33773377
DEOPT_IF(!PyCFunction_CheckExact(callable));
33783378
DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O);
3379+
// CPython promises to check all non-vectorcall function calls.
3380+
DEOPT_IF(tstate->c_recursion_remaining <= 0);
33793381
STAT_INC(CALL, hit);
33803382
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable);
3381-
// This is slower but CPython promises to check all non-vectorcall
3382-
// function calls.
3383-
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
3384-
GOTO_ERROR(error);
3385-
}
33863383
PyObject *arg = args[0];
3384+
_Py_EnterRecursiveCallTstateUnchecked(tstate);
33873385
res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg);
33883386
_Py_LeaveRecursiveCallTstate(tstate);
33893387
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
@@ -3480,10 +3478,11 @@ dummy_func(
34803478
}
34813479
res = PyLong_FromSsize_t(len_i);
34823480
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
3483-
3481+
if (res == NULL) {
3482+
GOTO_ERROR(error);
3483+
}
34843484
Py_DECREF(callable);
34853485
Py_DECREF(arg);
3486-
ERROR_IF(res == NULL, error);
34873486
}
34883487

34893488
inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
@@ -3505,11 +3504,12 @@ dummy_func(
35053504
}
35063505
res = PyBool_FromLong(retval);
35073506
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
3508-
3507+
if (res == NULL) {
3508+
GOTO_ERROR(error);
3509+
}
35093510
Py_DECREF(inst);
35103511
Py_DECREF(cls);
35113512
Py_DECREF(callable);
3512-
ERROR_IF(res == NULL, error);
35133513
}
35143514

35153515
// This is secretly a super-instruction
@@ -3543,16 +3543,14 @@ dummy_func(
35433543
DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type));
35443544
PyMethodDef *meth = method->d_method;
35453545
DEOPT_IF(meth->ml_flags != METH_O);
3546+
// CPython promises to check all non-vectorcall function calls.
3547+
DEOPT_IF(tstate->c_recursion_remaining <= 0);
35463548
PyObject *arg = args[1];
35473549
PyObject *self = args[0];
35483550
DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type));
35493551
STAT_INC(CALL, hit);
35503552
PyCFunction cfunc = meth->ml_meth;
3551-
// This is slower but CPython promises to check all non-vectorcall
3552-
// function calls.
3553-
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
3554-
GOTO_ERROR(error);
3555-
}
3553+
_Py_EnterRecursiveCallTstateUnchecked(tstate);
35563554
res = _PyCFunction_TrampolineCall(cfunc, self, arg);
35573555
_Py_LeaveRecursiveCallTstate(tstate);
35583556
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
@@ -3616,13 +3614,11 @@ dummy_func(
36163614
PyObject *self = args[0];
36173615
DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type));
36183616
DEOPT_IF(meth->ml_flags != METH_NOARGS);
3617+
// CPython promises to check all non-vectorcall function calls.
3618+
DEOPT_IF(tstate->c_recursion_remaining <= 0);
36193619
STAT_INC(CALL, hit);
36203620
PyCFunction cfunc = meth->ml_meth;
3621-
// This is slower but CPython promises to check all non-vectorcall
3622-
// function calls.
3623-
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
3624-
GOTO_ERROR(error);
3625-
}
3621+
_Py_EnterRecursiveCallTstateUnchecked(tstate);
36263622
res = _PyCFunction_TrampolineCall(cfunc, self, NULL);
36273623
_Py_LeaveRecursiveCallTstate(tstate);
36283624
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));

Python/executor_cases.c.h

Lines changed: 15 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 15 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)