gh-148378: Allow multiple consecutive recording ops per macro op (GH-148496)

This commit is contained in:
Hai Zhu 2026-04-14 19:26:53 +08:00 committed by GitHub
parent 21da9d7164
commit 5ce0fe8b6c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 318 additions and 82 deletions

View file

@ -866,6 +866,7 @@ _PyJit_translate_single_bytecode_to_trace(
assert(nuops > 0);
uint32_t orig_oparg = oparg; // For OPARG_TOP/BOTTOM
uint32_t orig_target = target;
int record_idx = 0;
for (int i = 0; i < nuops; i++) {
oparg = orig_oparg;
target = orig_target;
@ -946,8 +947,9 @@ _PyJit_translate_single_bytecode_to_trace(
operand = next->op.arg;
}
else if (_PyUop_Flags[uop] & HAS_RECORDS_VALUE_FLAG) {
PyObject *recorded_value = tracer->prev_state.recorded_value;
tracer->prev_state.recorded_value = NULL;
PyObject *recorded_value = tracer->prev_state.recorded_values[record_idx];
tracer->prev_state.recorded_values[record_idx] = NULL;
record_idx++;
operand = (uintptr_t)recorded_value;
}
// All other instructions
@ -1060,12 +1062,16 @@ _PyJit_TryInitializeTracing(
tracer->prev_state.instr_frame = frame;
tracer->prev_state.instr_oparg = oparg;
tracer->prev_state.instr_stacklevel = tracer->initial_state.stack_depth;
tracer->prev_state.recorded_value = NULL;
uint8_t record_func_index = _PyOpcode_RecordFunctionIndices[curr_instr->op.code];
if (record_func_index) {
_Py_RecordFuncPtr record_func = _PyOpcode_RecordFunctions[record_func_index];
record_func(frame, stack_pointer, oparg, &tracer->prev_state.recorded_value);
tracer->prev_state.recorded_count = 0;
for (int i = 0; i < MAX_RECORDED_VALUES; i++) {
tracer->prev_state.recorded_values[i] = NULL;
}
const _PyOpcodeRecordEntry *record_entry = &_PyOpcode_RecordEntries[curr_instr->op.code];
for (int i = 0; i < record_entry->count; i++) {
_Py_RecordFuncPtr record_func = _PyOpcode_RecordFunctions[record_entry->indices[i]];
record_func(frame, stack_pointer, oparg, &tracer->prev_state.recorded_values[i]);
}
tracer->prev_state.recorded_count = record_entry->count;
assert(curr_instr->op.code == JUMP_BACKWARD_JIT || curr_instr->op.code == RESUME_CHECK_JIT || (exit != NULL));
tracer->initial_state.jump_backward_instr = curr_instr;
@ -1117,7 +1123,10 @@ _PyJit_FinalizeTracing(PyThreadState *tstate, int err)
Py_CLEAR(tracer->initial_state.func);
Py_CLEAR(tracer->initial_state.executor);
Py_CLEAR(tracer->prev_state.instr_code);
Py_CLEAR(tracer->prev_state.recorded_value);
for (int i = 0; i < MAX_RECORDED_VALUES; i++) {
Py_CLEAR(tracer->prev_state.recorded_values[i]);
}
tracer->prev_state.recorded_count = 0;
uop_buffer_init(buffer, &tracer->uop_array[0], UOP_MAX_TRACE_LENGTH);
tracer->is_tracing = false;
}