-A new tracing frontend for the JIT compiler has been implemented. Patch by Ken Jin. Design for CPython by Brandt Bucher, Mark Shannon and Ken Jin.
+A new tracing frontend for the JIT compiler has been implemented. Patch by Ken Jin. Design for CPython by Mark Shannon, Ken Jin and Brandt Bucher.
}
tier2 op(_DEOPT, (--)) {
- GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET(), 0);
+ GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET());
}
tier2 op(_HANDLE_PENDING_AND_DEOPT, (--)) {
int err = _Py_HandlePending(tstate);
- GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET(), 0);
+ GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET());
}
tier2 op(_ERROR_POP_N, (target/2 --)) {
// gh-140104: The exception handler expects frame->instr_ptr to be pointing to next_instr, not this_instr!
frame->instr_ptr = next_instr;
SYNC_SP();
- GOTO_TIER_ONE(NULL, 0);
+ GOTO_TIER_ONE(NULL);
}
/* Progress is guaranteed if we DEOPT on the eval breaker, because
_Py_BackoffCounter temperature = exit->temperature;
if (!backoff_counter_triggers(temperature)) {
exit->temperature = advance_backoff_counter(temperature);
- GOTO_TIER_ONE(target, 0);
+ GOTO_TIER_ONE(target);
}
_PyExecutorObject *executor;
if (target->op.code == ENTER_EXECUTOR) {
// So setting it to anything else is wrong.
_PyJit_InitializeTracing(tstate, frame, target, target, target, STACK_LEVEL(), chain_depth, exit, target->op.arg);
exit->temperature = initial_temperature_backoff_counter();
- GOTO_TIER_ONE(target, 1);
+ GOTO_TIER_ONE_CONTINUE_TRACING(target);
}
assert(tstate->jit_exit == exit);
exit->executor = executor;
TIER2_TO_TIER2(executor);
}
else {
- GOTO_TIER_ONE(target, 0);
+ GOTO_TIER_ONE(target);
}
}
goto tier2_start; \
} while (0)
-#define GOTO_TIER_ONE(TARGET, SHOULD_CONTINUE_TRACING) \
- do \
- { \
- tstate->current_executor = NULL; \
- OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); \
- _PyFrame_SetStackPointer(frame, stack_pointer); \
- return (_Py_CODEUNIT *)(((uintptr_t)(TARGET)) | SHOULD_CONTINUE_TRACING); \
+#define GOTO_TIER_ONE_SETUP \
+ tstate->current_executor = NULL; \
+ OPT_HIST(trace_uop_execution_counter, trace_run_length_hist); \
+ _PyFrame_SetStackPointer(frame, stack_pointer);
+
+#define GOTO_TIER_ONE(TARGET) \
+ do \
+ { \
+ GOTO_TIER_ONE_SETUP \
+ return (_Py_CODEUNIT *)(TARGET); \
+ } while (0)
+
+#define GOTO_TIER_ONE_CONTINUE_TRACING(TARGET) \
+ do \
+ { \
+ GOTO_TIER_ONE_SETUP \
+ return (_Py_CODEUNIT *)(((uintptr_t)(TARGET))| 1); \
} while (0)
#define CURRENT_OPARG() (next_uop[-1].oparg)
}
case _DEOPT: {
- GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET(), 0);
+ GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET());
break;
}
_PyFrame_SetStackPointer(frame, stack_pointer);
int err = _Py_HandlePending(tstate);
stack_pointer = _PyFrame_GetStackPointer(frame);
- GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET(), 0);
+ GOTO_TIER_ONE(err ? NULL : _PyFrame_GetBytecode(frame) + CURRENT_TARGET());
break;
}
_Py_CODEUNIT *current_instr = _PyFrame_GetBytecode(frame) + target;
_Py_CODEUNIT *next_instr = current_instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[current_instr->op.code]];
frame->instr_ptr = next_instr;
- GOTO_TIER_ONE(NULL, 0);
+ GOTO_TIER_ONE(NULL);
break;
}
_Py_BackoffCounter temperature = exit->temperature;
if (!backoff_counter_triggers(temperature)) {
exit->temperature = advance_backoff_counter(temperature);
- GOTO_TIER_ONE(target, 0);
+ GOTO_TIER_ONE(target);
}
_PyExecutorObject *executor;
if (target->op.code == ENTER_EXECUTOR) {
int chain_depth = previous_executor->vm_data.chain_depth + 1;
_PyJit_InitializeTracing(tstate, frame, target, target, target, STACK_LEVEL(), chain_depth, exit, target->op.arg);
exit->temperature = initial_temperature_backoff_counter();
- GOTO_TIER_ONE(target, 1);
+ GOTO_TIER_ONE_CONTINUE_TRACING(target);
}
assert(tstate->jit_exit == exit);
exit->executor = executor;
TIER2_TO_TIER2(executor);
}
else {
- GOTO_TIER_ONE(target, 0);
+ GOTO_TIER_ONE(target);
}
break;
}