summaryrefslogtreecommitdiffstats
path: root/Python/bytecodes.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-03-14 16:31:47 (GMT)
committerGitHub <noreply@github.com>2024-03-14 16:31:47 (GMT)
commit61e54bfcee9f08a8e09aa1b2fd6cea69ca6a26e0 (patch)
treeb2b53742294226322d929a6e6cdfcf8c729a5d01 /Python/bytecodes.c
parent19c3a2ff91ccf7444efadbc8f7e67269060050a2 (diff)
downloadcpython-61e54bfcee9f08a8e09aa1b2fd6cea69ca6a26e0.zip
cpython-61e54bfcee9f08a8e09aa1b2fd6cea69ca6a26e0.tar.gz
cpython-61e54bfcee9f08a8e09aa1b2fd6cea69ca6a26e0.tar.bz2
GH-116422: Factor out eval breaker checks at end of calls into its own micro-op. (GH-116817)
Diffstat (limited to 'Python/bytecodes.c')
-rw-r--r--Python/bytecodes.c100
1 files changed, 74 insertions, 26 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index af2e2c8..e8fcb6c 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -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;