-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
GH-116422: Modify a few uops so that they can be supported by tier 2 with hot/cold splitting #116832
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GH-116422: Modify a few uops so that they can be supported by tier 2 with hot/cold splitting #116832
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3376,14 +3376,12 @@ dummy_func( | |
DEOPT_IF(total_args != 1); | ||
DEOPT_IF(!PyCFunction_CheckExact(callable)); | ||
DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O); | ||
// CPython promises to check all non-vectorcall function calls. | ||
DEOPT_IF(tstate->c_recursion_remaining <= 0); | ||
STAT_INC(CALL, hit); | ||
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); | ||
// This is slower but CPython promises to check all non-vectorcall | ||
// function calls. | ||
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { | ||
GOTO_ERROR(error); | ||
} | ||
PyObject *arg = args[0]; | ||
_Py_EnterRecursiveCallTstateUnchecked(tstate); | ||
res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); | ||
_Py_LeaveRecursiveCallTstate(tstate); | ||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||
|
@@ -3480,10 +3478,11 @@ dummy_func( | |
} | ||
res = PyLong_FromSsize_t(len_i); | ||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||
|
||
if (res == NULL) { | ||
GOTO_ERROR(error); | ||
} | ||
Py_DECREF(callable); | ||
Py_DECREF(arg); | ||
ERROR_IF(res == NULL, error); | ||
} | ||
|
||
inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) { | ||
|
@@ -3505,11 +3504,12 @@ dummy_func( | |
} | ||
res = PyBool_FromLong(retval); | ||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||
|
||
if (res == NULL) { | ||
GOTO_ERROR(error); | ||
} | ||
Py_DECREF(inst); | ||
Py_DECREF(cls); | ||
Py_DECREF(callable); | ||
ERROR_IF(res == NULL, error); | ||
} | ||
|
||
// This is secretly a super-instruction | ||
|
@@ -3543,16 +3543,14 @@ dummy_func( | |
DEOPT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type)); | ||
PyMethodDef *meth = method->d_method; | ||
DEOPT_IF(meth->ml_flags != METH_O); | ||
// CPython promises to check all non-vectorcall function calls. | ||
DEOPT_IF(tstate->c_recursion_remaining <= 0); | ||
PyObject *arg = args[1]; | ||
PyObject *self = args[0]; | ||
DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); | ||
STAT_INC(CALL, hit); | ||
PyCFunction cfunc = meth->ml_meth; | ||
// This is slower but CPython promises to check all non-vectorcall | ||
// function calls. | ||
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { | ||
GOTO_ERROR(error); | ||
} | ||
_Py_EnterRecursiveCallTstateUnchecked(tstate); | ||
res = _PyCFunction_TrampolineCall(cfunc, self, arg); | ||
_Py_LeaveRecursiveCallTstate(tstate); | ||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||
|
@@ -3616,13 +3614,11 @@ dummy_func( | |
PyObject *self = args[0]; | ||
DEOPT_IF(!Py_IS_TYPE(self, method->d_common.d_type)); | ||
DEOPT_IF(meth->ml_flags != METH_NOARGS); | ||
// CPython promises to check all non-vectorcall function calls. | ||
DEOPT_IF(tstate->c_recursion_remaining <= 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea is that after DEOPT we will end up doing GOTO_ERROR in the original bytecode? (Is that what the comment is saying?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment refers to our obligation to check the C recursion limit for almost all builtin function calls. We can fulfil that obligation more cheaply this way. |
||
STAT_INC(CALL, hit); | ||
PyCFunction cfunc = meth->ml_meth; | ||
// This is slower but CPython promises to check all non-vectorcall | ||
// function calls. | ||
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { | ||
GOTO_ERROR(error); | ||
} | ||
_Py_EnterRecursiveCallTstateUnchecked(tstate); | ||
res = _PyCFunction_TrampolineCall(cfunc, self, NULL); | ||
_Py_LeaveRecursiveCallTstate(tstate); | ||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason this change is here is to make the guard
tstate->c_recursion_remaining <= 0
instead oftstate->c_recursion_remaining <= 1
. Comparing to zero is generally faster.It also seems more correct. If
c_recursion_remaining
is 1, that suggest that there is 1 remaining call, not 0.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The actual number we compare to doesn't really matter, as long as we are consistent.