summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2023-09-07 13:39:03 (GMT)
committerGitHub <noreply@github.com>2023-09-07 13:39:03 (GMT)
commit0858328ca2457ae95715eb93e347d5c0547bec6f (patch)
tree35c18050d74c747699f30e9862fd4a63fb14eaa7 /Python
parentd485551c9d1792ff3539eef1d6374bd4c01dcd5d (diff)
downloadcpython-0858328ca2457ae95715eb93e347d5c0547bec6f.zip
cpython-0858328ca2457ae95715eb93e347d5c0547bec6f.tar.gz
cpython-0858328ca2457ae95715eb93e347d5c0547bec6f.tar.bz2
GH-108614: Add `RESUME_CHECK` instruction (GH-108630)
Diffstat (limited to 'Python')
-rw-r--r--Python/abstract_interp_cases.c.h2
-rw-r--r--Python/bytecodes.c29
-rw-r--r--Python/ceval_macros.h2
-rw-r--r--Python/emscripten_signal.c8
-rw-r--r--Python/executor_cases.c.h25
-rw-r--r--Python/generated_cases.c.h28
-rw-r--r--Python/opcode_targets.h4
7 files changed, 58 insertions, 40 deletions
diff --git a/Python/abstract_interp_cases.c.h b/Python/abstract_interp_cases.c.h
index 07e8a71..11fbf44 100644
--- a/Python/abstract_interp_cases.c.h
+++ b/Python/abstract_interp_cases.c.h
@@ -7,7 +7,7 @@
break;
}
- case RESUME: {
+ case RESUME_CHECK: {
break;
}
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index fae1da3..8820b52 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -132,24 +132,37 @@ dummy_func(
inst(NOP, (--)) {
}
+ family(RESUME, 0) = {
+ RESUME_CHECK,
+ };
+
inst(RESUME, (--)) {
+ TIER_ONE_ONLY
assert(frame == tstate->current_frame);
- /* Possibly combine this with eval breaker */
if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) {
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
ERROR_IF(err, error);
- #if TIER_ONE
next_instr--;
- #endif
- #if TIER_TWO
- goto deoptimize;
- #endif
}
- else if (oparg < 2) {
- CHECK_EVAL_BREAKER();
+ else {
+ if (oparg < 2) {
+ CHECK_EVAL_BREAKER();
+ }
+ next_instr[-1].op.code = RESUME_CHECK;
}
}
+ inst(RESUME_CHECK, (--)) {
+#if defined(__EMSCRIPTEN__)
+ DEOPT_IF(emscripten_signal_clock == 0, RESUME);
+ emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING;
+#endif
+ /* Possibly combine these two checks */
+ DEOPT_IF(_PyFrame_GetCode(frame)->_co_instrumentation_version
+ != tstate->interp->monitoring_version, RESUME);
+ DEOPT_IF(_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker), RESUME);
+ }
+
inst(INSTRUMENTED_RESUME, (--)) {
/* Possible performance enhancement:
* We need to check the eval breaker anyway, can we
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index 81fbb79..f5d9155 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -374,6 +374,8 @@ static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) {
tstate->py_recursion_remaining++;
}
+/* Marker to specify tier 1 only instructions */
+#define TIER_ONE_ONLY
/* Implementation of "macros" that modify the instruction pointer,
* stack pointer, or frame pointer.
diff --git a/Python/emscripten_signal.c b/Python/emscripten_signal.c
index d617ddf..1a19638 100644
--- a/Python/emscripten_signal.c
+++ b/Python/emscripten_signal.c
@@ -38,19 +38,17 @@ _Py_CheckEmscriptenSignals(void)
}
}
-
#define PY_EMSCRIPTEN_SIGNAL_INTERVAL 50
static int emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL;
void
_Py_CheckEmscriptenSignalsPeriodically(void)
{
- if (!Py_EMSCRIPTEN_SIGNAL_HANDLING) {
- return;
- }
- emscripten_signal_clock--;
if (emscripten_signal_clock == 0) {
emscripten_signal_clock = PY_EMSCRIPTEN_SIGNAL_INTERVAL;
_Py_CheckEmscriptenSignals();
}
+ else if (Py_EMSCRIPTEN_SIGNAL_HANDLING) {
+ emscripten_signal_clock--;
+ }
}
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 0d5606f..f4c526a 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -7,22 +7,15 @@
break;
}
- case RESUME: {
- assert(frame == tstate->current_frame);
- /* Possibly combine this with eval breaker */
- if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) {
- int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
- if (err) goto error;
- #if TIER_ONE
- next_instr--;
- #endif
- #if TIER_TWO
- goto deoptimize;
- #endif
- }
- else if (oparg < 2) {
- CHECK_EVAL_BREAKER();
- }
+ case RESUME_CHECK: {
+#if defined(__EMSCRIPTEN__)
+ DEOPT_IF(emscripten_signal_clock == 0, RESUME);
+ emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING;
+#endif
+ /* Possibly combine these two checks */
+ DEOPT_IF(_PyFrame_GetCode(frame)->_co_instrumentation_version
+ != tstate->interp->monitoring_version, RESUME);
+ DEOPT_IF(_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker), RESUME);
break;
}
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 34cea84..84f83db 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -8,24 +8,36 @@
}
TARGET(RESUME) {
+ PREDICTED(RESUME);
+ static_assert(0 == 0, "incorrect cache size");
+ TIER_ONE_ONLY
assert(frame == tstate->current_frame);
- /* Possibly combine this with eval breaker */
if (_PyFrame_GetCode(frame)->_co_instrumentation_version != tstate->interp->monitoring_version) {
int err = _Py_Instrument(_PyFrame_GetCode(frame), tstate->interp);
if (err) goto error;
- #if TIER_ONE
next_instr--;
- #endif
- #if TIER_TWO
- goto deoptimize;
- #endif
}
- else if (oparg < 2) {
- CHECK_EVAL_BREAKER();
+ else {
+ if (oparg < 2) {
+ CHECK_EVAL_BREAKER();
+ }
+ next_instr[-1].op.code = RESUME_CHECK;
}
DISPATCH();
}
+ TARGET(RESUME_CHECK) {
+#if defined(__EMSCRIPTEN__)
+ DEOPT_IF(emscripten_signal_clock == 0, RESUME);
+ emscripten_signal_clock -= Py_EMSCRIPTEN_SIGNAL_HANDLING;
+#endif
+ /* Possibly combine these two checks */
+ DEOPT_IF(_PyFrame_GetCode(frame)->_co_instrumentation_version
+ != tstate->interp->monitoring_version, RESUME);
+ DEOPT_IF(_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker), RESUME);
+ DISPATCH();
+ }
+
TARGET(INSTRUMENTED_RESUME) {
/* Possible performance enhancement:
* We need to check the eval breaker anyway, can we
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 305eb0b..413bb88 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -46,6 +46,7 @@ static void *opcode_targets[256] = {
&&TARGET_POP_TOP,
&&TARGET_PUSH_EXC_INFO,
&&TARGET_PUSH_NULL,
+ &&TARGET_RESUME_CHECK,
&&TARGET_RETURN_GENERATOR,
&&TARGET_RETURN_VALUE,
&&TARGET_SETUP_ANNOTATIONS,
@@ -164,8 +165,8 @@ static void *opcode_targets[256] = {
&&TARGET_POP_JUMP_IF_NOT_NONE,
&&TARGET_POP_JUMP_IF_TRUE,
&&TARGET_RAISE_VARARGS,
- &&TARGET_RERAISE,
&&TARGET_RESUME,
+ &&TARGET_RERAISE,
&&TARGET_RETURN_CONST,
&&TARGET_SEND,
&&TARGET_SEND_GEN,
@@ -235,7 +236,6 @@ static void *opcode_targets[256] = {
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
- &&_unknown_opcode,
&&TARGET_INSTRUMENTED_RESUME,
&&TARGET_INSTRUMENTED_END_FOR,
&&TARGET_INSTRUMENTED_END_SEND,