mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-139109: JIT _EXIT_TRACE to ENTER_EXECUTOR rather than _DEOPT (GH-141573)
This commit is contained in:
parent
85f3009d75
commit
ed73c909f2
5 changed files with 44 additions and 8 deletions
|
|
@ -362,7 +362,7 @@ PyAPI_FUNC(int) _PyDumpExecutors(FILE *out);
|
||||||
extern void _Py_ClearExecutorDeletionList(PyInterpreterState *interp);
|
extern void _Py_ClearExecutorDeletionList(PyInterpreterState *interp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int _PyJit_translate_single_bytecode_to_trace(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, bool stop_tracing);
|
int _PyJit_translate_single_bytecode_to_trace(PyThreadState *tstate, _PyInterpreterFrame *frame, _Py_CODEUNIT *next_instr, int stop_tracing_opcode);
|
||||||
|
|
||||||
int
|
int
|
||||||
_PyJit_TryInitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame,
|
_PyJit_TryInitializeTracing(PyThreadState *tstate, _PyInterpreterFrame *frame,
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,17 @@ def get_first_executor(func):
|
||||||
pass
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_all_executors(func):
|
||||||
|
code = func.__code__
|
||||||
|
co_code = code.co_code
|
||||||
|
executors = []
|
||||||
|
for i in range(0, len(co_code), 2):
|
||||||
|
try:
|
||||||
|
executors.append(_opcode.get_executor(code, i))
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return executors
|
||||||
|
|
||||||
|
|
||||||
def iter_opnames(ex):
|
def iter_opnames(ex):
|
||||||
for item in ex:
|
for item in ex:
|
||||||
|
|
@ -2629,6 +2640,31 @@ def gen():
|
||||||
next(g)
|
next(g)
|
||||||
""" % _testinternalcapi.SPECIALIZATION_THRESHOLD))
|
""" % _testinternalcapi.SPECIALIZATION_THRESHOLD))
|
||||||
|
|
||||||
|
def test_executor_side_exits_create_another_executor(self):
|
||||||
|
def f():
|
||||||
|
for x in range(TIER2_THRESHOLD + 3):
|
||||||
|
for y in range(TIER2_THRESHOLD + 3):
|
||||||
|
z = x + y
|
||||||
|
|
||||||
|
f()
|
||||||
|
all_executors = get_all_executors(f)
|
||||||
|
# Inner loop warms up first.
|
||||||
|
# Outer loop warms up later, linking to the inner one.
|
||||||
|
# Therefore, we have at least two executors.
|
||||||
|
self.assertGreaterEqual(len(all_executors), 2)
|
||||||
|
for executor in all_executors:
|
||||||
|
opnames = list(get_opnames(executor))
|
||||||
|
# Assert all executors first terminator ends in
|
||||||
|
# _EXIT_TRACE or _JUMP_TO_TOP, not _DEOPT
|
||||||
|
for idx, op in enumerate(opnames):
|
||||||
|
if op == "_EXIT_TRACE" or op == "_JUMP_TO_TOP":
|
||||||
|
break
|
||||||
|
elif op == "_DEOPT":
|
||||||
|
self.fail(f"_DEOPT encountered first at executor"
|
||||||
|
f" {executor} at offset {idx} rather"
|
||||||
|
f" than expected _EXIT_TRACE")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def global_identity(x):
|
def global_identity(x):
|
||||||
return x
|
return x
|
||||||
|
|
|
||||||
|
|
@ -5643,7 +5643,7 @@ dummy_func(
|
||||||
bool stop_tracing = (opcode == WITH_EXCEPT_START ||
|
bool stop_tracing = (opcode == WITH_EXCEPT_START ||
|
||||||
opcode == RERAISE || opcode == CLEANUP_THROW ||
|
opcode == RERAISE || opcode == CLEANUP_THROW ||
|
||||||
opcode == PUSH_EXC_INFO || opcode == INTERPRETER_EXIT);
|
opcode == PUSH_EXC_INFO || opcode == INTERPRETER_EXIT);
|
||||||
int full = !_PyJit_translate_single_bytecode_to_trace(tstate, frame, next_instr, stop_tracing);
|
int full = !_PyJit_translate_single_bytecode_to_trace(tstate, frame, next_instr, stop_tracing ? _DEOPT : 0);
|
||||||
if (full) {
|
if (full) {
|
||||||
LEAVE_TRACING();
|
LEAVE_TRACING();
|
||||||
int err = stop_tracing_and_jit(tstate, frame);
|
int err = stop_tracing_and_jit(tstate, frame);
|
||||||
|
|
@ -5683,7 +5683,7 @@ dummy_func(
|
||||||
#if _Py_TIER2
|
#if _Py_TIER2
|
||||||
assert(IS_JIT_TRACING());
|
assert(IS_JIT_TRACING());
|
||||||
int opcode = next_instr->op.code;
|
int opcode = next_instr->op.code;
|
||||||
_PyJit_translate_single_bytecode_to_trace(tstate, frame, NULL, true);
|
_PyJit_translate_single_bytecode_to_trace(tstate, frame, NULL, _EXIT_TRACE);
|
||||||
LEAVE_TRACING();
|
LEAVE_TRACING();
|
||||||
int err = stop_tracing_and_jit(tstate, frame);
|
int err = stop_tracing_and_jit(tstate, frame);
|
||||||
ERROR_IF(err < 0);
|
ERROR_IF(err < 0);
|
||||||
|
|
|
||||||
4
Python/generated_cases.c.h
generated
4
Python/generated_cases.c.h
generated
|
|
@ -12263,7 +12263,7 @@ JUMP_TO_LABEL(error);
|
||||||
opcode == RERAISE || opcode == CLEANUP_THROW ||
|
opcode == RERAISE || opcode == CLEANUP_THROW ||
|
||||||
opcode == PUSH_EXC_INFO || opcode == INTERPRETER_EXIT);
|
opcode == PUSH_EXC_INFO || opcode == INTERPRETER_EXIT);
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
int full = !_PyJit_translate_single_bytecode_to_trace(tstate, frame, next_instr, stop_tracing);
|
int full = !_PyJit_translate_single_bytecode_to_trace(tstate, frame, next_instr, stop_tracing ? _DEOPT : 0);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
if (full) {
|
if (full) {
|
||||||
LEAVE_TRACING();
|
LEAVE_TRACING();
|
||||||
|
|
@ -12309,7 +12309,7 @@ JUMP_TO_LABEL(error);
|
||||||
assert(IS_JIT_TRACING());
|
assert(IS_JIT_TRACING());
|
||||||
int opcode = next_instr->op.code;
|
int opcode = next_instr->op.code;
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
_PyJit_translate_single_bytecode_to_trace(tstate, frame, NULL, true);
|
_PyJit_translate_single_bytecode_to_trace(tstate, frame, NULL, _EXIT_TRACE);
|
||||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||||
LEAVE_TRACING();
|
LEAVE_TRACING();
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
|
|
|
||||||
|
|
@ -574,7 +574,7 @@ _PyJit_translate_single_bytecode_to_trace(
|
||||||
PyThreadState *tstate,
|
PyThreadState *tstate,
|
||||||
_PyInterpreterFrame *frame,
|
_PyInterpreterFrame *frame,
|
||||||
_Py_CODEUNIT *next_instr,
|
_Py_CODEUNIT *next_instr,
|
||||||
bool stop_tracing)
|
int stop_tracing_opcode)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Py_DEBUG
|
#ifdef Py_DEBUG
|
||||||
|
|
@ -637,8 +637,8 @@ _PyJit_translate_single_bytecode_to_trace(
|
||||||
goto full;
|
goto full;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stop_tracing) {
|
if (stop_tracing_opcode != 0) {
|
||||||
ADD_TO_TRACE(_DEOPT, 0, 0, target);
|
ADD_TO_TRACE(stop_tracing_opcode, 0, 0, target);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue