Skip to content

Commit 7b5c655

Browse files
Fix dispatch_inlined
1 parent aada168 commit 7b5c655

File tree

7 files changed

+78
-41
lines changed

7 files changed

+78
-41
lines changed

Include/internal/pycore_optimizer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ typedef struct _PyExitData {
4545
typedef struct _PyExecutorObject {
4646
PyObject_VAR_HEAD
4747
const _PyUOpInstruction *trace;
48-
_Py_CODEUNIT *expected_entrypoint;
4948
_PyVMData vm_data; /* Used by the VM, but opaque to the optimizer */
5049
uint32_t exit_count;
5150
uint32_t code_size;

Python/bytecodes.c

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5438,33 +5438,26 @@ dummy_func(
54385438
assert(exit != NULL);
54395439
bool is_dynamic = exit->is_dynamic;
54405440
_Py_CODEUNIT *target = is_dynamic ? frame->instr_ptr : (_PyFrame_GetBytecode(frame) + exit->target);
5441-
GOTO_TIER_ONE(target, 0);
5442-
// _Py_BackoffCounter temperature = exit->temperature;
5443-
// if (target->op.code == ENTER_EXECUTOR) {
5444-
// PyCodeObject *code = _PyFrame_GetCode(frame);
5445-
// _PyExecutorObject *executor = code->co_executors->executors[target->op.arg];
5446-
// if (is_dynamic && executor->expected_entrypoint != target) {
5447-
// GOTO_TIER_ONE(target, 0);
5448-
// }
5449-
// Py_INCREF(executor);
5450-
// assert(tstate->jit_exit == exit);
5451-
// exit->executor = executor;
5452-
// TIER2_TO_TIER2(exit->executor);
5453-
// }
5454-
// else {
5455-
// if (!backoff_counter_triggers(temperature)) {
5456-
// exit->temperature = advance_backoff_counter(temperature);
5457-
// GOTO_TIER_ONE(target, 0);
5458-
// }
5459-
// if (is_dynamic) {
5460-
// GOTO_TIER_ONE(target, 0);
5461-
// }
5462-
// _PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit);
5463-
// assert(tstate->current_executor == (PyObject *)previous_executor);
5464-
// int chain_depth = 0;
5465-
// _PyJIT_InitializeTracing(tstate, frame, target, STACK_LEVEL(), chain_depth);
5466-
// GOTO_TIER_ONE(target, 1);
5467-
// }
5441+
_Py_BackoffCounter temperature = exit->temperature;
5442+
if (target->op.code == ENTER_EXECUTOR) {
5443+
PyCodeObject *code = _PyFrame_GetCode(frame);
5444+
_PyExecutorObject *executor = code->co_executors->executors[target->op.arg];
5445+
Py_INCREF(executor);
5446+
assert(tstate->jit_exit == exit);
5447+
exit->executor = executor;
5448+
TIER2_TO_TIER2(exit->executor);
5449+
}
5450+
else {
5451+
if (!backoff_counter_triggers(temperature)) {
5452+
exit->temperature = advance_backoff_counter(temperature);
5453+
GOTO_TIER_ONE(target, 0);
5454+
}
5455+
_PyExecutorObject *previous_executor = _PyExecutor_FromExit(exit);
5456+
assert(tstate->current_executor == (PyObject *)previous_executor);
5457+
int chain_depth = 0;
5458+
_PyJIT_InitializeTracing(tstate, frame, target, STACK_LEVEL(), chain_depth);
5459+
GOTO_TIER_ONE(target, 1);
5460+
}
54685461
}
54695462

54705463
tier2 op(_GUARD_IP, (ip/4 --)) {

Python/ceval_macros.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ do { \
217217
JUMP_TO_LABEL(start_frame); \
218218
} while (0)
219219

220+
#define TRACING_DISPATCH_INLINED(NEW_FRAME) \
221+
RECORD_TRACE_NO_DISPATCH(); \
222+
DISPATCH_INLINED(NEW_FRAME);
223+
220224
#define TRACING_DISPATCH() \
221225
{ \
222226
assert(frame->stackpointer == NULL); \
@@ -421,7 +425,6 @@ do { \
421425
JUMP_TO_LABEL(error); \
422426
} \
423427
if (keep_tracing_bit) { \
424-
assert(next_instr == frame->instr_ptr); \
425428
assert(next_instr->op.code != ENTER_EXECUTOR); \
426429
assert(tstate->interp->jit_tracer_code_curr_size == 2); \
427430
ENTER_TRACING(); \

Python/executor_cases.c.h

Lines changed: 20 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,10 @@ _PyJIT_translate_single_bytecode_to_trace(
584584
return 1;
585585
}
586586

587+
if (opcode == JUMP_BACKWARD_NO_INTERRUPT) {
588+
return 1;
589+
}
590+
587591
if (opcode == ENTER_EXECUTOR) {
588592
ADD_TO_TRACE(_CHECK_VALIDITY, 0, 0, target);
589593
ADD_TO_TRACE(_SET_IP, 0, (uintptr_t)target_instr, target);
@@ -899,9 +903,13 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length)
899903
exit_op = _HANDLE_PENDING_AND_DEOPT;
900904
}
901905
int32_t jump_target = target;
902-
if (opcode == _FOR_ITER_TIER_TWO || opcode == _GUARD_IP) {
906+
bool unique_target = false;
907+
if (opcode == _FOR_ITER_TIER_TWO) {
908+
exit_op = _DYNAMIC_EXIT;
909+
}
910+
else if (opcode == _GUARD_IP) {
903911
exit_op = _DYNAMIC_EXIT;
904-
jump_target = current_jump_target + 1;
912+
unique_target = true;
905913
}
906914
if (is_for_iter_test[opcode]) {
907915
/* Target the POP_TOP immediately after the END_FOR,
@@ -910,7 +918,7 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length)
910918
int32_t next_inst = target + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + extended_arg;
911919
jump_target = next_inst + inst->oparg + 1;
912920
}
913-
if (jump_target != current_jump_target || current_exit_op != exit_op) {
921+
if (unique_target || jump_target != current_jump_target || current_exit_op != exit_op) {
914922
make_exit(&buffer[next_spare], exit_op, jump_target);
915923
current_exit_op = exit_op;
916924
current_jump_target = jump_target;

Tools/cases_generator/tracer_generator.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def __init__(self, out: CWriter, labels: dict[str, Label], cannot_escape: bool =
4040
self._replacers = {
4141
**self._replacers,
4242
"DISPATCH": self.dispatch,
43+
"DISPATCH_INLINED": self.dispatch_inlined,
4344
}
4445

4546
def dispatch(
@@ -57,6 +58,20 @@ def dispatch(
5758
self.emit("TRACING_DISPATCH")
5859
return False
5960

61+
def dispatch_inlined(
62+
self,
63+
tkn: Token,
64+
tkn_iter: TokenIterator,
65+
uop: CodeSection,
66+
storage: Storage,
67+
inst: Instruction | None,
68+
) -> bool:
69+
if storage.spilled:
70+
raise analysis_error("stack_pointer needs reloading before dispatch", tkn)
71+
storage.stack.flush(self.out)
72+
self.out.start_line()
73+
self.emit("TRACING_DISPATCH_INLINED")
74+
return False
6075
def record_jump_taken(
6176
self,
6277
tkn: Token,

0 commit comments

Comments
 (0)