mirror of
https://github.com/python/cpython.git
synced 2026-04-20 02:40:59 +00:00
gh-148378: Allow multiple consecutive recording ops per macro op (GH-148496)
This commit is contained in:
parent
21da9d7164
commit
5ce0fe8b6c
9 changed files with 318 additions and 82 deletions
|
|
@ -6349,7 +6349,10 @@ dummy_func(
|
|||
ERROR_IF(err < 0);
|
||||
DISPATCH();
|
||||
}
|
||||
Py_CLEAR(tracer->prev_state.recorded_value);
|
||||
for (int i = 0; i < tracer->prev_state.recorded_count; i++) {
|
||||
Py_CLEAR(tracer->prev_state.recorded_values[i]);
|
||||
}
|
||||
tracer->prev_state.recorded_count = 0;
|
||||
tracer->prev_state.instr = next_instr;
|
||||
PyObject *prev_code = PyStackRef_AsPyObjectBorrow(frame->f_executable);
|
||||
if (tracer->prev_state.instr_code != (PyCodeObject *)prev_code) {
|
||||
|
|
@ -6363,11 +6366,12 @@ dummy_func(
|
|||
(&next_instr[1])->counter = trigger_backoff_counter();
|
||||
}
|
||||
|
||||
uint8_t record_func_index = _PyOpcode_RecordFunctionIndices[opcode];
|
||||
if (record_func_index) {
|
||||
_Py_RecordFuncPtr doesnt_escape = _PyOpcode_RecordFunctions[record_func_index];
|
||||
doesnt_escape(frame, stack_pointer, oparg, &tracer->prev_state.recorded_value);
|
||||
const _PyOpcodeRecordEntry *record_entry = &_PyOpcode_RecordEntries[opcode];
|
||||
for (int i = 0; i < record_entry->count; i++) {
|
||||
_Py_RecordFuncPtr doesnt_escape = _PyOpcode_RecordFunctions[record_entry->indices[i]];
|
||||
doesnt_escape(frame, stack_pointer, oparg, &tracer->prev_state.recorded_values[i]);
|
||||
}
|
||||
tracer->prev_state.recorded_count = record_entry->count;
|
||||
DISPATCH_GOTO_NON_TRACING();
|
||||
#else
|
||||
(void)prev_instr;
|
||||
|
|
|
|||
18
Python/generated_cases.c.h
generated
18
Python/generated_cases.c.h
generated
|
|
@ -12314,9 +12314,12 @@
|
|||
}
|
||||
DISPATCH();
|
||||
}
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_CLEAR(tracer->prev_state.recorded_value);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
for (int i = 0; i < tracer->prev_state.recorded_count; i++) {
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
Py_CLEAR(tracer->prev_state.recorded_values[i]);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
}
|
||||
tracer->prev_state.recorded_count = 0;
|
||||
tracer->prev_state.instr = next_instr;
|
||||
PyObject *prev_code = PyStackRef_AsPyObjectBorrow(frame->f_executable);
|
||||
if (tracer->prev_state.instr_code != (PyCodeObject *)prev_code) {
|
||||
|
|
@ -12330,11 +12333,12 @@
|
|||
if (_PyOpcode_Caches[_PyOpcode_Deopt[opcode]]) {
|
||||
(&next_instr[1])->counter = trigger_backoff_counter();
|
||||
}
|
||||
uint8_t record_func_index = _PyOpcode_RecordFunctionIndices[opcode];
|
||||
if (record_func_index) {
|
||||
_Py_RecordFuncPtr doesnt_escape = _PyOpcode_RecordFunctions[record_func_index];
|
||||
doesnt_escape(frame, stack_pointer, oparg, &tracer->prev_state.recorded_value);
|
||||
const _PyOpcodeRecordEntry *record_entry = &_PyOpcode_RecordEntries[opcode];
|
||||
for (int i = 0; i < record_entry->count; i++) {
|
||||
_Py_RecordFuncPtr doesnt_escape = _PyOpcode_RecordFunctions[record_entry->indices[i]];
|
||||
doesnt_escape(frame, stack_pointer, oparg, &tracer->prev_state.recorded_values[i]);
|
||||
}
|
||||
tracer->prev_state.recorded_count = record_entry->count;
|
||||
DISPATCH_GOTO_NON_TRACING();
|
||||
#else
|
||||
(void)prev_instr;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
71
Python/record_functions.c.h
generated
71
Python/record_functions.c.h
generated
|
|
@ -99,41 +99,42 @@ void _PyOpcode_RecordFunction_CODE(_PyInterpreterFrame *frame, _PyStackRef *stac
|
|||
#define _RECORD_BOUND_METHOD_INDEX 6
|
||||
#define _RECORD_CALLABLE_KW_INDEX 7
|
||||
#define _RECORD_4OS_INDEX 8
|
||||
const uint8_t _PyOpcode_RecordFunctionIndices[256] = {
|
||||
[TO_BOOL_ALWAYS_TRUE] = _RECORD_TOS_TYPE_INDEX,
|
||||
[BINARY_OP_SUBSCR_GETITEM] = _RECORD_NOS_INDEX,
|
||||
[SEND_GEN] = _RECORD_3OS_GEN_FUNC_INDEX,
|
||||
[LOAD_SUPER_ATTR_METHOD] = _RECORD_NOS_INDEX,
|
||||
[LOAD_ATTR_INSTANCE_VALUE] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_WITH_HINT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_SLOT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_PROPERTY] = _RECORD_TOS_TYPE_INDEX,
|
||||
[STORE_ATTR_INSTANCE_VALUE] = _RECORD_TOS_TYPE_INDEX,
|
||||
[STORE_ATTR_WITH_HINT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[STORE_ATTR_SLOT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[FOR_ITER_GEN] = _RECORD_NOS_GEN_FUNC_INDEX,
|
||||
[LOAD_ATTR_METHOD_WITH_VALUES] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_METHOD_NO_DICT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[LOAD_ATTR_METHOD_LAZY_DICT] = _RECORD_TOS_TYPE_INDEX,
|
||||
[CALL_PY_GENERAL] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BOUND_METHOD_GENERAL] = _RECORD_BOUND_METHOD_INDEX,
|
||||
[CALL_NON_PY_GENERAL] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = _RECORD_BOUND_METHOD_INDEX,
|
||||
[CALL_PY_EXACT_ARGS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BUILTIN_CLASS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BUILTIN_O] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BUILTIN_FAST] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_METHOD_DESCRIPTOR_O] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = _RECORD_CALLABLE_INDEX,
|
||||
[CALL_KW_PY] = _RECORD_CALLABLE_KW_INDEX,
|
||||
[CALL_KW_BOUND_METHOD] = _RECORD_CALLABLE_KW_INDEX,
|
||||
[CALL_EX_PY] = _RECORD_4OS_INDEX,
|
||||
|
||||
const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = {
|
||||
[TO_BOOL_ALWAYS_TRUE] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[BINARY_OP_SUBSCR_GETITEM] = {1, {_RECORD_NOS_INDEX}},
|
||||
[SEND_GEN] = {1, {_RECORD_3OS_GEN_FUNC_INDEX}},
|
||||
[LOAD_SUPER_ATTR_METHOD] = {1, {_RECORD_NOS_INDEX}},
|
||||
[LOAD_ATTR_INSTANCE_VALUE] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[LOAD_ATTR_WITH_HINT] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[LOAD_ATTR_SLOT] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[LOAD_ATTR_PROPERTY] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[STORE_ATTR_INSTANCE_VALUE] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[STORE_ATTR_WITH_HINT] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[STORE_ATTR_SLOT] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[FOR_ITER_GEN] = {1, {_RECORD_NOS_GEN_FUNC_INDEX}},
|
||||
[LOAD_ATTR_METHOD_WITH_VALUES] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[LOAD_ATTR_METHOD_NO_DICT] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[LOAD_ATTR_METHOD_LAZY_DICT] = {1, {_RECORD_TOS_TYPE_INDEX}},
|
||||
[CALL_PY_GENERAL] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_BOUND_METHOD_GENERAL] = {1, {_RECORD_BOUND_METHOD_INDEX}},
|
||||
[CALL_NON_PY_GENERAL] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_BOUND_METHOD_EXACT_ARGS] = {1, {_RECORD_BOUND_METHOD_INDEX}},
|
||||
[CALL_PY_EXACT_ARGS] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_ALLOC_AND_ENTER_INIT] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_BUILTIN_CLASS] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_BUILTIN_O] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_BUILTIN_FAST] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_BUILTIN_FAST_WITH_KEYWORDS] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_METHOD_DESCRIPTOR_O] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_METHOD_DESCRIPTOR_NOARGS] = {1, {_RECORD_CALLABLE_INDEX}},
|
||||
[CALL_KW_PY] = {1, {_RECORD_CALLABLE_KW_INDEX}},
|
||||
[CALL_KW_BOUND_METHOD] = {1, {_RECORD_CALLABLE_KW_INDEX}},
|
||||
[CALL_EX_PY] = {1, {_RECORD_4OS_INDEX}},
|
||||
};
|
||||
|
||||
const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[9] = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue