GH-116422: Factor out eval breaker checks at end of calls into its own micro-op. (GH-116817)

This commit is contained in:
Mark Shannon 2024-03-14 16:31:47 +00:00 committed by GitHub
parent 19c3a2ff91
commit 61e54bfcee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 474 additions and 371 deletions

View file

@ -3108,10 +3108,13 @@ dummy_func(
Py_DECREF(args[i]);
}
ERROR_IF(res == NULL, error);
}
op(_CHECK_PERIODIC, (--)) {
CHECK_EVAL_BREAKER();
}
macro(CALL) = _SPECIALIZE_CALL + unused/2 + _CALL;
macro(CALL) = _SPECIALIZE_CALL + unused/2 + _CALL + _CHECK_PERIODIC;
op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) {
DEOPT_IF(null != NULL);
@ -3246,7 +3249,7 @@ dummy_func(
Py_DECREF(arg);
}
inst(CALL_STR_1, (unused/1, unused/2, callable, null, arg -- res)) {
op(_CALL_STR_1, (callable, null, arg -- res)) {
assert(oparg == 1);
DEOPT_IF(null != NULL);
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type);
@ -3254,10 +3257,15 @@ dummy_func(
res = PyObject_Str(arg);
Py_DECREF(arg);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
inst(CALL_TUPLE_1, (unused/1, unused/2, callable, null, arg -- res)) {
macro(CALL_STR_1) =
unused/1 +
unused/2 +
_CALL_STR_1 +
_CHECK_PERIODIC;
op(_CALL_TUPLE_1, (callable, null, arg -- res)) {
assert(oparg == 1);
DEOPT_IF(null != NULL);
DEOPT_IF(callable != (PyObject *)&PyTuple_Type);
@ -3265,9 +3273,14 @@ dummy_func(
res = PySequence_Tuple(arg);
Py_DECREF(arg);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
macro(CALL_TUPLE_1) =
unused/1 +
unused/2 +
_CALL_TUPLE_1 +
_CHECK_PERIODIC;
inst(CALL_ALLOC_AND_ENTER_INIT, (unused/1, unused/2, callable, null, args[oparg] -- unused)) {
/* This instruction does the following:
* 1. Creates the object (by calling ``object.__new__``)
@ -3328,7 +3341,7 @@ dummy_func(
}
}
inst(CALL_BUILTIN_CLASS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
op(_CALL_BUILTIN_CLASS, (callable, self_or_null, args[oparg] -- res)) {
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3345,10 +3358,15 @@ dummy_func(
}
Py_DECREF(tp);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
inst(CALL_BUILTIN_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
macro(CALL_BUILTIN_CLASS) =
unused/1 +
unused/2 +
_CALL_BUILTIN_CLASS +
_CHECK_PERIODIC;
op(_CALL_BUILTIN_O, (callable, self_or_null, args[oparg] -- res)) {
/* Builtin METH_O functions */
int total_args = oparg;
if (self_or_null != NULL) {
@ -3373,10 +3391,15 @@ dummy_func(
Py_DECREF(arg);
Py_DECREF(callable);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
inst(CALL_BUILTIN_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
macro(CALL_BUILTIN_O) =
unused/1 +
unused/2 +
_CALL_BUILTIN_O +
_CHECK_PERIODIC;
op(_CALL_BUILTIN_FAST, (callable, self_or_null, args[oparg] -- res)) {
/* Builtin METH_FASTCALL functions, without keywords */
int total_args = oparg;
if (self_or_null != NULL) {
@ -3400,15 +3423,15 @@ dummy_func(
}
Py_DECREF(callable);
ERROR_IF(res == NULL, error);
/* Not deopting because this doesn't mean our optimization was
wrong. `res` can be NULL for valid reasons. Eg. getattr(x,
'invalid'). In those cases an exception is set, so we must
handle it.
*/
CHECK_EVAL_BREAKER();
}
inst(CALL_BUILTIN_FAST_WITH_KEYWORDS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
macro(CALL_BUILTIN_FAST) =
unused/1 +
unused/2 +
_CALL_BUILTIN_FAST +
_CHECK_PERIODIC;
op(_CALL_BUILTIN_FAST_WITH_KEYWORDS, (callable, self_or_null, args[oparg] -- res)) {
/* Builtin METH_FASTCALL | METH_KEYWORDS functions */
int total_args = oparg;
if (self_or_null != NULL) {
@ -3431,9 +3454,14 @@ dummy_func(
}
Py_DECREF(callable);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
macro(CALL_BUILTIN_FAST_WITH_KEYWORDS) =
unused/1 +
unused/2 +
_CALL_BUILTIN_FAST_WITH_KEYWORDS +
_CHECK_PERIODIC;
inst(CALL_LEN, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
/* len(o) */
int total_args = oparg;
@ -3504,7 +3532,7 @@ dummy_func(
DISPATCH();
}
inst(CALL_METHOD_DESCRIPTOR_O, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
op(_CALL_METHOD_DESCRIPTOR_O, (callable, self_or_null, args[oparg] -- res)) {
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3532,10 +3560,15 @@ dummy_func(
Py_DECREF(arg);
Py_DECREF(callable);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
inst(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
macro(CALL_METHOD_DESCRIPTOR_O) =
unused/1 +
unused/2 +
_CALL_METHOD_DESCRIPTOR_O +
_CHECK_PERIODIC;
op(_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, (callable, self_or_null, args[oparg] -- res)) {
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3561,10 +3594,15 @@ dummy_func(
}
Py_DECREF(callable);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
inst(CALL_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
macro(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) =
unused/1 +
unused/2 +
_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS +
_CHECK_PERIODIC;
op(_CALL_METHOD_DESCRIPTOR_NOARGS, (callable, self_or_null, args[oparg] -- res)) {
assert(oparg == 0 || oparg == 1);
int total_args = oparg;
if (self_or_null != NULL) {
@ -3591,10 +3629,15 @@ dummy_func(
Py_DECREF(self);
Py_DECREF(callable);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
inst(CALL_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, callable, self_or_null, args[oparg] -- res)) {
macro(CALL_METHOD_DESCRIPTOR_NOARGS) =
unused/1 +
unused/2 +
_CALL_METHOD_DESCRIPTOR_NOARGS +
_CHECK_PERIODIC;
op(_CALL_METHOD_DESCRIPTOR_FAST, (callable, self_or_null, args[oparg] -- res)) {
int total_args = oparg;
if (self_or_null != NULL) {
args--;
@ -3619,9 +3662,14 @@ dummy_func(
}
Py_DECREF(callable);
ERROR_IF(res == NULL, error);
CHECK_EVAL_BREAKER();
}
macro(CALL_METHOD_DESCRIPTOR_FAST) =
unused/1 +
unused/2 +
_CALL_METHOD_DESCRIPTOR_FAST +
_CHECK_PERIODIC;
inst(INSTRUMENTED_CALL_KW, ( -- )) {
int is_meth = PEEK(oparg + 2) != NULL;
int total_args = oparg + is_meth;