From 5ce0fe8b6ce01744ec253bf79016403ca76c1153 Mon Sep 17 00:00:00 2001 From: Hai Zhu Date: Tue, 14 Apr 2026 19:26:53 +0800 Subject: [PATCH 01/12] gh-148378: Allow multiple consecutive recording ops per macro op (GH-148496) --- Include/internal/pycore_optimizer.h | 11 +- Lib/test/test_generated_cases.py | 199 +++++++++++++++++- Modules/_testinternalcapi/test_cases.c.h | 18 +- Python/bytecodes.c | 14 +- Python/generated_cases.c.h | 18 +- Python/optimizer.c | 25 ++- Python/record_functions.c.h | 71 ++++--- Tools/cases_generator/analyzer.py | 19 +- .../record_function_generator.py | 25 ++- 9 files changed, 318 insertions(+), 82 deletions(-) diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index e7b688333d9ced..78bbdc2026e9d2 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -91,13 +91,15 @@ typedef struct _PyJitTracerInitialState { _Py_CODEUNIT *jump_backward_instr; } _PyJitTracerInitialState; +#define MAX_RECORDED_VALUES 3 typedef struct _PyJitTracerPreviousState { int instr_oparg; int instr_stacklevel; _Py_CODEUNIT *instr; PyCodeObject *instr_code; // Strong struct _PyInterpreterFrame *instr_frame; - PyObject *recorded_value; // Strong, may be NULL + PyObject *recorded_values[MAX_RECORDED_VALUES]; // Strong, may be NULL + int recorded_count; } _PyJitTracerPreviousState; typedef struct _PyJitTracerTranslatorState { @@ -481,7 +483,12 @@ void _PyJit_TracerFree(_PyThreadStateImpl *_tstate); #ifdef _Py_TIER2 typedef void (*_Py_RecordFuncPtr)(_PyInterpreterFrame *frame, _PyStackRef *stackpointer, int oparg, PyObject **recorded_value); PyAPI_DATA(const _Py_RecordFuncPtr) _PyOpcode_RecordFunctions[]; -PyAPI_DATA(const uint8_t) _PyOpcode_RecordFunctionIndices[256]; + +typedef struct { + uint8_t count; + uint8_t indices[MAX_RECORDED_VALUES]; +} _PyOpcodeRecordEntry; +PyAPI_DATA(const _PyOpcodeRecordEntry) _PyOpcode_RecordEntries[256]; #endif #ifdef __cplusplus diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index 33fae682a3ceec..62cf0c0c6af0b2 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -29,12 +29,13 @@ def skip_if_different_mount_drives(): test_tools.skip_if_missing("cases_generator") with test_tools.imports_under_tool("cases_generator"): - from analyzer import StackItem + from analyzer import StackItem, analyze_files from cwriter import CWriter import parser from stack import Local, Stack import tier1_generator import optimizer_generator + import record_function_generator def handle_stderr(): @@ -1948,6 +1949,202 @@ def test_recording_after_non_specializing(self): with self.assertRaisesRegex(SyntaxError, "Recording uop"): self.run_cases_test(input, "") + def test_multiple_consecutive_recording_uops(self): + """Multiple consecutive recording uops at the start of a macro are legal.""" + input = """ + tier2 op(_RECORD_A, (a, b -- a, b)) { + RECORD_VALUE(a); + } + tier2 op(_RECORD_B, (a, b -- a, b)) { + RECORD_VALUE(b); + } + op(_DO_STUFF, (a, b -- res)) { + res = a; + INPUTS_DEAD(); + } + macro(OP) = _RECORD_A + _RECORD_B + _DO_STUFF; + """ + output = """ + TARGET(OP) { + #if _Py_TAIL_CALL_INTERP + int opcode = OP; + (void)(opcode); + #endif + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(OP); + _PyStackRef a; + _PyStackRef res; + // _DO_STUFF + { + a = stack_pointer[-2]; + res = a; + } + stack_pointer[-2] = res; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_multiple_recording_uops_after_specializing(self): + """Multiple recording uops after a specializing uop are legal.""" + input = """ + specializing op(_SPECIALIZE_OP, (counter/1, a, b -- a, b)) { + SPAM(); + } + tier2 op(_RECORD_A, (a, b -- a, b)) { + RECORD_VALUE(a); + } + tier2 op(_RECORD_B, (a, b -- a, b)) { + RECORD_VALUE(b); + } + op(_DO_STUFF, (a, b -- res)) { + res = a; + INPUTS_DEAD(); + } + macro(OP) = _SPECIALIZE_OP + _RECORD_A + _RECORD_B + unused/2 + _DO_STUFF; + """ + output = """ + TARGET(OP) { + #if _Py_TAIL_CALL_INTERP + int opcode = OP; + (void)(opcode); + #endif + _Py_CODEUNIT* const this_instr = next_instr; + (void)this_instr; + frame->instr_ptr = next_instr; + next_instr += 4; + INSTRUCTION_STATS(OP); + _PyStackRef a; + _PyStackRef res; + // _SPECIALIZE_OP + { + uint16_t counter = read_u16(&this_instr[1].cache); + (void)counter; + SPAM(); + } + /* Skip 2 cache entries */ + // _DO_STUFF + { + a = stack_pointer[-2]; + res = a; + } + stack_pointer[-2] = res; + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + DISPATCH(); + } + """ + self.run_cases_test(input, output) + + def test_recording_uop_between_real_uops_rejected(self): + """A recording uop sandwiched between real uops is rejected.""" + input = """ + tier2 op(_RECORD_A, (a, b -- a, b)) { + RECORD_VALUE(a); + } + op(_FIRST, (a, b -- a, b)) { + first(a); + } + tier2 op(_RECORD_B, (a, b -- a, b)) { + RECORD_VALUE(b); + } + macro(OP) = _RECORD_A + _FIRST + _RECORD_B; + """ + with self.assertRaisesRegex(SyntaxError, + "must precede all " + "non-recording, non-specializing uops"): + self.run_cases_test(input, "") + + +class TestRecorderTableGeneration(unittest.TestCase): + + def setUp(self) -> None: + super().setUp() + self.maxDiff = None + self.temp_dir = tempfile.gettempdir() + self.temp_input_filename = os.path.join(self.temp_dir, "input.txt") + + def tearDown(self) -> None: + try: + os.remove(self.temp_input_filename) + except FileNotFoundError: + pass + super().tearDown() + + def generate_tables(self, input: str) -> str: + import io + with open(self.temp_input_filename, "w+") as f: + f.write(parser.BEGIN_MARKER) + f.write(input) + f.write(parser.END_MARKER) + with handle_stderr(): + analysis = analyze_files([self.temp_input_filename]) + buf = io.StringIO() + out = CWriter(buf, 0, False) + record_function_generator.generate_recorder_tables(analysis, out) + return buf.getvalue() + + def test_single_recording_uop_generates_count(self): + input = """ + tier2 op(_RECORD_TOS, (value -- value)) { + RECORD_VALUE(value); + } + op(_DO_STUFF, (value -- res)) { + res = value; + } + macro(OP) = _RECORD_TOS + _DO_STUFF; + """ + output = self.generate_tables(input) + self.assertIn("_RECORD_TOS_INDEX", output) + self.assertIn("[OP] = {1, {_RECORD_TOS_INDEX}}", output) + + def test_three_recording_uops_generate_count_3_in_order(self): + input = """ + tier2 op(_RECORD_X, (a, b, c -- a, b, c)) { + RECORD_VALUE(a); + } + tier2 op(_RECORD_Y, (a, b, c -- a, b, c)) { + RECORD_VALUE(b); + } + tier2 op(_RECORD_Z, (a, b, c -- a, b, c)) { + RECORD_VALUE(c); + } + op(_DO_STUFF, (a, b, c -- res)) { + res = a; + } + macro(OP) = _RECORD_X + _RECORD_Y + _RECORD_Z + _DO_STUFF; + """ + output = self.generate_tables(input) + self.assertIn( + "[OP] = {3, {_RECORD_X_INDEX, _RECORD_Y_INDEX, _RECORD_Z_INDEX}}", + output, + ) + + def test_four_recording_uops_rejected(self): + input = """ + tier2 op(_RECORD_A, (a, b, c, d -- a, b, c, d)) { + RECORD_VALUE(a); + } + tier2 op(_RECORD_B, (a, b, c, d -- a, b, c, d)) { + RECORD_VALUE(b); + } + tier2 op(_RECORD_C, (a, b, c, d -- a, b, c, d)) { + RECORD_VALUE(c); + } + tier2 op(_RECORD_D, (a, b, c, d -- a, b, c, d)) { + RECORD_VALUE(d); + } + op(_DO_STUFF, (a, b, c, d -- res)) { + res = a; + } + macro(OP) = _RECORD_A + _RECORD_B + _RECORD_C + _RECORD_D + _DO_STUFF; + """ + with self.assertRaisesRegex(ValueError, "exceeds MAX_RECORDED_VALUES"): + self.generate_tables(input) + class TestGeneratedAbstractCases(unittest.TestCase): def setUp(self) -> None: diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 041adcff388a41..8bf751026bd35c 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -12317,9 +12317,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) { @@ -12333,11 +12336,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; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index b6526b08c0a816..57731fc65ed35c 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -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; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index ae01925077c29e..d710e82a306ab4 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -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; diff --git a/Python/optimizer.c b/Python/optimizer.c index f09bf778587b12..5d5aecda4e45e3 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -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; } diff --git a/Python/record_functions.c.h b/Python/record_functions.c.h index db03374b62f7ba..25bca4735726fd 100644 --- a/Python/record_functions.c.h +++ b/Python/record_functions.c.h @@ -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] = { diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 100de4c7250907..414ca18be4654c 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -1132,9 +1132,7 @@ def add_macro( macro: parser.Macro, instructions: dict[str, Instruction], uops: dict[str, Uop] ) -> None: parts: list[Part] = [] - # Track the last non-specializing uop seen, so that recording uops - # can follow specializing ones without triggering the position check. - prev_uop: Uop | None = None + seen_real_uop = False for part in macro.uops: match part: case parser.OpName(): @@ -1146,14 +1144,15 @@ def add_macro( f"No Uop named {part.name}", macro.tokens[0] ) uop = uops[part.name] - if uop.properties.records_value and prev_uop is not None: - raise analysis_error( - f"Recording uop {part.name} is not allowed " - f"after non-specializing uops in macro", - macro.tokens[0]) + if uop.properties.records_value: + if seen_real_uop: + raise analysis_error( + f"Recording uop {part.name} must precede all " + f"non-recording, non-specializing uops in macro", + macro.tokens[0]) + elif "specializing" not in uop.annotations: + seen_real_uop = True parts.append(uop) - if "specializing" not in uop.annotations: - prev_uop = uop case parser.CacheEffect(): parts.append(Skip(part.size)) case _: diff --git a/Tools/cases_generator/record_function_generator.py b/Tools/cases_generator/record_function_generator.py index 58d948f198c4dc..d7ae0ebf79fe62 100644 --- a/Tools/cases_generator/record_function_generator.py +++ b/Tools/cases_generator/record_function_generator.py @@ -25,6 +25,9 @@ DEFAULT_OUTPUT = ROOT / "Python/recorder_functions.c.h" +# Must match MAX_RECORDED_VALUES in Include/internal/pycore_optimizer.h. +MAX_RECORDED_VALUES = 3 + class RecorderEmitter(Emitter): def __init__(self, out: CWriter): @@ -81,27 +84,35 @@ def generate_recorder_functions(filenames: list[str], analysis: Analysis, out: C def generate_recorder_tables(analysis: Analysis, out: CWriter) -> None: record_function_indexes: dict[str, int] = dict() - record_table: dict[str, str] = {} + record_table: dict[str, list[str]] = {} index = 1 for inst in analysis.instructions.values(): if not inst.properties.records_value: continue + records: list[str] = [] for part in inst.parts: if not part.properties.records_value: continue if part.name not in record_function_indexes: record_function_indexes[part.name] = index index += 1 - record_table[inst.name] = part.name - break + records.append(part.name) + if records: + if len(records) > MAX_RECORDED_VALUES: + raise ValueError( + f"Instruction {inst.name} has {len(records)} recording ops, " + f"exceeds MAX_RECORDED_VALUES ({MAX_RECORDED_VALUES})" + ) + record_table[inst.name] = records func_count = len(record_function_indexes) for name, index in record_function_indexes.items(): out.emit(f"#define {name}_INDEX {index}\n") - args = "_PyJitTracerState *tracer, _PyInterpreterFrame *frame, _PyStackRef *stackpointer, int oparg" - out.emit("const uint8_t _PyOpcode_RecordFunctionIndices[256] = {\n") - for inst_name, record_name in record_table.items(): - out.emit(f" [{inst_name}] = {record_name}_INDEX,\n") + out.emit("\n") + out.emit("const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = {\n") + for inst_name, record_names in record_table.items(): + indices = ", ".join(f"{name}_INDEX" for name in record_names) + out.emit(f" [{inst_name}] = {{{len(record_names)}, {{{indices}}}}},\n") out.emit("};\n\n") out.emit(f"const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[{func_count+1}] = {{\n") out.emit(" [0] = NULL,\n") From 74a4f8c1d0caece261b379d5a6cd4e41eae3557a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Simon?= Date: Tue, 14 Apr 2026 13:37:41 +0200 Subject: [PATCH 02/12] gh-134551: Add t-strings support to pprint (#134577) Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> --- Doc/whatsnew/3.15.rst | 6 +- Lib/pprint.py | 55 +++++++++++++ Lib/test/test_pprint.py | 80 +++++++++++++++++++ ...-05-23-10-28-51.gh-issue-134551.0rnq0X.rst | 1 + 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-05-23-10-28-51.gh-issue-134551.0rnq0X.rst diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index c754b634ecccfa..fe2ddfdcd0e917 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -1551,7 +1551,11 @@ pprint :func:`pprint.pformat`, :func:`pprint.pp`. If true, the output will be formatted similar to pretty-printed :func:`json.dumps` when *indent* is supplied. - (Contributed by Stefan Todoran and Semyon Moroz in :gh:`112632`.) + (Contributed by Stefan Todoran, Semyon Moroz and Hugo van Kemenade in + :gh:`112632`.) + +* Add t-string support to :mod:`pprint`. + (Contributed by Loïc Simon and Hugo van Kemenade in :gh:`134551`.) sre_* diff --git a/Lib/pprint.py b/Lib/pprint.py index f197d7d17cdb96..7355021998081d 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -735,6 +735,61 @@ def _pprint_user_string(self, object, stream, indent, allowance, context, level) _dispatch[_collections.UserString.__repr__] = _pprint_user_string + def _pprint_template(self, object, stream, indent, allowance, context, level): + cls_name = object.__class__.__name__ + if self._expand: + indent += self._indent_per_level + else: + indent += len(cls_name) + 1 + + items = ( + ("strings", object.strings), + ("interpolations", object.interpolations), + ) + stream.write(self._format_block_start(cls_name + "(", indent)) + self._format_namespace_items( + items, stream, indent, allowance, context, level + ) + stream.write( + self._format_block_end(")", indent - self._indent_per_level) + ) + + def _pprint_interpolation(self, object, stream, indent, allowance, context, level): + cls_name = object.__class__.__name__ + if self._expand: + indent += self._indent_per_level + items = ( + ("value", object.value), + ("expression", object.expression), + ("conversion", object.conversion), + ("format_spec", object.format_spec), + ) + stream.write(self._format_block_start(cls_name + "(", indent)) + self._format_namespace_items( + items, stream, indent, allowance, context, level + ) + stream.write( + self._format_block_end(")", indent - self._indent_per_level) + ) + else: + indent += len(cls_name) + items = ( + object.value, + object.expression, + object.conversion, + object.format_spec, + ) + stream.write(cls_name + "(") + self._format_items( + items, stream, indent, allowance, context, level + ) + stream.write(")") + + t = t"{0}" + _dispatch[type(t).__repr__] = _pprint_template + _dispatch[type(t.interpolations[0]).__repr__] = _pprint_interpolation + del t + def _safe_repr(self, object, context, maxlevels, level): # Return triple (repr_string, isreadable, isrecursive). typ = type(object) diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index 45e081c233f0b0..041c2072b9e253 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -1515,6 +1515,86 @@ def test_user_string(self): 'jumped over a ' 'lazy dog'}""") + def test_template(self): + d = t"" + self.assertEqual(pprint.pformat(d), + "Template(strings=('',), interpolations=())") + self.assertEqual(pprint.pformat(d), repr(d)) + self.assertEqual(pprint.pformat(d, width=1), +"""\ +Template(strings=('',), + interpolations=())""") + name = "World" + d = t"Hello {name}" + self.assertEqual(pprint.pformat(d), +"""\ +Template(strings=('Hello ', ''), + interpolations=(Interpolation('World', 'name', None, ''),))""") + ver = {3.13: False, 3.14: True} + d = t"Hello { {"name": "Python", "version": ver}!s:z}!" + self.assertEqual(pprint.pformat(d, width=1), +"""\ +Template(strings=('Hello ', + '!'), + interpolations=(Interpolation({'name': 'Python', + 'version': {3.13: False, + 3.14: True}}, + ' ' + '{"name": ' + '"Python", ' + '"version": ' + 'ver}', + 's', + 'z'),))""") + + def test_expand_template(self): + d = t"" + self.assertEqual( + pprint.pformat(d, expand=True), + "Template(strings=('',), interpolations=())", + ) + name = "World" + d = t"Hello {name}" + self.assertEqual( + pprint.pformat(d, width=40, indent=4, expand=True), + """\ +Template( + strings=('Hello ', ''), + interpolations=( + Interpolation( + value='World', + expression='name', + conversion=None, + format_spec='', + ), + ), +)""", + ) + ver = {3.13: False, 3.14: True} + d = t"Hello { {"name": "Python", "version": ver}!s:z}!" + self.assertEqual( + pprint.pformat(d, width=40, indent=4, expand=True), + """\ +Template( + strings=('Hello ', '!'), + interpolations=( + Interpolation( + value={ + 'name': 'Python', + 'version': { + 3.13: False, + 3.14: True, + }, + }, + expression=' {"name": "Python", ' + '"version": ver}', + conversion='s', + format_spec='z', + ), + ), +)""", + ) + def test_expand_dataclass(self): @dataclasses.dataclass class DummyDataclass: diff --git a/Misc/NEWS.d/next/Library/2025-05-23-10-28-51.gh-issue-134551.0rnq0X.rst b/Misc/NEWS.d/next/Library/2025-05-23-10-28-51.gh-issue-134551.0rnq0X.rst new file mode 100644 index 00000000000000..94e0c1e0b225d6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-05-23-10-28-51.gh-issue-134551.0rnq0X.rst @@ -0,0 +1 @@ +Add t-strings support to pprint functions From 4af46b4ab5af49d8df034320a9a70fcbb062f7cf Mon Sep 17 00:00:00 2001 From: Henry Jones <44321887+henryivesjones@users.noreply.github.com> Date: Wed, 15 Apr 2026 01:10:08 +1200 Subject: [PATCH 03/12] gh-148192: Fix Generator._make_boundary behavior with CRLF line endings. (#148193) The Generator._make_boundary regex did not match on boundary phrases correctly when using CRLF line endings due to re.MULTILINE not considering \r\n as a line ending. --- Lib/email/generator.py | 2 +- Lib/test/test_email/test_generator.py | 37 +++++++++++++++++++ ...-04-07-14-13-40.gh-issue-148192.34AUYQ.rst | 3 ++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-04-07-14-13-40.gh-issue-148192.34AUYQ.rst diff --git a/Lib/email/generator.py b/Lib/email/generator.py index cebbc416087fee..ba11d63fba600a 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -392,7 +392,7 @@ def _make_boundary(cls, text=None): b = boundary counter = 0 while True: - cre = cls._compile_re('^--' + re.escape(b) + '(--)?$', re.MULTILINE) + cre = cls._compile_re('^--' + re.escape(b) + '(--)?\r?$', re.MULTILINE) if not cre.search(text): break b = boundary + '.' + str(counter) diff --git a/Lib/test/test_email/test_generator.py b/Lib/test/test_email/test_generator.py index c2d7d09d591e86..3c9a86f3e8cf29 100644 --- a/Lib/test/test_email/test_generator.py +++ b/Lib/test/test_email/test_generator.py @@ -1,13 +1,20 @@ import io import textwrap import unittest +import random +import sys from email import message_from_string, message_from_bytes from email.message import EmailMessage +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText from email.generator import Generator, BytesGenerator +import email.generator from email.headerregistry import Address from email import policy import email.errors from test.test_email import TestEmailBase, parameterize +import test.support + @parameterize @@ -288,6 +295,36 @@ def test_keep_long_encoded_newlines(self): g.flatten(msg) self.assertEqual(s.getvalue(), self.typ(expected)) + def _test_boundary_detection(self, linesep): + # Generate a boundary token in the same way as _make_boundary + token = random.randrange(sys.maxsize) + + def _patch_random_randrange(*args, **kwargs): + return token + + with test.support.swap_attr( + random, "randrange", _patch_random_randrange + ): + boundary = self.genclass._make_boundary(text=None) + boundary_in_part = ( + "this goes before the boundary\n--" + + boundary + + "\nthis goes after\n" + ) + msg = MIMEMultipart() + msg.attach(MIMEText(boundary_in_part)) + self.genclass(self.ioclass()).flatten(msg, linesep=linesep) + # Generator checks the message content for the string it is about + # to use as a boundary ('token' in this test) and when it finds it + # in our attachment appends .0 to make the boundary it uses unique. + self.assertEqual(msg.get_boundary(), boundary + ".0") + + def test_lf_boundary_detection(self): + self._test_boundary_detection("\n") + + def test_crlf_boundary_detection(self): + self._test_boundary_detection("\r\n") + class TestGenerator(TestGeneratorBase, TestEmailBase): diff --git a/Misc/NEWS.d/next/Library/2026-04-07-14-13-40.gh-issue-148192.34AUYQ.rst b/Misc/NEWS.d/next/Library/2026-04-07-14-13-40.gh-issue-148192.34AUYQ.rst new file mode 100644 index 00000000000000..87a568b50c17c3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-04-07-14-13-40.gh-issue-148192.34AUYQ.rst @@ -0,0 +1,3 @@ +``email.generator.Generator._make_boundary`` could fail to detect a duplicate +boundary string if linesep was not \n. It now correctly detects boundary +strings when linesep is \r\n as well. From 52a7f1b7f88d7f25e4cf02b6bc5e7521848d99f0 Mon Sep 17 00:00:00 2001 From: Neko Asakura Date: Tue, 14 Apr 2026 10:44:39 -0400 Subject: [PATCH 04/12] gh-148510: restore `func_version` check in `_LOAD_ATTR_PROPERTY_FRAME` (GH-148528) --- Include/internal/pycore_opcode_metadata.h | 2 +- Include/internal/pycore_optimizer.h | 1 + Include/internal/pycore_uop_ids.h | 673 +++++++++++----------- Include/internal/pycore_uop_metadata.h | 14 +- Lib/test/test_capi/test_opt.py | 32 + Modules/_testinternalcapi/test_cases.c.h | 16 +- Python/bytecodes.c | 7 +- Python/executor_cases.c.h | 132 ++++- Python/generated_cases.c.h | 16 +- Python/optimizer_analysis.c | 1 + Python/optimizer_bytecodes.c | 57 +- Python/optimizer_cases.c.h | 48 +- Python/specialize.c | 5 + 13 files changed, 589 insertions(+), 415 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index aa7b44d9e7f16b..ce07b71192bf3b 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1451,7 +1451,7 @@ _PyOpcode_macro_expansion[256] = { [LOAD_ATTR_MODULE] = { .nuops = 4, .uops = { { _LOAD_ATTR_MODULE, 2, 1 }, { _LOAD_ATTR_MODULE, OPERAND1_1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } }, [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = { .nuops = 3, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_NONDESCRIPTOR_NO_DICT, 4, 5 } } }, [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT, OPARG_SIMPLE, 3 }, { _GUARD_KEYS_VERSION, 2, 3 }, { _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, 4, 5 } } }, - [LOAD_ATTR_PROPERTY] = { .nuops = 6, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_PROPERTY_FRAME, 4, 5 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 9 }, { _PUSH_FRAME, OPARG_SIMPLE, 9 } } }, + [LOAD_ATTR_PROPERTY] = { .nuops = 7, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_PROPERTY_FRAME, 2, 3 }, { _LOAD_ATTR_PROPERTY_FRAME, OPERAND1_4, 5 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 9 }, { _PUSH_FRAME, OPARG_SIMPLE, 9 } } }, [LOAD_ATTR_SLOT] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_SLOT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } }, [LOAD_ATTR_WITH_HINT] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_WITH_HINT, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } }, [LOAD_BUILD_CLASS] = { .nuops = 1, .uops = { { _LOAD_BUILD_CLASS, OPARG_SIMPLE, 0 } } }, diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index 78bbdc2026e9d2..a809a7e25526f6 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -402,6 +402,7 @@ extern JitOptRef _Py_uop_sym_new_null(JitOptContext *ctx); extern bool _Py_uop_sym_has_type(JitOptRef sym); extern bool _Py_uop_sym_matches_type(JitOptRef sym, PyTypeObject *typ); extern bool _Py_uop_sym_matches_type_version(JitOptRef sym, unsigned int version); +extern unsigned int _Py_uop_sym_get_type_version(JitOptRef sym); extern void _Py_uop_sym_set_null(JitOptContext *ctx, JitOptRef sym); extern void _Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptRef sym); extern void _Py_uop_sym_set_type(JitOptContext *ctx, JitOptRef sym, PyTypeObject *typ); diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 390bfa27c100c3..105878aef3ae9b 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -1025,341 +1025,344 @@ extern "C" { #define _LOAD_ATTR_MODULE_r12 1235 #define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1236 #define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1237 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1238 -#define _LOAD_ATTR_SLOT_r02 1239 -#define _LOAD_ATTR_SLOT_r12 1240 -#define _LOAD_ATTR_SLOT_r23 1241 -#define _LOAD_ATTR_WITH_HINT_r12 1242 -#define _LOAD_BUILD_CLASS_r01 1243 -#define _LOAD_BYTECODE_r00 1244 -#define _LOAD_COMMON_CONSTANT_r01 1245 -#define _LOAD_COMMON_CONSTANT_r12 1246 -#define _LOAD_COMMON_CONSTANT_r23 1247 -#define _LOAD_CONST_r01 1248 -#define _LOAD_CONST_r12 1249 -#define _LOAD_CONST_r23 1250 -#define _LOAD_CONST_INLINE_r01 1251 -#define _LOAD_CONST_INLINE_r12 1252 -#define _LOAD_CONST_INLINE_r23 1253 -#define _LOAD_CONST_INLINE_BORROW_r01 1254 -#define _LOAD_CONST_INLINE_BORROW_r12 1255 -#define _LOAD_CONST_INLINE_BORROW_r23 1256 -#define _LOAD_DEREF_r01 1257 -#define _LOAD_FAST_r01 1258 -#define _LOAD_FAST_r12 1259 -#define _LOAD_FAST_r23 1260 -#define _LOAD_FAST_0_r01 1261 -#define _LOAD_FAST_0_r12 1262 -#define _LOAD_FAST_0_r23 1263 -#define _LOAD_FAST_1_r01 1264 -#define _LOAD_FAST_1_r12 1265 -#define _LOAD_FAST_1_r23 1266 -#define _LOAD_FAST_2_r01 1267 -#define _LOAD_FAST_2_r12 1268 -#define _LOAD_FAST_2_r23 1269 -#define _LOAD_FAST_3_r01 1270 -#define _LOAD_FAST_3_r12 1271 -#define _LOAD_FAST_3_r23 1272 -#define _LOAD_FAST_4_r01 1273 -#define _LOAD_FAST_4_r12 1274 -#define _LOAD_FAST_4_r23 1275 -#define _LOAD_FAST_5_r01 1276 -#define _LOAD_FAST_5_r12 1277 -#define _LOAD_FAST_5_r23 1278 -#define _LOAD_FAST_6_r01 1279 -#define _LOAD_FAST_6_r12 1280 -#define _LOAD_FAST_6_r23 1281 -#define _LOAD_FAST_7_r01 1282 -#define _LOAD_FAST_7_r12 1283 -#define _LOAD_FAST_7_r23 1284 -#define _LOAD_FAST_AND_CLEAR_r01 1285 -#define _LOAD_FAST_AND_CLEAR_r12 1286 -#define _LOAD_FAST_AND_CLEAR_r23 1287 -#define _LOAD_FAST_BORROW_r01 1288 -#define _LOAD_FAST_BORROW_r12 1289 -#define _LOAD_FAST_BORROW_r23 1290 -#define _LOAD_FAST_BORROW_0_r01 1291 -#define _LOAD_FAST_BORROW_0_r12 1292 -#define _LOAD_FAST_BORROW_0_r23 1293 -#define _LOAD_FAST_BORROW_1_r01 1294 -#define _LOAD_FAST_BORROW_1_r12 1295 -#define _LOAD_FAST_BORROW_1_r23 1296 -#define _LOAD_FAST_BORROW_2_r01 1297 -#define _LOAD_FAST_BORROW_2_r12 1298 -#define _LOAD_FAST_BORROW_2_r23 1299 -#define _LOAD_FAST_BORROW_3_r01 1300 -#define _LOAD_FAST_BORROW_3_r12 1301 -#define _LOAD_FAST_BORROW_3_r23 1302 -#define _LOAD_FAST_BORROW_4_r01 1303 -#define _LOAD_FAST_BORROW_4_r12 1304 -#define _LOAD_FAST_BORROW_4_r23 1305 -#define _LOAD_FAST_BORROW_5_r01 1306 -#define _LOAD_FAST_BORROW_5_r12 1307 -#define _LOAD_FAST_BORROW_5_r23 1308 -#define _LOAD_FAST_BORROW_6_r01 1309 -#define _LOAD_FAST_BORROW_6_r12 1310 -#define _LOAD_FAST_BORROW_6_r23 1311 -#define _LOAD_FAST_BORROW_7_r01 1312 -#define _LOAD_FAST_BORROW_7_r12 1313 -#define _LOAD_FAST_BORROW_7_r23 1314 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1315 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1316 -#define _LOAD_FAST_CHECK_r01 1317 -#define _LOAD_FAST_CHECK_r12 1318 -#define _LOAD_FAST_CHECK_r23 1319 -#define _LOAD_FAST_LOAD_FAST_r02 1320 -#define _LOAD_FAST_LOAD_FAST_r13 1321 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1322 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1323 -#define _LOAD_GLOBAL_r00 1324 -#define _LOAD_GLOBAL_BUILTINS_r01 1325 -#define _LOAD_GLOBAL_MODULE_r01 1326 -#define _LOAD_LOCALS_r01 1327 -#define _LOAD_LOCALS_r12 1328 -#define _LOAD_LOCALS_r23 1329 -#define _LOAD_NAME_r01 1330 -#define _LOAD_SMALL_INT_r01 1331 -#define _LOAD_SMALL_INT_r12 1332 -#define _LOAD_SMALL_INT_r23 1333 -#define _LOAD_SMALL_INT_0_r01 1334 -#define _LOAD_SMALL_INT_0_r12 1335 -#define _LOAD_SMALL_INT_0_r23 1336 -#define _LOAD_SMALL_INT_1_r01 1337 -#define _LOAD_SMALL_INT_1_r12 1338 -#define _LOAD_SMALL_INT_1_r23 1339 -#define _LOAD_SMALL_INT_2_r01 1340 -#define _LOAD_SMALL_INT_2_r12 1341 -#define _LOAD_SMALL_INT_2_r23 1342 -#define _LOAD_SMALL_INT_3_r01 1343 -#define _LOAD_SMALL_INT_3_r12 1344 -#define _LOAD_SMALL_INT_3_r23 1345 -#define _LOAD_SPECIAL_r00 1346 -#define _LOAD_SUPER_ATTR_ATTR_r31 1347 -#define _LOAD_SUPER_ATTR_METHOD_r32 1348 -#define _LOCK_OBJECT_r01 1349 -#define _LOCK_OBJECT_r11 1350 -#define _LOCK_OBJECT_r22 1351 -#define _LOCK_OBJECT_r33 1352 -#define _MAKE_CALLARGS_A_TUPLE_r33 1353 -#define _MAKE_CELL_r00 1354 -#define _MAKE_FUNCTION_r12 1355 -#define _MAKE_HEAP_SAFE_r01 1356 -#define _MAKE_HEAP_SAFE_r11 1357 -#define _MAKE_HEAP_SAFE_r22 1358 -#define _MAKE_HEAP_SAFE_r33 1359 -#define _MAKE_WARM_r00 1360 -#define _MAKE_WARM_r11 1361 -#define _MAKE_WARM_r22 1362 -#define _MAKE_WARM_r33 1363 -#define _MAP_ADD_r20 1364 -#define _MATCH_CLASS_r33 1365 -#define _MATCH_KEYS_r23 1366 -#define _MATCH_MAPPING_r02 1367 -#define _MATCH_MAPPING_r12 1368 -#define _MATCH_MAPPING_r23 1369 -#define _MATCH_SEQUENCE_r02 1370 -#define _MATCH_SEQUENCE_r12 1371 -#define _MATCH_SEQUENCE_r23 1372 -#define _MAYBE_EXPAND_METHOD_r00 1373 -#define _MAYBE_EXPAND_METHOD_KW_r11 1374 -#define _MONITOR_CALL_r00 1375 -#define _MONITOR_CALL_KW_r11 1376 -#define _MONITOR_JUMP_BACKWARD_r00 1377 -#define _MONITOR_JUMP_BACKWARD_r11 1378 -#define _MONITOR_JUMP_BACKWARD_r22 1379 -#define _MONITOR_JUMP_BACKWARD_r33 1380 -#define _MONITOR_RESUME_r00 1381 -#define _NOP_r00 1382 -#define _NOP_r11 1383 -#define _NOP_r22 1384 -#define _NOP_r33 1385 -#define _POP_EXCEPT_r10 1386 -#define _POP_ITER_r20 1387 -#define _POP_JUMP_IF_FALSE_r00 1388 -#define _POP_JUMP_IF_FALSE_r10 1389 -#define _POP_JUMP_IF_FALSE_r21 1390 -#define _POP_JUMP_IF_FALSE_r32 1391 -#define _POP_JUMP_IF_TRUE_r00 1392 -#define _POP_JUMP_IF_TRUE_r10 1393 -#define _POP_JUMP_IF_TRUE_r21 1394 -#define _POP_JUMP_IF_TRUE_r32 1395 -#define _POP_TOP_r10 1396 -#define _POP_TOP_FLOAT_r00 1397 -#define _POP_TOP_FLOAT_r10 1398 -#define _POP_TOP_FLOAT_r21 1399 -#define _POP_TOP_FLOAT_r32 1400 -#define _POP_TOP_INT_r00 1401 -#define _POP_TOP_INT_r10 1402 -#define _POP_TOP_INT_r21 1403 -#define _POP_TOP_INT_r32 1404 -#define _POP_TOP_NOP_r00 1405 -#define _POP_TOP_NOP_r10 1406 -#define _POP_TOP_NOP_r21 1407 -#define _POP_TOP_NOP_r32 1408 -#define _POP_TOP_OPARG_r00 1409 -#define _POP_TOP_UNICODE_r00 1410 -#define _POP_TOP_UNICODE_r10 1411 -#define _POP_TOP_UNICODE_r21 1412 -#define _POP_TOP_UNICODE_r32 1413 -#define _PUSH_EXC_INFO_r02 1414 -#define _PUSH_EXC_INFO_r12 1415 -#define _PUSH_EXC_INFO_r23 1416 -#define _PUSH_FRAME_r10 1417 -#define _PUSH_NULL_r01 1418 -#define _PUSH_NULL_r12 1419 -#define _PUSH_NULL_r23 1420 -#define _PUSH_NULL_CONDITIONAL_r00 1421 -#define _PY_FRAME_EX_r31 1422 -#define _PY_FRAME_GENERAL_r01 1423 -#define _PY_FRAME_KW_r11 1424 -#define _REPLACE_WITH_TRUE_r02 1425 -#define _REPLACE_WITH_TRUE_r12 1426 -#define _REPLACE_WITH_TRUE_r23 1427 -#define _RESUME_CHECK_r00 1428 -#define _RESUME_CHECK_r11 1429 -#define _RESUME_CHECK_r22 1430 -#define _RESUME_CHECK_r33 1431 -#define _RETURN_GENERATOR_r01 1432 -#define _RETURN_VALUE_r11 1433 -#define _SAVE_RETURN_OFFSET_r00 1434 -#define _SAVE_RETURN_OFFSET_r11 1435 -#define _SAVE_RETURN_OFFSET_r22 1436 -#define _SAVE_RETURN_OFFSET_r33 1437 -#define _SEND_r33 1438 -#define _SEND_GEN_FRAME_r33 1439 -#define _SETUP_ANNOTATIONS_r00 1440 -#define _SET_ADD_r10 1441 -#define _SET_FUNCTION_ATTRIBUTE_r01 1442 -#define _SET_FUNCTION_ATTRIBUTE_r11 1443 -#define _SET_FUNCTION_ATTRIBUTE_r21 1444 -#define _SET_FUNCTION_ATTRIBUTE_r32 1445 -#define _SET_IP_r00 1446 -#define _SET_IP_r11 1447 -#define _SET_IP_r22 1448 -#define _SET_IP_r33 1449 -#define _SET_UPDATE_r11 1450 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1451 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1452 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1453 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1454 -#define _SPILL_OR_RELOAD_r01 1455 -#define _SPILL_OR_RELOAD_r02 1456 -#define _SPILL_OR_RELOAD_r03 1457 -#define _SPILL_OR_RELOAD_r10 1458 -#define _SPILL_OR_RELOAD_r12 1459 -#define _SPILL_OR_RELOAD_r13 1460 -#define _SPILL_OR_RELOAD_r20 1461 -#define _SPILL_OR_RELOAD_r21 1462 -#define _SPILL_OR_RELOAD_r23 1463 -#define _SPILL_OR_RELOAD_r30 1464 -#define _SPILL_OR_RELOAD_r31 1465 -#define _SPILL_OR_RELOAD_r32 1466 -#define _START_EXECUTOR_r00 1467 -#define _STORE_ATTR_r20 1468 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1469 -#define _STORE_ATTR_SLOT_r21 1470 -#define _STORE_ATTR_WITH_HINT_r21 1471 -#define _STORE_DEREF_r10 1472 -#define _STORE_FAST_LOAD_FAST_r11 1473 -#define _STORE_FAST_STORE_FAST_r20 1474 -#define _STORE_GLOBAL_r10 1475 -#define _STORE_NAME_r10 1476 -#define _STORE_SLICE_r30 1477 -#define _STORE_SUBSCR_r30 1478 -#define _STORE_SUBSCR_DICT_r31 1479 -#define _STORE_SUBSCR_DICT_KNOWN_HASH_r31 1480 -#define _STORE_SUBSCR_LIST_INT_r32 1481 -#define _SWAP_r11 1482 -#define _SWAP_2_r02 1483 -#define _SWAP_2_r12 1484 -#define _SWAP_2_r22 1485 -#define _SWAP_2_r33 1486 -#define _SWAP_3_r03 1487 -#define _SWAP_3_r13 1488 -#define _SWAP_3_r23 1489 -#define _SWAP_3_r33 1490 -#define _SWAP_FAST_r01 1491 -#define _SWAP_FAST_r11 1492 -#define _SWAP_FAST_r22 1493 -#define _SWAP_FAST_r33 1494 -#define _SWAP_FAST_0_r01 1495 -#define _SWAP_FAST_0_r11 1496 -#define _SWAP_FAST_0_r22 1497 -#define _SWAP_FAST_0_r33 1498 -#define _SWAP_FAST_1_r01 1499 -#define _SWAP_FAST_1_r11 1500 -#define _SWAP_FAST_1_r22 1501 -#define _SWAP_FAST_1_r33 1502 -#define _SWAP_FAST_2_r01 1503 -#define _SWAP_FAST_2_r11 1504 -#define _SWAP_FAST_2_r22 1505 -#define _SWAP_FAST_2_r33 1506 -#define _SWAP_FAST_3_r01 1507 -#define _SWAP_FAST_3_r11 1508 -#define _SWAP_FAST_3_r22 1509 -#define _SWAP_FAST_3_r33 1510 -#define _SWAP_FAST_4_r01 1511 -#define _SWAP_FAST_4_r11 1512 -#define _SWAP_FAST_4_r22 1513 -#define _SWAP_FAST_4_r33 1514 -#define _SWAP_FAST_5_r01 1515 -#define _SWAP_FAST_5_r11 1516 -#define _SWAP_FAST_5_r22 1517 -#define _SWAP_FAST_5_r33 1518 -#define _SWAP_FAST_6_r01 1519 -#define _SWAP_FAST_6_r11 1520 -#define _SWAP_FAST_6_r22 1521 -#define _SWAP_FAST_6_r33 1522 -#define _SWAP_FAST_7_r01 1523 -#define _SWAP_FAST_7_r11 1524 -#define _SWAP_FAST_7_r22 1525 -#define _SWAP_FAST_7_r33 1526 -#define _TIER2_RESUME_CHECK_r00 1527 -#define _TIER2_RESUME_CHECK_r11 1528 -#define _TIER2_RESUME_CHECK_r22 1529 -#define _TIER2_RESUME_CHECK_r33 1530 -#define _TO_BOOL_r11 1531 -#define _TO_BOOL_BOOL_r01 1532 -#define _TO_BOOL_BOOL_r11 1533 -#define _TO_BOOL_BOOL_r22 1534 -#define _TO_BOOL_BOOL_r33 1535 -#define _TO_BOOL_INT_r02 1536 -#define _TO_BOOL_INT_r12 1537 -#define _TO_BOOL_INT_r23 1538 -#define _TO_BOOL_LIST_r02 1539 -#define _TO_BOOL_LIST_r12 1540 -#define _TO_BOOL_LIST_r23 1541 -#define _TO_BOOL_NONE_r01 1542 -#define _TO_BOOL_NONE_r11 1543 -#define _TO_BOOL_NONE_r22 1544 -#define _TO_BOOL_NONE_r33 1545 -#define _TO_BOOL_STR_r02 1546 -#define _TO_BOOL_STR_r12 1547 -#define _TO_BOOL_STR_r23 1548 -#define _TRACE_RECORD_r00 1549 -#define _UNARY_INVERT_r12 1550 -#define _UNARY_NEGATIVE_r12 1551 -#define _UNARY_NEGATIVE_FLOAT_INPLACE_r02 1552 -#define _UNARY_NEGATIVE_FLOAT_INPLACE_r12 1553 -#define _UNARY_NEGATIVE_FLOAT_INPLACE_r23 1554 -#define _UNARY_NOT_r01 1555 -#define _UNARY_NOT_r11 1556 -#define _UNARY_NOT_r22 1557 -#define _UNARY_NOT_r33 1558 -#define _UNPACK_EX_r10 1559 -#define _UNPACK_SEQUENCE_r10 1560 -#define _UNPACK_SEQUENCE_LIST_r10 1561 -#define _UNPACK_SEQUENCE_TUPLE_r10 1562 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1563 -#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE_r03 1564 -#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE_r13 1565 -#define _UNPACK_SEQUENCE_UNIQUE_TUPLE_r10 1566 -#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r02 1567 -#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r12 1568 -#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r23 1569 -#define _WITH_EXCEPT_START_r33 1570 -#define _YIELD_VALUE_r11 1571 -#define MAX_UOP_REGS_ID 1571 +#define _LOAD_ATTR_PROPERTY_FRAME_r01 1238 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1239 +#define _LOAD_ATTR_PROPERTY_FRAME_r22 1240 +#define _LOAD_ATTR_PROPERTY_FRAME_r33 1241 +#define _LOAD_ATTR_SLOT_r02 1242 +#define _LOAD_ATTR_SLOT_r12 1243 +#define _LOAD_ATTR_SLOT_r23 1244 +#define _LOAD_ATTR_WITH_HINT_r12 1245 +#define _LOAD_BUILD_CLASS_r01 1246 +#define _LOAD_BYTECODE_r00 1247 +#define _LOAD_COMMON_CONSTANT_r01 1248 +#define _LOAD_COMMON_CONSTANT_r12 1249 +#define _LOAD_COMMON_CONSTANT_r23 1250 +#define _LOAD_CONST_r01 1251 +#define _LOAD_CONST_r12 1252 +#define _LOAD_CONST_r23 1253 +#define _LOAD_CONST_INLINE_r01 1254 +#define _LOAD_CONST_INLINE_r12 1255 +#define _LOAD_CONST_INLINE_r23 1256 +#define _LOAD_CONST_INLINE_BORROW_r01 1257 +#define _LOAD_CONST_INLINE_BORROW_r12 1258 +#define _LOAD_CONST_INLINE_BORROW_r23 1259 +#define _LOAD_DEREF_r01 1260 +#define _LOAD_FAST_r01 1261 +#define _LOAD_FAST_r12 1262 +#define _LOAD_FAST_r23 1263 +#define _LOAD_FAST_0_r01 1264 +#define _LOAD_FAST_0_r12 1265 +#define _LOAD_FAST_0_r23 1266 +#define _LOAD_FAST_1_r01 1267 +#define _LOAD_FAST_1_r12 1268 +#define _LOAD_FAST_1_r23 1269 +#define _LOAD_FAST_2_r01 1270 +#define _LOAD_FAST_2_r12 1271 +#define _LOAD_FAST_2_r23 1272 +#define _LOAD_FAST_3_r01 1273 +#define _LOAD_FAST_3_r12 1274 +#define _LOAD_FAST_3_r23 1275 +#define _LOAD_FAST_4_r01 1276 +#define _LOAD_FAST_4_r12 1277 +#define _LOAD_FAST_4_r23 1278 +#define _LOAD_FAST_5_r01 1279 +#define _LOAD_FAST_5_r12 1280 +#define _LOAD_FAST_5_r23 1281 +#define _LOAD_FAST_6_r01 1282 +#define _LOAD_FAST_6_r12 1283 +#define _LOAD_FAST_6_r23 1284 +#define _LOAD_FAST_7_r01 1285 +#define _LOAD_FAST_7_r12 1286 +#define _LOAD_FAST_7_r23 1287 +#define _LOAD_FAST_AND_CLEAR_r01 1288 +#define _LOAD_FAST_AND_CLEAR_r12 1289 +#define _LOAD_FAST_AND_CLEAR_r23 1290 +#define _LOAD_FAST_BORROW_r01 1291 +#define _LOAD_FAST_BORROW_r12 1292 +#define _LOAD_FAST_BORROW_r23 1293 +#define _LOAD_FAST_BORROW_0_r01 1294 +#define _LOAD_FAST_BORROW_0_r12 1295 +#define _LOAD_FAST_BORROW_0_r23 1296 +#define _LOAD_FAST_BORROW_1_r01 1297 +#define _LOAD_FAST_BORROW_1_r12 1298 +#define _LOAD_FAST_BORROW_1_r23 1299 +#define _LOAD_FAST_BORROW_2_r01 1300 +#define _LOAD_FAST_BORROW_2_r12 1301 +#define _LOAD_FAST_BORROW_2_r23 1302 +#define _LOAD_FAST_BORROW_3_r01 1303 +#define _LOAD_FAST_BORROW_3_r12 1304 +#define _LOAD_FAST_BORROW_3_r23 1305 +#define _LOAD_FAST_BORROW_4_r01 1306 +#define _LOAD_FAST_BORROW_4_r12 1307 +#define _LOAD_FAST_BORROW_4_r23 1308 +#define _LOAD_FAST_BORROW_5_r01 1309 +#define _LOAD_FAST_BORROW_5_r12 1310 +#define _LOAD_FAST_BORROW_5_r23 1311 +#define _LOAD_FAST_BORROW_6_r01 1312 +#define _LOAD_FAST_BORROW_6_r12 1313 +#define _LOAD_FAST_BORROW_6_r23 1314 +#define _LOAD_FAST_BORROW_7_r01 1315 +#define _LOAD_FAST_BORROW_7_r12 1316 +#define _LOAD_FAST_BORROW_7_r23 1317 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1318 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1319 +#define _LOAD_FAST_CHECK_r01 1320 +#define _LOAD_FAST_CHECK_r12 1321 +#define _LOAD_FAST_CHECK_r23 1322 +#define _LOAD_FAST_LOAD_FAST_r02 1323 +#define _LOAD_FAST_LOAD_FAST_r13 1324 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1325 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1326 +#define _LOAD_GLOBAL_r00 1327 +#define _LOAD_GLOBAL_BUILTINS_r01 1328 +#define _LOAD_GLOBAL_MODULE_r01 1329 +#define _LOAD_LOCALS_r01 1330 +#define _LOAD_LOCALS_r12 1331 +#define _LOAD_LOCALS_r23 1332 +#define _LOAD_NAME_r01 1333 +#define _LOAD_SMALL_INT_r01 1334 +#define _LOAD_SMALL_INT_r12 1335 +#define _LOAD_SMALL_INT_r23 1336 +#define _LOAD_SMALL_INT_0_r01 1337 +#define _LOAD_SMALL_INT_0_r12 1338 +#define _LOAD_SMALL_INT_0_r23 1339 +#define _LOAD_SMALL_INT_1_r01 1340 +#define _LOAD_SMALL_INT_1_r12 1341 +#define _LOAD_SMALL_INT_1_r23 1342 +#define _LOAD_SMALL_INT_2_r01 1343 +#define _LOAD_SMALL_INT_2_r12 1344 +#define _LOAD_SMALL_INT_2_r23 1345 +#define _LOAD_SMALL_INT_3_r01 1346 +#define _LOAD_SMALL_INT_3_r12 1347 +#define _LOAD_SMALL_INT_3_r23 1348 +#define _LOAD_SPECIAL_r00 1349 +#define _LOAD_SUPER_ATTR_ATTR_r31 1350 +#define _LOAD_SUPER_ATTR_METHOD_r32 1351 +#define _LOCK_OBJECT_r01 1352 +#define _LOCK_OBJECT_r11 1353 +#define _LOCK_OBJECT_r22 1354 +#define _LOCK_OBJECT_r33 1355 +#define _MAKE_CALLARGS_A_TUPLE_r33 1356 +#define _MAKE_CELL_r00 1357 +#define _MAKE_FUNCTION_r12 1358 +#define _MAKE_HEAP_SAFE_r01 1359 +#define _MAKE_HEAP_SAFE_r11 1360 +#define _MAKE_HEAP_SAFE_r22 1361 +#define _MAKE_HEAP_SAFE_r33 1362 +#define _MAKE_WARM_r00 1363 +#define _MAKE_WARM_r11 1364 +#define _MAKE_WARM_r22 1365 +#define _MAKE_WARM_r33 1366 +#define _MAP_ADD_r20 1367 +#define _MATCH_CLASS_r33 1368 +#define _MATCH_KEYS_r23 1369 +#define _MATCH_MAPPING_r02 1370 +#define _MATCH_MAPPING_r12 1371 +#define _MATCH_MAPPING_r23 1372 +#define _MATCH_SEQUENCE_r02 1373 +#define _MATCH_SEQUENCE_r12 1374 +#define _MATCH_SEQUENCE_r23 1375 +#define _MAYBE_EXPAND_METHOD_r00 1376 +#define _MAYBE_EXPAND_METHOD_KW_r11 1377 +#define _MONITOR_CALL_r00 1378 +#define _MONITOR_CALL_KW_r11 1379 +#define _MONITOR_JUMP_BACKWARD_r00 1380 +#define _MONITOR_JUMP_BACKWARD_r11 1381 +#define _MONITOR_JUMP_BACKWARD_r22 1382 +#define _MONITOR_JUMP_BACKWARD_r33 1383 +#define _MONITOR_RESUME_r00 1384 +#define _NOP_r00 1385 +#define _NOP_r11 1386 +#define _NOP_r22 1387 +#define _NOP_r33 1388 +#define _POP_EXCEPT_r10 1389 +#define _POP_ITER_r20 1390 +#define _POP_JUMP_IF_FALSE_r00 1391 +#define _POP_JUMP_IF_FALSE_r10 1392 +#define _POP_JUMP_IF_FALSE_r21 1393 +#define _POP_JUMP_IF_FALSE_r32 1394 +#define _POP_JUMP_IF_TRUE_r00 1395 +#define _POP_JUMP_IF_TRUE_r10 1396 +#define _POP_JUMP_IF_TRUE_r21 1397 +#define _POP_JUMP_IF_TRUE_r32 1398 +#define _POP_TOP_r10 1399 +#define _POP_TOP_FLOAT_r00 1400 +#define _POP_TOP_FLOAT_r10 1401 +#define _POP_TOP_FLOAT_r21 1402 +#define _POP_TOP_FLOAT_r32 1403 +#define _POP_TOP_INT_r00 1404 +#define _POP_TOP_INT_r10 1405 +#define _POP_TOP_INT_r21 1406 +#define _POP_TOP_INT_r32 1407 +#define _POP_TOP_NOP_r00 1408 +#define _POP_TOP_NOP_r10 1409 +#define _POP_TOP_NOP_r21 1410 +#define _POP_TOP_NOP_r32 1411 +#define _POP_TOP_OPARG_r00 1412 +#define _POP_TOP_UNICODE_r00 1413 +#define _POP_TOP_UNICODE_r10 1414 +#define _POP_TOP_UNICODE_r21 1415 +#define _POP_TOP_UNICODE_r32 1416 +#define _PUSH_EXC_INFO_r02 1417 +#define _PUSH_EXC_INFO_r12 1418 +#define _PUSH_EXC_INFO_r23 1419 +#define _PUSH_FRAME_r10 1420 +#define _PUSH_NULL_r01 1421 +#define _PUSH_NULL_r12 1422 +#define _PUSH_NULL_r23 1423 +#define _PUSH_NULL_CONDITIONAL_r00 1424 +#define _PY_FRAME_EX_r31 1425 +#define _PY_FRAME_GENERAL_r01 1426 +#define _PY_FRAME_KW_r11 1427 +#define _REPLACE_WITH_TRUE_r02 1428 +#define _REPLACE_WITH_TRUE_r12 1429 +#define _REPLACE_WITH_TRUE_r23 1430 +#define _RESUME_CHECK_r00 1431 +#define _RESUME_CHECK_r11 1432 +#define _RESUME_CHECK_r22 1433 +#define _RESUME_CHECK_r33 1434 +#define _RETURN_GENERATOR_r01 1435 +#define _RETURN_VALUE_r11 1436 +#define _SAVE_RETURN_OFFSET_r00 1437 +#define _SAVE_RETURN_OFFSET_r11 1438 +#define _SAVE_RETURN_OFFSET_r22 1439 +#define _SAVE_RETURN_OFFSET_r33 1440 +#define _SEND_r33 1441 +#define _SEND_GEN_FRAME_r33 1442 +#define _SETUP_ANNOTATIONS_r00 1443 +#define _SET_ADD_r10 1444 +#define _SET_FUNCTION_ATTRIBUTE_r01 1445 +#define _SET_FUNCTION_ATTRIBUTE_r11 1446 +#define _SET_FUNCTION_ATTRIBUTE_r21 1447 +#define _SET_FUNCTION_ATTRIBUTE_r32 1448 +#define _SET_IP_r00 1449 +#define _SET_IP_r11 1450 +#define _SET_IP_r22 1451 +#define _SET_IP_r33 1452 +#define _SET_UPDATE_r11 1453 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1454 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1455 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1456 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1457 +#define _SPILL_OR_RELOAD_r01 1458 +#define _SPILL_OR_RELOAD_r02 1459 +#define _SPILL_OR_RELOAD_r03 1460 +#define _SPILL_OR_RELOAD_r10 1461 +#define _SPILL_OR_RELOAD_r12 1462 +#define _SPILL_OR_RELOAD_r13 1463 +#define _SPILL_OR_RELOAD_r20 1464 +#define _SPILL_OR_RELOAD_r21 1465 +#define _SPILL_OR_RELOAD_r23 1466 +#define _SPILL_OR_RELOAD_r30 1467 +#define _SPILL_OR_RELOAD_r31 1468 +#define _SPILL_OR_RELOAD_r32 1469 +#define _START_EXECUTOR_r00 1470 +#define _STORE_ATTR_r20 1471 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1472 +#define _STORE_ATTR_SLOT_r21 1473 +#define _STORE_ATTR_WITH_HINT_r21 1474 +#define _STORE_DEREF_r10 1475 +#define _STORE_FAST_LOAD_FAST_r11 1476 +#define _STORE_FAST_STORE_FAST_r20 1477 +#define _STORE_GLOBAL_r10 1478 +#define _STORE_NAME_r10 1479 +#define _STORE_SLICE_r30 1480 +#define _STORE_SUBSCR_r30 1481 +#define _STORE_SUBSCR_DICT_r31 1482 +#define _STORE_SUBSCR_DICT_KNOWN_HASH_r31 1483 +#define _STORE_SUBSCR_LIST_INT_r32 1484 +#define _SWAP_r11 1485 +#define _SWAP_2_r02 1486 +#define _SWAP_2_r12 1487 +#define _SWAP_2_r22 1488 +#define _SWAP_2_r33 1489 +#define _SWAP_3_r03 1490 +#define _SWAP_3_r13 1491 +#define _SWAP_3_r23 1492 +#define _SWAP_3_r33 1493 +#define _SWAP_FAST_r01 1494 +#define _SWAP_FAST_r11 1495 +#define _SWAP_FAST_r22 1496 +#define _SWAP_FAST_r33 1497 +#define _SWAP_FAST_0_r01 1498 +#define _SWAP_FAST_0_r11 1499 +#define _SWAP_FAST_0_r22 1500 +#define _SWAP_FAST_0_r33 1501 +#define _SWAP_FAST_1_r01 1502 +#define _SWAP_FAST_1_r11 1503 +#define _SWAP_FAST_1_r22 1504 +#define _SWAP_FAST_1_r33 1505 +#define _SWAP_FAST_2_r01 1506 +#define _SWAP_FAST_2_r11 1507 +#define _SWAP_FAST_2_r22 1508 +#define _SWAP_FAST_2_r33 1509 +#define _SWAP_FAST_3_r01 1510 +#define _SWAP_FAST_3_r11 1511 +#define _SWAP_FAST_3_r22 1512 +#define _SWAP_FAST_3_r33 1513 +#define _SWAP_FAST_4_r01 1514 +#define _SWAP_FAST_4_r11 1515 +#define _SWAP_FAST_4_r22 1516 +#define _SWAP_FAST_4_r33 1517 +#define _SWAP_FAST_5_r01 1518 +#define _SWAP_FAST_5_r11 1519 +#define _SWAP_FAST_5_r22 1520 +#define _SWAP_FAST_5_r33 1521 +#define _SWAP_FAST_6_r01 1522 +#define _SWAP_FAST_6_r11 1523 +#define _SWAP_FAST_6_r22 1524 +#define _SWAP_FAST_6_r33 1525 +#define _SWAP_FAST_7_r01 1526 +#define _SWAP_FAST_7_r11 1527 +#define _SWAP_FAST_7_r22 1528 +#define _SWAP_FAST_7_r33 1529 +#define _TIER2_RESUME_CHECK_r00 1530 +#define _TIER2_RESUME_CHECK_r11 1531 +#define _TIER2_RESUME_CHECK_r22 1532 +#define _TIER2_RESUME_CHECK_r33 1533 +#define _TO_BOOL_r11 1534 +#define _TO_BOOL_BOOL_r01 1535 +#define _TO_BOOL_BOOL_r11 1536 +#define _TO_BOOL_BOOL_r22 1537 +#define _TO_BOOL_BOOL_r33 1538 +#define _TO_BOOL_INT_r02 1539 +#define _TO_BOOL_INT_r12 1540 +#define _TO_BOOL_INT_r23 1541 +#define _TO_BOOL_LIST_r02 1542 +#define _TO_BOOL_LIST_r12 1543 +#define _TO_BOOL_LIST_r23 1544 +#define _TO_BOOL_NONE_r01 1545 +#define _TO_BOOL_NONE_r11 1546 +#define _TO_BOOL_NONE_r22 1547 +#define _TO_BOOL_NONE_r33 1548 +#define _TO_BOOL_STR_r02 1549 +#define _TO_BOOL_STR_r12 1550 +#define _TO_BOOL_STR_r23 1551 +#define _TRACE_RECORD_r00 1552 +#define _UNARY_INVERT_r12 1553 +#define _UNARY_NEGATIVE_r12 1554 +#define _UNARY_NEGATIVE_FLOAT_INPLACE_r02 1555 +#define _UNARY_NEGATIVE_FLOAT_INPLACE_r12 1556 +#define _UNARY_NEGATIVE_FLOAT_INPLACE_r23 1557 +#define _UNARY_NOT_r01 1558 +#define _UNARY_NOT_r11 1559 +#define _UNARY_NOT_r22 1560 +#define _UNARY_NOT_r33 1561 +#define _UNPACK_EX_r10 1562 +#define _UNPACK_SEQUENCE_r10 1563 +#define _UNPACK_SEQUENCE_LIST_r10 1564 +#define _UNPACK_SEQUENCE_TUPLE_r10 1565 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1566 +#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE_r03 1567 +#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE_r13 1568 +#define _UNPACK_SEQUENCE_UNIQUE_TUPLE_r10 1569 +#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r02 1570 +#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r12 1571 +#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r23 1572 +#define _WITH_EXCEPT_START_r33 1573 +#define _YIELD_VALUE_r11 1574 +#define MAX_UOP_REGS_ID 1574 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 6e0e42d2542b8a..bb3e3b9950c577 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -2112,12 +2112,12 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { }, }, [_LOAD_ATTR_PROPERTY_FRAME] = { - .best = { 1, 1, 1, 1 }, + .best = { 0, 1, 2, 3 }, .entries = { - { -1, -1, -1 }, + { 1, 0, _LOAD_ATTR_PROPERTY_FRAME_r01 }, { 1, 1, _LOAD_ATTR_PROPERTY_FRAME_r11 }, - { -1, -1, -1 }, - { -1, -1, -1 }, + { 2, 2, _LOAD_ATTR_PROPERTY_FRAME_r22 }, + { 3, 3, _LOAD_ATTR_PROPERTY_FRAME_r33 }, }, }, [_GUARD_DORV_NO_DICT] = { @@ -4180,7 +4180,10 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_CHECK_ATTR_CLASS_r22] = _CHECK_ATTR_CLASS, [_CHECK_ATTR_CLASS_r33] = _CHECK_ATTR_CLASS, [_LOAD_ATTR_CLASS_r11] = _LOAD_ATTR_CLASS, + [_LOAD_ATTR_PROPERTY_FRAME_r01] = _LOAD_ATTR_PROPERTY_FRAME, [_LOAD_ATTR_PROPERTY_FRAME_r11] = _LOAD_ATTR_PROPERTY_FRAME, + [_LOAD_ATTR_PROPERTY_FRAME_r22] = _LOAD_ATTR_PROPERTY_FRAME, + [_LOAD_ATTR_PROPERTY_FRAME_r33] = _LOAD_ATTR_PROPERTY_FRAME, [_GUARD_DORV_NO_DICT_r01] = _GUARD_DORV_NO_DICT, [_GUARD_DORV_NO_DICT_r11] = _GUARD_DORV_NO_DICT, [_GUARD_DORV_NO_DICT_r22] = _GUARD_DORV_NO_DICT, @@ -5425,7 +5428,10 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES", [_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11] = "_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11", [_LOAD_ATTR_PROPERTY_FRAME] = "_LOAD_ATTR_PROPERTY_FRAME", + [_LOAD_ATTR_PROPERTY_FRAME_r01] = "_LOAD_ATTR_PROPERTY_FRAME_r01", [_LOAD_ATTR_PROPERTY_FRAME_r11] = "_LOAD_ATTR_PROPERTY_FRAME_r11", + [_LOAD_ATTR_PROPERTY_FRAME_r22] = "_LOAD_ATTR_PROPERTY_FRAME_r22", + [_LOAD_ATTR_PROPERTY_FRAME_r33] = "_LOAD_ATTR_PROPERTY_FRAME_r33", [_LOAD_ATTR_SLOT] = "_LOAD_ATTR_SLOT", [_LOAD_ATTR_SLOT_r02] = "_LOAD_ATTR_SLOT_r02", [_LOAD_ATTR_SLOT_r12] = "_LOAD_ATTR_SLOT_r12", diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 0b112afb8181b1..f9cd37c4e1c86b 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -4896,6 +4896,38 @@ def testfunc(*args): # This is a sign the optimizer ran and didn't hit contradiction. self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) + def test_load_attr_property_frame_invalidates_on_code_change(self): + class C: + @property + def val(self): + return int(1) + + fget = C.val.fget + + def testfunc(*args): + n, c = args[0] + total = 0 + for _ in range(n): + total += c.val + return total + + testfunc((3, C())) + res, ex = self._run_with_optimizer(testfunc, (TIER2_THRESHOLD, C())) + self.assertEqual(res, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + self.assertIn("_LOAD_ATTR_PROPERTY_FRAME", uops) + # Check the optimizer traced through the property call. + self.assertNotIn("_LOAD_GLOBAL_BUILTINS", uops) + self.assertIn("_CALL_BUILTIN_CLASS", uops) + + fget.__code__ = (lambda self: 2).__code__ + _testinternalcapi.clear_executor_deletion_list() + ex = get_first_executor(testfunc) + self.assertIsNone(ex) + res = testfunc((TIER2_THRESHOLD, C())) + self.assertEqual(res, TIER2_THRESHOLD * 2) + def test_unary_negative(self): def testfunc(n): a = 3 diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index 8bf751026bd35c..afbc88381d65b4 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -8840,29 +8840,19 @@ JUMP_TO_PREDICTED(LOAD_ATTR); } } - /* Skip 2 cache entries */ // _LOAD_ATTR_PROPERTY_FRAME { + uint32_t func_version = read_u32(&this_instr[4].cache); PyObject *fget = read_obj(&this_instr[6].cache); assert((oparg & 1) == 0); assert(Py_IS_TYPE(fget, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)fget; - PyCodeObject *code = (PyCodeObject *)f->func_code; - if ((code->co_flags & (CO_VARKEYWORDS | CO_VARARGS | CO_OPTIMIZED)) != CO_OPTIMIZED) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - if (code->co_kwonlyargcount) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - if (code->co_argcount != 1) { + if (f->func_version != func_version) { UPDATE_MISS_STATS(LOAD_ATTR); assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); JUMP_TO_PREDICTED(LOAD_ATTR); } + PyCodeObject *code = (PyCodeObject *)f->func_code; if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { UPDATE_MISS_STATS(LOAD_ATTR); assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 57731fc65ed35c..1ae6610774e274 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2919,14 +2919,12 @@ dummy_func( _LOAD_ATTR_CLASS + _PUSH_NULL_CONDITIONAL; - op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame)) { + op(_LOAD_ATTR_PROPERTY_FRAME, (func_version/2, fget/4, owner -- new_frame)) { assert((oparg & 1) == 0); assert(Py_IS_TYPE(fget, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)fget; + EXIT_IF(f->func_version != func_version); PyCodeObject *code = (PyCodeObject *)f->func_code; - EXIT_IF((code->co_flags & (CO_VARKEYWORDS | CO_VARARGS | CO_OPTIMIZED)) != CO_OPTIMIZED); - EXIT_IF(code->co_kwonlyargcount); - EXIT_IF(code->co_argcount != 1); EXIT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); STAT_INC(LOAD_ATTR, hit); _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); @@ -2940,7 +2938,6 @@ dummy_func( _RECORD_TOS_TYPE + _GUARD_TYPE_VERSION + _CHECK_PEP_523 + - unused/2 + _LOAD_ATTR_PROPERTY_FRAME + _SAVE_RETURN_OFFSET + _PUSH_FRAME; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index d54afe34f202b2..3614839499b7ab 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -11450,6 +11450,41 @@ break; } + case _LOAD_ATTR_PROPERTY_FRAME_r01: { + CHECK_CURRENT_CACHED_VALUES(0); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef owner; + _PyStackRef new_frame; + oparg = CURRENT_OPARG(); + owner = stack_pointer[-1]; + uint32_t func_version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *fget = (PyObject *)CURRENT_OPERAND1_64(); + assert((oparg & 1) == 0); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)fget; + if (f->func_version != func_version) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + PyCodeObject *code = (PyCodeObject *)f->func_code; + if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { + UOP_STAT_INC(uopcode, miss); + SET_CURRENT_CACHED_VALUES(0); + JUMP_TO_JUMP_TARGET(); + } + STAT_INC(LOAD_ATTR, hit); + _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); + pushed_frame->localsplus[0] = owner; + new_frame = PyStackRef_Wrap(pushed_frame); + _tos_cache0 = new_frame; + SET_CURRENT_CACHED_VALUES(1); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + case _LOAD_ATTR_PROPERTY_FRAME_r11: { CHECK_CURRENT_CACHED_VALUES(1); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); @@ -11458,43 +11493,114 @@ _PyStackRef _stack_item_0 = _tos_cache0; oparg = CURRENT_OPARG(); owner = _stack_item_0; - PyObject *fget = (PyObject *)CURRENT_OPERAND0_64(); + uint32_t func_version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *fget = (PyObject *)CURRENT_OPERAND1_64(); assert((oparg & 1) == 0); assert(Py_IS_TYPE(fget, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)fget; - PyCodeObject *code = (PyCodeObject *)f->func_code; - if ((code->co_flags & (CO_VARKEYWORDS | CO_VARARGS | CO_OPTIMIZED)) != CO_OPTIMIZED) { + if (f->func_version != func_version) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = owner; SET_CURRENT_CACHED_VALUES(1); JUMP_TO_JUMP_TARGET(); } - if (code->co_kwonlyargcount) { + PyCodeObject *code = (PyCodeObject *)f->func_code; + if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { UOP_STAT_INC(uopcode, miss); _tos_cache0 = owner; SET_CURRENT_CACHED_VALUES(1); JUMP_TO_JUMP_TARGET(); } - if (code->co_argcount != 1) { + STAT_INC(LOAD_ATTR, hit); + _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); + pushed_frame->localsplus[0] = owner; + new_frame = PyStackRef_Wrap(pushed_frame); + _tos_cache0 = new_frame; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _LOAD_ATTR_PROPERTY_FRAME_r22: { + CHECK_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef owner; + _PyStackRef new_frame; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + oparg = CURRENT_OPARG(); + owner = _stack_item_1; + uint32_t func_version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *fget = (PyObject *)CURRENT_OPERAND1_64(); + assert((oparg & 1) == 0); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)fget; + if (f->func_version != func_version) { UOP_STAT_INC(uopcode, miss); - _tos_cache0 = owner; - SET_CURRENT_CACHED_VALUES(1); + _tos_cache1 = owner; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); JUMP_TO_JUMP_TARGET(); } + PyCodeObject *code = (PyCodeObject *)f->func_code; if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { UOP_STAT_INC(uopcode, miss); - _tos_cache0 = owner; - SET_CURRENT_CACHED_VALUES(1); + _tos_cache1 = owner; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); JUMP_TO_JUMP_TARGET(); } STAT_INC(LOAD_ATTR, hit); _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); pushed_frame->localsplus[0] = owner; new_frame = PyStackRef_Wrap(pushed_frame); - _tos_cache0 = new_frame; - _tos_cache1 = PyStackRef_ZERO_BITS; - _tos_cache2 = PyStackRef_ZERO_BITS; - SET_CURRENT_CACHED_VALUES(1); + _tos_cache1 = new_frame; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(2); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } + + case _LOAD_ATTR_PROPERTY_FRAME_r33: { + CHECK_CURRENT_CACHED_VALUES(3); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef owner; + _PyStackRef new_frame; + _PyStackRef _stack_item_0 = _tos_cache0; + _PyStackRef _stack_item_1 = _tos_cache1; + _PyStackRef _stack_item_2 = _tos_cache2; + oparg = CURRENT_OPARG(); + owner = _stack_item_2; + uint32_t func_version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *fget = (PyObject *)CURRENT_OPERAND1_64(); + assert((oparg & 1) == 0); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)fget; + if (f->func_version != func_version) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = owner; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + PyCodeObject *code = (PyCodeObject *)f->func_code; + if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache2 = owner; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); + JUMP_TO_JUMP_TARGET(); + } + STAT_INC(LOAD_ATTR, hit); + _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked(tstate, PyStackRef_FromPyObjectNew(fget), 1, frame); + pushed_frame->localsplus[0] = owner; + new_frame = PyStackRef_Wrap(pushed_frame); + _tos_cache2 = new_frame; + _tos_cache1 = _stack_item_1; + _tos_cache0 = _stack_item_0; + SET_CURRENT_CACHED_VALUES(3); assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); break; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index d710e82a306ab4..cd5131c0f1b68c 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -8839,29 +8839,19 @@ JUMP_TO_PREDICTED(LOAD_ATTR); } } - /* Skip 2 cache entries */ // _LOAD_ATTR_PROPERTY_FRAME { + uint32_t func_version = read_u32(&this_instr[4].cache); PyObject *fget = read_obj(&this_instr[6].cache); assert((oparg & 1) == 0); assert(Py_IS_TYPE(fget, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)fget; - PyCodeObject *code = (PyCodeObject *)f->func_code; - if ((code->co_flags & (CO_VARKEYWORDS | CO_VARARGS | CO_OPTIMIZED)) != CO_OPTIMIZED) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - if (code->co_kwonlyargcount) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - if (code->co_argcount != 1) { + if (f->func_version != func_version) { UPDATE_MISS_STATS(LOAD_ATTR); assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); JUMP_TO_PREDICTED(LOAD_ATTR); } + PyCodeObject *code = (PyCodeObject *)f->func_code; if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { UPDATE_MISS_STATS(LOAD_ATTR); assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 6b48f89510ef28..095bcfc639bc65 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -257,6 +257,7 @@ add_op(JitOptContext *ctx, _PyUOpInstruction *this_instr, #define sym_get_probable_type _Py_uop_sym_get_probable_type #define sym_matches_type _Py_uop_sym_matches_type #define sym_matches_type_version _Py_uop_sym_matches_type_version +#define sym_get_type_version _Py_uop_sym_get_type_version #define sym_set_null(SYM) _Py_uop_sym_set_null(ctx, SYM) #define sym_set_non_null(SYM) _Py_uop_sym_set_non_null(ctx, SYM) #define sym_set_type(SYM, TYPE) _Py_uop_sym_set_type(ctx, SYM, TYPE) diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 3332a9627c1523..d50e32e590bdb9 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -20,6 +20,7 @@ typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame; #define sym_new_null _Py_uop_sym_new_null #define sym_matches_type _Py_uop_sym_matches_type #define sym_matches_type_version _Py_uop_sym_matches_type_version +#define sym_get_type_version _Py_uop_sym_get_type_version #define sym_get_type _Py_uop_sym_get_type #define sym_has_type _Py_uop_sym_has_type #define sym_set_null(SYM) _Py_uop_sym_set_null(ctx, SYM) @@ -138,15 +139,24 @@ dummy_func(void) { assert(type_version); if (sym_matches_type_version(owner, type_version)) { ADD_OP(_NOP, 0, 0); - } else { + } + else { PyTypeObject *probable_type = sym_get_probable_type(owner); - if (probable_type->tp_version_tag == type_version && sym_set_type_version(owner, type_version)) { + if (probable_type != NULL && + probable_type->tp_version_tag == type_version) { // Promote the probable type version to a known one. + sym_set_type(owner, probable_type); + sym_set_type_version(owner, type_version); if ((probable_type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) { PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type); _Py_BloomFilter_Add(dependencies, probable_type); } } + else { + ctx->contradiction = true; + ctx->done = true; + break; + } } } @@ -239,20 +249,20 @@ dummy_func(void) { assert(this_instr[-1].opcode == _RECORD_TOS_TYPE); if (sym_matches_type_version(owner, type_version)) { ADD_OP(_NOP, 0, 0); - } else { - // add watcher so that whenever the type changes we invalidate this - PyTypeObject *type = _PyType_LookupByVersion(type_version); - // if the type is null, it was not found in the cache (there was a conflict) - // with the key, in which case we can't trust the version - if (type) { - // if the type version was set properly, then add a watcher - // if it wasn't this means that the type version was previously set to something else - // and we set the owner to bottom, so we don't need to add a watcher because we must have - // already added one earlier. - if (sym_set_type_version(owner, type_version)) { - PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type); - _Py_BloomFilter_Add(dependencies, type); - } + } + else { + PyTypeObject *probable_type = sym_get_probable_type(owner); + if (probable_type != NULL && + probable_type->tp_version_tag == type_version) { + sym_set_type(owner, probable_type); + sym_set_type_version(owner, type_version); + PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type); + _Py_BloomFilter_Add(dependencies, probable_type); + } + else { + ctx->contradiction = true; + ctx->done = true; + break; } } } @@ -983,15 +993,22 @@ dummy_func(void) { _LOAD_CONST_INLINE, _SWAP); } - op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame)) { - // + 1 for _SAVE_RETURN_OFFSET - // FIX ME -- This needs a version check and function watcher - PyCodeObject *co = (PyCodeObject *)((PyFunctionObject *)fget)->func_code; + op(_LOAD_ATTR_PROPERTY_FRAME, (func_version/2, fget/4, owner -- new_frame)) { + PyFunctionObject *func = (PyFunctionObject *)fget; + if (sym_get_type_version(owner) == 0 || + func->func_version != func_version) { + ctx->contradiction = true; + ctx->done = true; + break; + } + _Py_BloomFilter_Add(dependencies, fget); + PyCodeObject *co = (PyCodeObject *)func->func_code; _Py_UOpsAbstractFrame *f = frame_new(ctx, co, NULL, 0); if (f == NULL) { break; } f->locals[0] = owner; + f->func = func; new_frame = PyJitRef_WrapInvalid(f); } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 2547c959ed50ae..fcea042a585e80 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2429,13 +2429,20 @@ assert(this_instr[-1].opcode == _RECORD_TOS_TYPE); if (sym_matches_type_version(owner, type_version)) { ADD_OP(_NOP, 0, 0); - } else { - PyTypeObject *type = _PyType_LookupByVersion(type_version); - if (type) { - if (sym_set_type_version(owner, type_version)) { - PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type); - _Py_BloomFilter_Add(dependencies, type); - } + } + else { + PyTypeObject *probable_type = sym_get_probable_type(owner); + if (probable_type != NULL && + probable_type->tp_version_tag == type_version) { + sym_set_type(owner, probable_type); + sym_set_type_version(owner, type_version); + PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type); + _Py_BloomFilter_Add(dependencies, probable_type); + } + else { + ctx->contradiction = true; + ctx->done = true; + break; } } break; @@ -2448,14 +2455,23 @@ assert(type_version); if (sym_matches_type_version(owner, type_version)) { ADD_OP(_NOP, 0, 0); - } else { + } + else { PyTypeObject *probable_type = sym_get_probable_type(owner); - if (probable_type->tp_version_tag == type_version && sym_set_type_version(owner, type_version)) { + if (probable_type != NULL && + probable_type->tp_version_tag == type_version) { + sym_set_type(owner, probable_type); + sym_set_type_version(owner, type_version); if ((probable_type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) { PyType_Watch(TYPE_WATCHER_ID, (PyObject *)probable_type); _Py_BloomFilter_Add(dependencies, probable_type); } } + else { + ctx->contradiction = true; + ctx->done = true; + break; + } } break; } @@ -2598,13 +2614,23 @@ JitOptRef owner; JitOptRef new_frame; owner = stack_pointer[-1]; - PyObject *fget = (PyObject *)this_instr->operand0; - PyCodeObject *co = (PyCodeObject *)((PyFunctionObject *)fget)->func_code; + uint32_t func_version = (uint32_t)this_instr->operand0; + PyObject *fget = (PyObject *)this_instr->operand1; + PyFunctionObject *func = (PyFunctionObject *)fget; + if (sym_get_type_version(owner) == 0 || + func->func_version != func_version) { + ctx->contradiction = true; + ctx->done = true; + break; + } + _Py_BloomFilter_Add(dependencies, fget); + PyCodeObject *co = (PyCodeObject *)func->func_code; _Py_UOpsAbstractFrame *f = frame_new(ctx, co, NULL, 0); if (f == NULL) { break; } f->locals[0] = owner; + f->func = func; new_frame = PyJitRef_WrapInvalid(f); stack_pointer[-1] = new_frame; break; diff --git a/Python/specialize.c b/Python/specialize.c index bfa7b8148e46de..e42e1a8faa8a23 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -846,8 +846,13 @@ do_specialize_instance_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* return -1; } #endif + uint32_t func_version = function_get_version(fget, LOAD_ATTR); + if (func_version == 0) { + return -1; + } assert(tp_version != 0); write_u32(lm_cache->type_version, tp_version); + write_u32(lm_cache->keys_version, func_version); /* borrowed */ write_ptr(lm_cache->descr, fget); specialize(instr, LOAD_ATTR_PROPERTY); From e0b56f006c7ee1e5e6f353f030d0e5a672bfc190 Mon Sep 17 00:00:00 2001 From: Wulian233 <1055917385@qq.com> Date: Tue, 14 Apr 2026 23:04:28 +0800 Subject: [PATCH 05/12] gh-131798: Constant-fold `_CONTAINS_OP_DICT` for frozendict (GH-148548) --- Lib/test/test_capi/test_opt.py | 34 +++++++++++++++++++++++- Python/optimizer_bytecodes.c | 4 +++ Python/optimizer_cases.c.h | 47 ++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index f9cd37c4e1c86b..32da5e6159d532 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -4646,7 +4646,7 @@ def testfunc(n): self.assertEqual(res, TIER2_THRESHOLD) self.assertIsNotNone(ex) uops = get_opnames(ex) - self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) + self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 2) self.assertNotIn("_BINARY_OP_SUBSCR_DICT", uops) def test_binary_subscr_frozendict_const_fold(self): @@ -4661,6 +4661,7 @@ def testfunc(n): self.assertEqual(res, TIER2_THRESHOLD) self.assertIsNotNone(ex) uops = get_opnames(ex) + self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 3) # lookup result is folded to constant 1, so comparison is optimized away self.assertNotIn("_COMPARE_OP_INT", uops) @@ -4676,8 +4677,39 @@ def testfunc(n): self.assertEqual(res, TIER2_THRESHOLD) self.assertIsNotNone(ex) uops = get_opnames(ex) + self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 3) self.assertNotIn("_CONTAINS_OP_SET", uops) + def test_contains_op_frozendict_const_fold(self): + def testfunc(n): + x = 0 + for _ in range(n): + if 'x' in FROZEN_DICT_CONST: + x += 1 + return x + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 3) + self.assertNotIn("_CONTAINS_OP_DICT", uops) + + def test_not_contains_op_frozendict_const_fold(self): + def testfunc(n): + x = 0 + for _ in range(n): + if 'z' not in FROZEN_DICT_CONST: + x += 1 + return x + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertEqual(res, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + uops = get_opnames(ex) + self.assertGreaterEqual(count_ops(ex, "_LOAD_CONST_INLINE_BORROW"), 3) + self.assertNotIn("_CONTAINS_OP_DICT", uops) + def test_binary_subscr_list_slice(self): def testfunc(n): x = 0 diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index d50e32e590bdb9..b10c1276f715e1 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -771,6 +771,10 @@ dummy_func(void) { b = sym_new_type(ctx, &PyBool_Type); l = left; r = right; + if (sym_is_not_container(left) && + sym_matches_type(right, &PyFrozenDict_Type)) { + REPLACE_OPCODE_IF_EVALUATES_PURE(left, right, b); + } } op(_LOAD_CONST, (-- value)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index fcea042a585e80..fa0694d876159e 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -3174,6 +3174,53 @@ b = sym_new_type(ctx, &PyBool_Type); l = left; r = right; + if (sym_is_not_container(left) && + sym_matches_type(right, &PyFrozenDict_Type)) { + if ( + sym_is_safe_const(ctx, left) && + sym_is_safe_const(ctx, right) + ) { + JitOptRef left_sym = left; + JitOptRef right_sym = right; + _PyStackRef left = sym_get_const_as_stackref(ctx, left_sym); + _PyStackRef right = sym_get_const_as_stackref(ctx, right_sym); + _PyStackRef b_stackref; + _PyStackRef l_stackref; + _PyStackRef r_stackref; + /* Start of uop copied from bytecodes for constant evaluation */ + PyObject *left_o = PyStackRef_AsPyObjectBorrow(left); + PyObject *right_o = PyStackRef_AsPyObjectBorrow(right); + assert(PyAnyDict_CheckExact(right_o)); + STAT_INC(CONTAINS_OP, hit); + int res = PyDict_Contains(right_o, left_o); + if (res < 0) { + JUMP_TO_LABEL(error); + } + b_stackref = (res ^ oparg) ? PyStackRef_True : PyStackRef_False; + l_stackref = left; + r_stackref = right; + /* End of uop copied from bytecodes for constant evaluation */ + (void)l_stackref; + (void)r_stackref; + b = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(b_stackref)); + if (sym_is_const(ctx, b)) { + PyObject *result = sym_get_const(ctx, b); + if (_Py_IsImmortal(result)) { + // Replace with _LOAD_CONST_INLINE_BORROW + _SWAP + _SWAP since we have two inputs and an immortal result + ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result); + ADD_OP(_SWAP, 3, 0); + ADD_OP(_SWAP, 2, 0); + } + } + CHECK_STACK_BOUNDS(1); + stack_pointer[-2] = b; + stack_pointer[-1] = l; + stack_pointer[0] = r; + stack_pointer += 1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + break; + } + } CHECK_STACK_BOUNDS(1); stack_pointer[-2] = b; stack_pointer[-1] = l; From c88c27b0c1c09c125fe6a5ad78a4d42cf9c3fcd2 Mon Sep 17 00:00:00 2001 From: Geoffrey Thomas Date: Tue, 14 Apr 2026 11:26:19 -0400 Subject: [PATCH 06/12] gh-133312: configure: add --enable-static-libpython-for-interpreter (#133313) This option changes the behavior of --enable-shared to continue to build the libpython3.x.so shared library, but not use it for linking the python3 interpreter executable. Instead, the executable is linked directly against the libpython .o files as it would be with --disable-shared. There are two benefits of this change. First, libpython uses thread-local storage, which is noticeably slower when used in a loaded module instead of in the main program, because the main program can take advantage of constant offsets from the thread state pointer but loaded modules have to dynamically call a function __tls_get_addr() to potentially allocate their thread-local storage area. (There is another thread-local storage model for dynamic libraries which mitigates most of this performance hit, but it comes at the cost of preventing dlopen("libpython3.x.so"), which is a use case we want to preserve.) Second, this improves the user experience around relocatable Python a little bit, in that we don't need to use an $ORIGIN-relative path to locate libpython3.x.so, which has some mild benefits around musl (which does not support $ORIGIN-relative DT_NEEDED, only $ORIGIN-relative DT_RPATH/DT_RUNPATH), users who want to make the interpreter setuid or setcap (which prevents processing $ORIGIN), etc. --- Doc/using/configure.rst | 15 ++++++++ ...-05-02-17-06-10.gh-issue-133312.YkO6BI.rst | 8 +++++ configure | 34 +++++++++++++++++-- configure.ac | 24 +++++++++++-- 4 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2025-05-02-17-06-10.gh-issue-133312.YkO6BI.rst diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index bf25de7cc90c6c..d5c17560b6658a 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -1012,6 +1012,21 @@ Linker options .. versionadded:: 3.10 +.. option:: --enable-static-libpython-for-interpreter + + Do not link the Python interpreter binary (``python3``) against the + shared Python library; instead, statically link the interpreter + against ``libpython`` as if ``--enable-shared`` had not been used, + but continue to build the shared ``libpython`` (for use by other + programs). + + This option does nothing if ``--enable-shared`` is not used. + + The default (when ``-enable-shared`` is used) is to link the Python + interpreter against the built shared library. + + .. versionadded:: next + Libraries options ----------------- diff --git a/Misc/NEWS.d/next/Build/2025-05-02-17-06-10.gh-issue-133312.YkO6BI.rst b/Misc/NEWS.d/next/Build/2025-05-02-17-06-10.gh-issue-133312.YkO6BI.rst new file mode 100644 index 00000000000000..3ad2db63907ecb --- /dev/null +++ b/Misc/NEWS.d/next/Build/2025-05-02-17-06-10.gh-issue-133312.YkO6BI.rst @@ -0,0 +1,8 @@ +Add a new ``./configure`` option +:option:`--enable-static-libpython-for-interpreter` which, when used +with :option:`--enable-shared`, continues to build the shared library +but does not use it for the interpreter. Instead, libpython is +statically linked into the interpreter, as if :option:`--enable-shared` +had not been used. This allows you to do a single build and get a Python +interpreter binary that does not use a shared library but also get a +shared library for use by other programs. diff --git a/configure b/configure index 07c16a4e37874e..8620eb3fbdd36b 100755 --- a/configure +++ b/configure @@ -1100,6 +1100,7 @@ enable_wasm_pthreads with_suffix enable_shared with_static_libpython +enable_static_libpython_for_interpreter enable_profiling enable_gil with_pydebug @@ -1837,6 +1838,10 @@ Optional Features: no) --enable-shared enable building a shared Python library (default is no) + --enable-static-libpython-for-interpreter + even with --enable-shared, statically link libpython + into the interpreter (default is to use the shared + library) --enable-profiling enable C-level code profiling with gprof (default is no) --disable-gil enable support for running without the GIL (default @@ -7688,6 +7693,22 @@ fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-static-libpython-for-interpreter" >&5 +printf %s "checking for --enable-static-libpython-for-interpreter... " >&6; } +# Check whether --enable-static-libpython-for-interpreter was given. +if test ${enable_static_libpython_for_interpreter+y} +then : + enableval=$enable_static_libpython_for_interpreter; +fi + + +if test -z "$enable_static_libpython_for_interpreter" +then + enable_static_libpython_for_interpreter="no" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static_libpython_for_interpreter" >&5 +printf "%s\n" "$enable_static_libpython_for_interpreter" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-profiling" >&5 printf %s "checking for --enable-profiling... " >&6; } # Check whether --enable-profiling was given. @@ -7977,7 +7998,11 @@ if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" fi # Link Python program to the shared library - LINK_PYTHON_OBJS='$(BLDLIBRARY)' + if test "$enable_static_libpython_for_interpreter" = "yes"; then + LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' + else + LINK_PYTHON_OBJS='$(BLDLIBRARY)' + fi else if test "$STATIC_LIBPYTHON" = 0; then # Build Python needs object files but don't need to build @@ -9473,7 +9498,12 @@ BOLT_BINARIES='$(BUILDPYTHON)' if test "x$enable_shared" = xyes then : - BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" + if test "x$enable_static_libpython_for_interpreter" = xno +then : + + BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" + +fi fi diff --git a/configure.ac b/configure.ac index d6e152d42b765e..d73b37327fe584 100644 --- a/configure.ac +++ b/configure.ac @@ -1526,6 +1526,17 @@ fi], [AC_MSG_RESULT([yes])]) AC_SUBST([STATIC_LIBPYTHON]) +AC_MSG_CHECKING([for --enable-static-libpython-for-interpreter]) +AC_ARG_ENABLE([static-libpython-for-interpreter], + AS_HELP_STRING([--enable-static-libpython-for-interpreter], + [even with --enable-shared, statically link libpython into the interpreter (default is to use the shared library)])) + +if test -z "$enable_static_libpython_for_interpreter" +then + enable_static_libpython_for_interpreter="no" +fi +AC_MSG_RESULT([$enable_static_libpython_for_interpreter]) + AC_MSG_CHECKING([for --enable-profiling]) AC_ARG_ENABLE([profiling], AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)])) @@ -1679,7 +1690,11 @@ if test "$PY_ENABLE_SHARED" = 1 || test "$enable_framework" ; then LIBRARY_DEPS="\$(LIBRARY) $LIBRARY_DEPS" fi # Link Python program to the shared library - LINK_PYTHON_OBJS='$(BLDLIBRARY)' + if test "$enable_static_libpython_for_interpreter" = "yes"; then + LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' + else + LINK_PYTHON_OBJS='$(BLDLIBRARY)' + fi else if test "$STATIC_LIBPYTHON" = 0; then # Build Python needs object files but don't need to build @@ -2161,11 +2176,14 @@ if test "$Py_BOLT" = 'true' ; then fi fi -dnl Enable BOLT of libpython if built. +dnl Enable BOLT of libpython if built and used by the python3 binary. +dnl (If it is built but not used, we cannot profile it.) AC_SUBST([BOLT_BINARIES]) BOLT_BINARIES='$(BUILDPYTHON)' AS_VAR_IF([enable_shared], [yes], [ - BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" + AS_VAR_IF([enable_static_libpython_for_interpreter], [no], [ + BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" + ]) ]) AC_ARG_VAR( From 1aa7e7ee6d2f823e41d5bf21f5bb862a4f937e50 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Tue, 14 Apr 2026 21:00:32 +0530 Subject: [PATCH 07/12] gh-gh-131798: optimize `LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN` in the JIT (#148555) --- Include/internal/pycore_opcode_metadata.h | 5 +- Include/internal/pycore_uop_ids.h | 2138 ++++++++++----------- Include/internal/pycore_uop_metadata.h | 15 + Lib/test/test_capi/test_opt.py | 19 + Modules/_testinternalcapi/test_cases.c.h | 117 +- Python/bytecodes.c | 33 +- Python/executor_cases.c.h | 43 +- Python/generated_cases.c.h | 117 +- Python/optimizer_bytecodes.c | 21 + Python/optimizer_cases.c.h | 28 +- Python/record_functions.c.h | 1 + 11 files changed, 1361 insertions(+), 1176 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index ce07b71192bf3b..be7105cef5310f 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -800,7 +800,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { case LOAD_ATTR_CLASS_WITH_METACLASS_CHECK: return 1 + (oparg & 1); case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: - return 1; + return 0; case LOAD_ATTR_INSTANCE_VALUE: return 1 + (oparg & 1); case LOAD_ATTR_METHOD_LAZY_DICT: @@ -1223,7 +1223,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [LOAD_ATTR] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG }, [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, - [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG }, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG }, [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG }, [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_RECORDS_VALUE_FLAG }, @@ -1444,6 +1444,7 @@ _PyOpcode_macro_expansion[256] = { [LOAD_ATTR] = { .nuops = 1, .uops = { { _LOAD_ATTR, OPARG_SIMPLE, 8 } } }, [LOAD_ATTR_CLASS] = { .nuops = 3, .uops = { { _CHECK_ATTR_CLASS, 2, 1 }, { _LOAD_ATTR_CLASS, 4, 5 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } }, [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = { .nuops = 5, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_CLASS, 2, 3 }, { _LOAD_ATTR_CLASS, 4, 5 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } }, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { .nuops = 7, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_PEP_523, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME, 2, 3 }, { _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME, OPERAND1_4, 5 }, { _SAVE_RETURN_OFFSET, OPARG_SAVE_RETURN_OFFSET, 9 }, { _PUSH_FRAME, OPARG_SIMPLE, 9 } } }, [LOAD_ATTR_INSTANCE_VALUE] = { .nuops = 6, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_MANAGED_OBJECT_HAS_VALUES, OPARG_SIMPLE, 3 }, { _LOAD_ATTR_INSTANCE_VALUE, 1, 3 }, { _POP_TOP, OPARG_SIMPLE, 4 }, { _PUSH_NULL_CONDITIONAL, OPARG_SIMPLE, 9 } } }, [LOAD_ATTR_METHOD_LAZY_DICT] = { .nuops = 4, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _CHECK_ATTR_METHOD_LAZY_DICT, 1, 3 }, { _LOAD_ATTR_METHOD_LAZY_DICT, 4, 5 } } }, [LOAD_ATTR_METHOD_NO_DICT] = { .nuops = 3, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 1 }, { _GUARD_TYPE_VERSION, 2, 1 }, { _LOAD_ATTR_METHOD_NO_DICT, 4, 5 } } }, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index 105878aef3ae9b..e7fa495d46108b 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -259,1110 +259,1110 @@ extern "C" { #define _LIST_EXTEND 506 #define _LOAD_ATTR 507 #define _LOAD_ATTR_CLASS 508 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN -#define _LOAD_ATTR_INSTANCE_VALUE 509 -#define _LOAD_ATTR_METHOD_LAZY_DICT 510 -#define _LOAD_ATTR_METHOD_NO_DICT 511 -#define _LOAD_ATTR_METHOD_WITH_VALUES 512 -#define _LOAD_ATTR_MODULE 513 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 514 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 515 -#define _LOAD_ATTR_PROPERTY_FRAME 516 -#define _LOAD_ATTR_SLOT 517 -#define _LOAD_ATTR_WITH_HINT 518 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME 509 +#define _LOAD_ATTR_INSTANCE_VALUE 510 +#define _LOAD_ATTR_METHOD_LAZY_DICT 511 +#define _LOAD_ATTR_METHOD_NO_DICT 512 +#define _LOAD_ATTR_METHOD_WITH_VALUES 513 +#define _LOAD_ATTR_MODULE 514 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 515 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 516 +#define _LOAD_ATTR_PROPERTY_FRAME 517 +#define _LOAD_ATTR_SLOT 518 +#define _LOAD_ATTR_WITH_HINT 519 #define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS -#define _LOAD_BYTECODE 519 +#define _LOAD_BYTECODE 520 #define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT #define _LOAD_CONST LOAD_CONST -#define _LOAD_CONST_INLINE 520 -#define _LOAD_CONST_INLINE_BORROW 521 +#define _LOAD_CONST_INLINE 521 +#define _LOAD_CONST_INLINE_BORROW 522 #define _LOAD_DEREF LOAD_DEREF -#define _LOAD_FAST 522 -#define _LOAD_FAST_0 523 -#define _LOAD_FAST_1 524 -#define _LOAD_FAST_2 525 -#define _LOAD_FAST_3 526 -#define _LOAD_FAST_4 527 -#define _LOAD_FAST_5 528 -#define _LOAD_FAST_6 529 -#define _LOAD_FAST_7 530 +#define _LOAD_FAST 523 +#define _LOAD_FAST_0 524 +#define _LOAD_FAST_1 525 +#define _LOAD_FAST_2 526 +#define _LOAD_FAST_3 527 +#define _LOAD_FAST_4 528 +#define _LOAD_FAST_5 529 +#define _LOAD_FAST_6 530 +#define _LOAD_FAST_7 531 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR -#define _LOAD_FAST_BORROW 531 -#define _LOAD_FAST_BORROW_0 532 -#define _LOAD_FAST_BORROW_1 533 -#define _LOAD_FAST_BORROW_2 534 -#define _LOAD_FAST_BORROW_3 535 -#define _LOAD_FAST_BORROW_4 536 -#define _LOAD_FAST_BORROW_5 537 -#define _LOAD_FAST_BORROW_6 538 -#define _LOAD_FAST_BORROW_7 539 +#define _LOAD_FAST_BORROW 532 +#define _LOAD_FAST_BORROW_0 533 +#define _LOAD_FAST_BORROW_1 534 +#define _LOAD_FAST_BORROW_2 535 +#define _LOAD_FAST_BORROW_3 536 +#define _LOAD_FAST_BORROW_4 537 +#define _LOAD_FAST_BORROW_5 538 +#define _LOAD_FAST_BORROW_6 539 +#define _LOAD_FAST_BORROW_7 540 #define _LOAD_FAST_CHECK LOAD_FAST_CHECK #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS -#define _LOAD_GLOBAL 540 -#define _LOAD_GLOBAL_BUILTINS 541 -#define _LOAD_GLOBAL_MODULE 542 +#define _LOAD_GLOBAL 541 +#define _LOAD_GLOBAL_BUILTINS 542 +#define _LOAD_GLOBAL_MODULE 543 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME -#define _LOAD_SMALL_INT 543 -#define _LOAD_SMALL_INT_0 544 -#define _LOAD_SMALL_INT_1 545 -#define _LOAD_SMALL_INT_2 546 -#define _LOAD_SMALL_INT_3 547 -#define _LOAD_SPECIAL 548 +#define _LOAD_SMALL_INT 544 +#define _LOAD_SMALL_INT_0 545 +#define _LOAD_SMALL_INT_1 546 +#define _LOAD_SMALL_INT_2 547 +#define _LOAD_SMALL_INT_3 548 +#define _LOAD_SPECIAL 549 #define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR -#define _LOAD_SUPER_ATTR_METHOD 549 -#define _LOCK_OBJECT 550 -#define _MAKE_CALLARGS_A_TUPLE 551 +#define _LOAD_SUPER_ATTR_METHOD 550 +#define _LOCK_OBJECT 551 +#define _MAKE_CALLARGS_A_TUPLE 552 #define _MAKE_CELL MAKE_CELL -#define _MAKE_FUNCTION 552 -#define _MAKE_HEAP_SAFE 553 -#define _MAKE_WARM 554 +#define _MAKE_FUNCTION 553 +#define _MAKE_HEAP_SAFE 554 +#define _MAKE_WARM 555 #define _MAP_ADD MAP_ADD -#define _MATCH_CLASS 555 +#define _MATCH_CLASS 556 #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 556 -#define _MAYBE_EXPAND_METHOD_KW 557 -#define _MONITOR_CALL 558 -#define _MONITOR_CALL_KW 559 -#define _MONITOR_JUMP_BACKWARD 560 -#define _MONITOR_RESUME 561 +#define _MAYBE_EXPAND_METHOD 557 +#define _MAYBE_EXPAND_METHOD_KW 558 +#define _MONITOR_CALL 559 +#define _MONITOR_CALL_KW 560 +#define _MONITOR_JUMP_BACKWARD 561 +#define _MONITOR_RESUME 562 #define _NOP NOP #define _POP_EXCEPT POP_EXCEPT #define _POP_ITER POP_ITER -#define _POP_JUMP_IF_FALSE 562 -#define _POP_JUMP_IF_TRUE 563 +#define _POP_JUMP_IF_FALSE 563 +#define _POP_JUMP_IF_TRUE 564 #define _POP_TOP POP_TOP -#define _POP_TOP_FLOAT 564 -#define _POP_TOP_INT 565 -#define _POP_TOP_NOP 566 -#define _POP_TOP_OPARG 567 -#define _POP_TOP_UNICODE 568 +#define _POP_TOP_FLOAT 565 +#define _POP_TOP_INT 566 +#define _POP_TOP_NOP 567 +#define _POP_TOP_OPARG 568 +#define _POP_TOP_UNICODE 569 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 569 +#define _PUSH_FRAME 570 #define _PUSH_NULL PUSH_NULL -#define _PUSH_NULL_CONDITIONAL 570 -#define _PY_FRAME_EX 571 -#define _PY_FRAME_GENERAL 572 -#define _PY_FRAME_KW 573 -#define _RECORD_3OS_GEN_FUNC 574 -#define _RECORD_4OS 575 -#define _RECORD_BOUND_METHOD 576 -#define _RECORD_CALLABLE 577 -#define _RECORD_CALLABLE_KW 578 -#define _RECORD_CODE 579 -#define _RECORD_NOS 580 -#define _RECORD_NOS_GEN_FUNC 581 -#define _RECORD_TOS 582 -#define _RECORD_TOS_TYPE 583 -#define _REPLACE_WITH_TRUE 584 -#define _RESUME_CHECK 585 +#define _PUSH_NULL_CONDITIONAL 571 +#define _PY_FRAME_EX 572 +#define _PY_FRAME_GENERAL 573 +#define _PY_FRAME_KW 574 +#define _RECORD_3OS_GEN_FUNC 575 +#define _RECORD_4OS 576 +#define _RECORD_BOUND_METHOD 577 +#define _RECORD_CALLABLE 578 +#define _RECORD_CALLABLE_KW 579 +#define _RECORD_CODE 580 +#define _RECORD_NOS 581 +#define _RECORD_NOS_GEN_FUNC 582 +#define _RECORD_TOS 583 +#define _RECORD_TOS_TYPE 584 +#define _REPLACE_WITH_TRUE 585 +#define _RESUME_CHECK 586 #define _RETURN_GENERATOR RETURN_GENERATOR -#define _RETURN_VALUE 586 -#define _SAVE_RETURN_OFFSET 587 -#define _SEND 588 -#define _SEND_GEN_FRAME 589 +#define _RETURN_VALUE 587 +#define _SAVE_RETURN_OFFSET 588 +#define _SEND 589 +#define _SEND_GEN_FRAME 590 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE -#define _SET_UPDATE 590 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 591 -#define _SPILL_OR_RELOAD 592 -#define _START_EXECUTOR 593 -#define _STORE_ATTR 594 -#define _STORE_ATTR_INSTANCE_VALUE 595 -#define _STORE_ATTR_SLOT 596 -#define _STORE_ATTR_WITH_HINT 597 +#define _SET_UPDATE 591 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW 592 +#define _SPILL_OR_RELOAD 593 +#define _START_EXECUTOR 594 +#define _STORE_ATTR 595 +#define _STORE_ATTR_INSTANCE_VALUE 596 +#define _STORE_ATTR_SLOT 597 +#define _STORE_ATTR_WITH_HINT 598 #define _STORE_DEREF STORE_DEREF #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 598 -#define _STORE_SUBSCR 599 -#define _STORE_SUBSCR_DICT 600 -#define _STORE_SUBSCR_DICT_KNOWN_HASH 601 -#define _STORE_SUBSCR_LIST_INT 602 -#define _SWAP 603 -#define _SWAP_2 604 -#define _SWAP_3 605 -#define _SWAP_FAST 606 -#define _SWAP_FAST_0 607 -#define _SWAP_FAST_1 608 -#define _SWAP_FAST_2 609 -#define _SWAP_FAST_3 610 -#define _SWAP_FAST_4 611 -#define _SWAP_FAST_5 612 -#define _SWAP_FAST_6 613 -#define _SWAP_FAST_7 614 -#define _TIER2_RESUME_CHECK 615 -#define _TO_BOOL 616 +#define _STORE_SLICE 599 +#define _STORE_SUBSCR 600 +#define _STORE_SUBSCR_DICT 601 +#define _STORE_SUBSCR_DICT_KNOWN_HASH 602 +#define _STORE_SUBSCR_LIST_INT 603 +#define _SWAP 604 +#define _SWAP_2 605 +#define _SWAP_3 606 +#define _SWAP_FAST 607 +#define _SWAP_FAST_0 608 +#define _SWAP_FAST_1 609 +#define _SWAP_FAST_2 610 +#define _SWAP_FAST_3 611 +#define _SWAP_FAST_4 612 +#define _SWAP_FAST_5 613 +#define _SWAP_FAST_6 614 +#define _SWAP_FAST_7 615 +#define _TIER2_RESUME_CHECK 616 +#define _TO_BOOL 617 #define _TO_BOOL_BOOL TO_BOOL_BOOL -#define _TO_BOOL_INT 617 -#define _TO_BOOL_LIST 618 +#define _TO_BOOL_INT 618 +#define _TO_BOOL_LIST 619 #define _TO_BOOL_NONE TO_BOOL_NONE -#define _TO_BOOL_STR 619 +#define _TO_BOOL_STR 620 #define _TRACE_RECORD TRACE_RECORD -#define _UNARY_INVERT 620 -#define _UNARY_NEGATIVE 621 -#define _UNARY_NEGATIVE_FLOAT_INPLACE 622 +#define _UNARY_INVERT 621 +#define _UNARY_NEGATIVE 622 +#define _UNARY_NEGATIVE_FLOAT_INPLACE 623 #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 623 -#define _UNPACK_SEQUENCE_LIST 624 -#define _UNPACK_SEQUENCE_TUPLE 625 -#define _UNPACK_SEQUENCE_TWO_TUPLE 626 -#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE 627 -#define _UNPACK_SEQUENCE_UNIQUE_TUPLE 628 -#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE 629 +#define _UNPACK_SEQUENCE 624 +#define _UNPACK_SEQUENCE_LIST 625 +#define _UNPACK_SEQUENCE_TUPLE 626 +#define _UNPACK_SEQUENCE_TWO_TUPLE 627 +#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE 628 +#define _UNPACK_SEQUENCE_UNIQUE_TUPLE 629 +#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE 630 #define _WITH_EXCEPT_START WITH_EXCEPT_START -#define _YIELD_VALUE 630 -#define MAX_UOP_ID 630 -#define _ALLOCATE_OBJECT_r00 631 -#define _BINARY_OP_r23 632 -#define _BINARY_OP_ADD_FLOAT_r03 633 -#define _BINARY_OP_ADD_FLOAT_r13 634 -#define _BINARY_OP_ADD_FLOAT_r23 635 -#define _BINARY_OP_ADD_FLOAT_INPLACE_r03 636 -#define _BINARY_OP_ADD_FLOAT_INPLACE_r13 637 -#define _BINARY_OP_ADD_FLOAT_INPLACE_r23 638 -#define _BINARY_OP_ADD_FLOAT_INPLACE_RIGHT_r03 639 -#define _BINARY_OP_ADD_FLOAT_INPLACE_RIGHT_r13 640 -#define _BINARY_OP_ADD_FLOAT_INPLACE_RIGHT_r23 641 -#define _BINARY_OP_ADD_INT_r03 642 -#define _BINARY_OP_ADD_INT_r13 643 -#define _BINARY_OP_ADD_INT_r23 644 -#define _BINARY_OP_ADD_INT_INPLACE_r03 645 -#define _BINARY_OP_ADD_INT_INPLACE_r13 646 -#define _BINARY_OP_ADD_INT_INPLACE_r23 647 -#define _BINARY_OP_ADD_INT_INPLACE_RIGHT_r03 648 -#define _BINARY_OP_ADD_INT_INPLACE_RIGHT_r13 649 -#define _BINARY_OP_ADD_INT_INPLACE_RIGHT_r23 650 -#define _BINARY_OP_ADD_UNICODE_r03 651 -#define _BINARY_OP_ADD_UNICODE_r13 652 -#define _BINARY_OP_ADD_UNICODE_r23 653 -#define _BINARY_OP_EXTEND_r23 654 -#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 655 -#define _BINARY_OP_MULTIPLY_FLOAT_r03 656 -#define _BINARY_OP_MULTIPLY_FLOAT_r13 657 -#define _BINARY_OP_MULTIPLY_FLOAT_r23 658 -#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_r03 659 -#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_r13 660 -#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_r23 661 -#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_RIGHT_r03 662 -#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_RIGHT_r13 663 -#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_RIGHT_r23 664 -#define _BINARY_OP_MULTIPLY_INT_r03 665 -#define _BINARY_OP_MULTIPLY_INT_r13 666 -#define _BINARY_OP_MULTIPLY_INT_r23 667 -#define _BINARY_OP_MULTIPLY_INT_INPLACE_r03 668 -#define _BINARY_OP_MULTIPLY_INT_INPLACE_r13 669 -#define _BINARY_OP_MULTIPLY_INT_INPLACE_r23 670 -#define _BINARY_OP_MULTIPLY_INT_INPLACE_RIGHT_r03 671 -#define _BINARY_OP_MULTIPLY_INT_INPLACE_RIGHT_r13 672 -#define _BINARY_OP_MULTIPLY_INT_INPLACE_RIGHT_r23 673 -#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 674 -#define _BINARY_OP_SUBSCR_DICT_r23 675 -#define _BINARY_OP_SUBSCR_DICT_KNOWN_HASH_r23 676 -#define _BINARY_OP_SUBSCR_INIT_CALL_r01 677 -#define _BINARY_OP_SUBSCR_INIT_CALL_r11 678 -#define _BINARY_OP_SUBSCR_INIT_CALL_r21 679 -#define _BINARY_OP_SUBSCR_INIT_CALL_r31 680 -#define _BINARY_OP_SUBSCR_LIST_INT_r23 681 -#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 682 -#define _BINARY_OP_SUBSCR_STR_INT_r23 683 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 684 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 685 -#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 686 -#define _BINARY_OP_SUBSCR_USTR_INT_r23 687 -#define _BINARY_OP_SUBTRACT_FLOAT_r03 688 -#define _BINARY_OP_SUBTRACT_FLOAT_r13 689 -#define _BINARY_OP_SUBTRACT_FLOAT_r23 690 -#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_r03 691 -#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_r13 692 -#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_r23 693 -#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_RIGHT_r03 694 -#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_RIGHT_r13 695 -#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_RIGHT_r23 696 -#define _BINARY_OP_SUBTRACT_INT_r03 697 -#define _BINARY_OP_SUBTRACT_INT_r13 698 -#define _BINARY_OP_SUBTRACT_INT_r23 699 -#define _BINARY_OP_SUBTRACT_INT_INPLACE_r03 700 -#define _BINARY_OP_SUBTRACT_INT_INPLACE_r13 701 -#define _BINARY_OP_SUBTRACT_INT_INPLACE_r23 702 -#define _BINARY_OP_SUBTRACT_INT_INPLACE_RIGHT_r03 703 -#define _BINARY_OP_SUBTRACT_INT_INPLACE_RIGHT_r13 704 -#define _BINARY_OP_SUBTRACT_INT_INPLACE_RIGHT_r23 705 -#define _BINARY_SLICE_r31 706 -#define _BUILD_INTERPOLATION_r01 707 -#define _BUILD_LIST_r01 708 -#define _BUILD_MAP_r01 709 -#define _BUILD_SET_r01 710 -#define _BUILD_SLICE_r01 711 -#define _BUILD_STRING_r01 712 -#define _BUILD_TEMPLATE_r21 713 -#define _BUILD_TUPLE_r01 714 -#define _CALL_BUILTIN_CLASS_r00 715 -#define _CALL_BUILTIN_FAST_r00 716 -#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r00 717 -#define _CALL_BUILTIN_O_r03 718 -#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 719 -#define _CALL_INTRINSIC_1_r12 720 -#define _CALL_INTRINSIC_2_r23 721 -#define _CALL_ISINSTANCE_r31 722 -#define _CALL_KW_NON_PY_r11 723 -#define _CALL_LEN_r33 724 -#define _CALL_LIST_APPEND_r03 725 -#define _CALL_LIST_APPEND_r13 726 -#define _CALL_LIST_APPEND_r23 727 -#define _CALL_LIST_APPEND_r33 728 -#define _CALL_METHOD_DESCRIPTOR_FAST_r00 729 -#define _CALL_METHOD_DESCRIPTOR_FAST_INLINE_r00 730 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r00 731 -#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_INLINE_r00 732 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_r03 733 -#define _CALL_METHOD_DESCRIPTOR_NOARGS_INLINE_r03 734 -#define _CALL_METHOD_DESCRIPTOR_O_r03 735 -#define _CALL_METHOD_DESCRIPTOR_O_INLINE_r03 736 -#define _CALL_NON_PY_GENERAL_r01 737 -#define _CALL_STR_1_r32 738 -#define _CALL_TUPLE_1_r32 739 -#define _CALL_TYPE_1_r02 740 -#define _CALL_TYPE_1_r12 741 -#define _CALL_TYPE_1_r22 742 -#define _CALL_TYPE_1_r32 743 -#define _CHECK_ATTR_CLASS_r01 744 -#define _CHECK_ATTR_CLASS_r11 745 -#define _CHECK_ATTR_CLASS_r22 746 -#define _CHECK_ATTR_CLASS_r33 747 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 748 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 749 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 750 -#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 751 -#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 752 -#define _CHECK_EG_MATCH_r22 753 -#define _CHECK_EXC_MATCH_r22 754 -#define _CHECK_FUNCTION_EXACT_ARGS_r00 755 -#define _CHECK_FUNCTION_VERSION_r00 756 -#define _CHECK_FUNCTION_VERSION_INLINE_r00 757 -#define _CHECK_FUNCTION_VERSION_INLINE_r11 758 -#define _CHECK_FUNCTION_VERSION_INLINE_r22 759 -#define _CHECK_FUNCTION_VERSION_INLINE_r33 760 -#define _CHECK_FUNCTION_VERSION_KW_r11 761 -#define _CHECK_IS_NOT_PY_CALLABLE_r00 762 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 763 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 764 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 765 -#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 766 -#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 767 -#define _CHECK_IS_PY_CALLABLE_EX_r03 768 -#define _CHECK_IS_PY_CALLABLE_EX_r13 769 -#define _CHECK_IS_PY_CALLABLE_EX_r23 770 -#define _CHECK_IS_PY_CALLABLE_EX_r33 771 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 772 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 773 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 774 -#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 775 -#define _CHECK_METHOD_VERSION_r00 776 -#define _CHECK_METHOD_VERSION_KW_r11 777 -#define _CHECK_OBJECT_r00 778 -#define _CHECK_PEP_523_r00 779 -#define _CHECK_PEP_523_r11 780 -#define _CHECK_PEP_523_r22 781 -#define _CHECK_PEP_523_r33 782 -#define _CHECK_PERIODIC_r00 783 -#define _CHECK_PERIODIC_AT_END_r00 784 -#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 785 -#define _CHECK_RECURSION_LIMIT_r00 786 -#define _CHECK_RECURSION_LIMIT_r11 787 -#define _CHECK_RECURSION_LIMIT_r22 788 -#define _CHECK_RECURSION_LIMIT_r33 789 -#define _CHECK_RECURSION_REMAINING_r00 790 -#define _CHECK_RECURSION_REMAINING_r11 791 -#define _CHECK_RECURSION_REMAINING_r22 792 -#define _CHECK_RECURSION_REMAINING_r33 793 -#define _CHECK_STACK_SPACE_r00 794 -#define _CHECK_STACK_SPACE_OPERAND_r00 795 -#define _CHECK_STACK_SPACE_OPERAND_r11 796 -#define _CHECK_STACK_SPACE_OPERAND_r22 797 -#define _CHECK_STACK_SPACE_OPERAND_r33 798 -#define _CHECK_VALIDITY_r00 799 -#define _CHECK_VALIDITY_r11 800 -#define _CHECK_VALIDITY_r22 801 -#define _CHECK_VALIDITY_r33 802 -#define _COLD_DYNAMIC_EXIT_r00 803 -#define _COLD_EXIT_r00 804 -#define _COMPARE_OP_r21 805 -#define _COMPARE_OP_FLOAT_r03 806 -#define _COMPARE_OP_FLOAT_r13 807 -#define _COMPARE_OP_FLOAT_r23 808 -#define _COMPARE_OP_INT_r23 809 -#define _COMPARE_OP_STR_r23 810 -#define _CONTAINS_OP_r23 811 -#define _CONTAINS_OP_DICT_r23 812 -#define _CONTAINS_OP_SET_r23 813 -#define _CONVERT_VALUE_r11 814 -#define _COPY_r01 815 -#define _COPY_1_r02 816 -#define _COPY_1_r12 817 -#define _COPY_1_r23 818 -#define _COPY_2_r03 819 -#define _COPY_2_r13 820 -#define _COPY_2_r23 821 -#define _COPY_3_r03 822 -#define _COPY_3_r13 823 -#define _COPY_3_r23 824 -#define _COPY_3_r33 825 -#define _COPY_FREE_VARS_r00 826 -#define _COPY_FREE_VARS_r11 827 -#define _COPY_FREE_VARS_r22 828 -#define _COPY_FREE_VARS_r33 829 -#define _CREATE_INIT_FRAME_r01 830 -#define _DELETE_ATTR_r10 831 -#define _DELETE_DEREF_r00 832 -#define _DELETE_FAST_r00 833 -#define _DELETE_GLOBAL_r00 834 -#define _DELETE_NAME_r00 835 -#define _DELETE_SUBSCR_r20 836 -#define _DEOPT_r00 837 -#define _DEOPT_r10 838 -#define _DEOPT_r20 839 -#define _DEOPT_r30 840 -#define _DICT_MERGE_r11 841 -#define _DICT_UPDATE_r11 842 -#define _DO_CALL_r01 843 -#define _DO_CALL_FUNCTION_EX_r31 844 -#define _DO_CALL_KW_r11 845 -#define _DYNAMIC_EXIT_r00 846 -#define _DYNAMIC_EXIT_r10 847 -#define _DYNAMIC_EXIT_r20 848 -#define _DYNAMIC_EXIT_r30 849 -#define _END_FOR_r10 850 -#define _END_SEND_r31 851 -#define _ERROR_POP_N_r00 852 -#define _EXIT_INIT_CHECK_r10 853 -#define _EXIT_TRACE_r00 854 -#define _EXIT_TRACE_r10 855 -#define _EXIT_TRACE_r20 856 -#define _EXIT_TRACE_r30 857 -#define _EXPAND_METHOD_r00 858 -#define _EXPAND_METHOD_KW_r11 859 -#define _FATAL_ERROR_r00 860 -#define _FATAL_ERROR_r11 861 -#define _FATAL_ERROR_r22 862 -#define _FATAL_ERROR_r33 863 -#define _FORMAT_SIMPLE_r11 864 -#define _FORMAT_WITH_SPEC_r21 865 -#define _FOR_ITER_r23 866 -#define _FOR_ITER_GEN_FRAME_r03 867 -#define _FOR_ITER_GEN_FRAME_r13 868 -#define _FOR_ITER_GEN_FRAME_r23 869 -#define _FOR_ITER_TIER_TWO_r23 870 -#define _GET_AITER_r11 871 -#define _GET_ANEXT_r12 872 -#define _GET_AWAITABLE_r11 873 -#define _GET_ITER_r12 874 -#define _GET_LEN_r12 875 -#define _GUARD_BINARY_OP_EXTEND_r22 876 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 877 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 878 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 879 -#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 880 -#define _GUARD_BIT_IS_SET_POP_r00 881 -#define _GUARD_BIT_IS_SET_POP_r10 882 -#define _GUARD_BIT_IS_SET_POP_r21 883 -#define _GUARD_BIT_IS_SET_POP_r32 884 -#define _GUARD_BIT_IS_SET_POP_4_r00 885 -#define _GUARD_BIT_IS_SET_POP_4_r10 886 -#define _GUARD_BIT_IS_SET_POP_4_r21 887 -#define _GUARD_BIT_IS_SET_POP_4_r32 888 -#define _GUARD_BIT_IS_SET_POP_5_r00 889 -#define _GUARD_BIT_IS_SET_POP_5_r10 890 -#define _GUARD_BIT_IS_SET_POP_5_r21 891 -#define _GUARD_BIT_IS_SET_POP_5_r32 892 -#define _GUARD_BIT_IS_SET_POP_6_r00 893 -#define _GUARD_BIT_IS_SET_POP_6_r10 894 -#define _GUARD_BIT_IS_SET_POP_6_r21 895 -#define _GUARD_BIT_IS_SET_POP_6_r32 896 -#define _GUARD_BIT_IS_SET_POP_7_r00 897 -#define _GUARD_BIT_IS_SET_POP_7_r10 898 -#define _GUARD_BIT_IS_SET_POP_7_r21 899 -#define _GUARD_BIT_IS_SET_POP_7_r32 900 -#define _GUARD_BIT_IS_UNSET_POP_r00 901 -#define _GUARD_BIT_IS_UNSET_POP_r10 902 -#define _GUARD_BIT_IS_UNSET_POP_r21 903 -#define _GUARD_BIT_IS_UNSET_POP_r32 904 -#define _GUARD_BIT_IS_UNSET_POP_4_r00 905 -#define _GUARD_BIT_IS_UNSET_POP_4_r10 906 -#define _GUARD_BIT_IS_UNSET_POP_4_r21 907 -#define _GUARD_BIT_IS_UNSET_POP_4_r32 908 -#define _GUARD_BIT_IS_UNSET_POP_5_r00 909 -#define _GUARD_BIT_IS_UNSET_POP_5_r10 910 -#define _GUARD_BIT_IS_UNSET_POP_5_r21 911 -#define _GUARD_BIT_IS_UNSET_POP_5_r32 912 -#define _GUARD_BIT_IS_UNSET_POP_6_r00 913 -#define _GUARD_BIT_IS_UNSET_POP_6_r10 914 -#define _GUARD_BIT_IS_UNSET_POP_6_r21 915 -#define _GUARD_BIT_IS_UNSET_POP_6_r32 916 -#define _GUARD_BIT_IS_UNSET_POP_7_r00 917 -#define _GUARD_BIT_IS_UNSET_POP_7_r10 918 -#define _GUARD_BIT_IS_UNSET_POP_7_r21 919 -#define _GUARD_BIT_IS_UNSET_POP_7_r32 920 -#define _GUARD_CALLABLE_BUILTIN_CLASS_r00 921 -#define _GUARD_CALLABLE_BUILTIN_FAST_r00 922 -#define _GUARD_CALLABLE_BUILTIN_FAST_WITH_KEYWORDS_r00 923 -#define _GUARD_CALLABLE_BUILTIN_O_r00 924 -#define _GUARD_CALLABLE_ISINSTANCE_r03 925 -#define _GUARD_CALLABLE_ISINSTANCE_r13 926 -#define _GUARD_CALLABLE_ISINSTANCE_r23 927 -#define _GUARD_CALLABLE_ISINSTANCE_r33 928 -#define _GUARD_CALLABLE_LEN_r03 929 -#define _GUARD_CALLABLE_LEN_r13 930 -#define _GUARD_CALLABLE_LEN_r23 931 -#define _GUARD_CALLABLE_LEN_r33 932 -#define _GUARD_CALLABLE_LIST_APPEND_r03 933 -#define _GUARD_CALLABLE_LIST_APPEND_r13 934 -#define _GUARD_CALLABLE_LIST_APPEND_r23 935 -#define _GUARD_CALLABLE_LIST_APPEND_r33 936 -#define _GUARD_CALLABLE_METHOD_DESCRIPTOR_FAST_r00 937 -#define _GUARD_CALLABLE_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r00 938 -#define _GUARD_CALLABLE_METHOD_DESCRIPTOR_NOARGS_r00 939 -#define _GUARD_CALLABLE_METHOD_DESCRIPTOR_O_r00 940 -#define _GUARD_CALLABLE_STR_1_r03 941 -#define _GUARD_CALLABLE_STR_1_r13 942 -#define _GUARD_CALLABLE_STR_1_r23 943 -#define _GUARD_CALLABLE_STR_1_r33 944 -#define _GUARD_CALLABLE_TUPLE_1_r03 945 -#define _GUARD_CALLABLE_TUPLE_1_r13 946 -#define _GUARD_CALLABLE_TUPLE_1_r23 947 -#define _GUARD_CALLABLE_TUPLE_1_r33 948 -#define _GUARD_CALLABLE_TYPE_1_r03 949 -#define _GUARD_CALLABLE_TYPE_1_r13 950 -#define _GUARD_CALLABLE_TYPE_1_r23 951 -#define _GUARD_CALLABLE_TYPE_1_r33 952 -#define _GUARD_CODE_VERSION_RETURN_GENERATOR_r00 953 -#define _GUARD_CODE_VERSION_RETURN_GENERATOR_r11 954 -#define _GUARD_CODE_VERSION_RETURN_GENERATOR_r22 955 -#define _GUARD_CODE_VERSION_RETURN_GENERATOR_r33 956 -#define _GUARD_CODE_VERSION_RETURN_VALUE_r00 957 -#define _GUARD_CODE_VERSION_RETURN_VALUE_r11 958 -#define _GUARD_CODE_VERSION_RETURN_VALUE_r22 959 -#define _GUARD_CODE_VERSION_RETURN_VALUE_r33 960 -#define _GUARD_CODE_VERSION_YIELD_VALUE_r00 961 -#define _GUARD_CODE_VERSION_YIELD_VALUE_r11 962 -#define _GUARD_CODE_VERSION_YIELD_VALUE_r22 963 -#define _GUARD_CODE_VERSION_YIELD_VALUE_r33 964 -#define _GUARD_CODE_VERSION__PUSH_FRAME_r00 965 -#define _GUARD_CODE_VERSION__PUSH_FRAME_r11 966 -#define _GUARD_CODE_VERSION__PUSH_FRAME_r22 967 -#define _GUARD_CODE_VERSION__PUSH_FRAME_r33 968 -#define _GUARD_DORV_NO_DICT_r01 969 -#define _GUARD_DORV_NO_DICT_r11 970 -#define _GUARD_DORV_NO_DICT_r22 971 -#define _GUARD_DORV_NO_DICT_r33 972 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 973 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 974 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 975 -#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 976 -#define _GUARD_GLOBALS_VERSION_r00 977 -#define _GUARD_GLOBALS_VERSION_r11 978 -#define _GUARD_GLOBALS_VERSION_r22 979 -#define _GUARD_GLOBALS_VERSION_r33 980 -#define _GUARD_IP_RETURN_GENERATOR_r00 981 -#define _GUARD_IP_RETURN_GENERATOR_r11 982 -#define _GUARD_IP_RETURN_GENERATOR_r22 983 -#define _GUARD_IP_RETURN_GENERATOR_r33 984 -#define _GUARD_IP_RETURN_VALUE_r00 985 -#define _GUARD_IP_RETURN_VALUE_r11 986 -#define _GUARD_IP_RETURN_VALUE_r22 987 -#define _GUARD_IP_RETURN_VALUE_r33 988 -#define _GUARD_IP_YIELD_VALUE_r00 989 -#define _GUARD_IP_YIELD_VALUE_r11 990 -#define _GUARD_IP_YIELD_VALUE_r22 991 -#define _GUARD_IP_YIELD_VALUE_r33 992 -#define _GUARD_IP__PUSH_FRAME_r00 993 -#define _GUARD_IP__PUSH_FRAME_r11 994 -#define _GUARD_IP__PUSH_FRAME_r22 995 -#define _GUARD_IP__PUSH_FRAME_r33 996 -#define _GUARD_IS_FALSE_POP_r00 997 -#define _GUARD_IS_FALSE_POP_r10 998 -#define _GUARD_IS_FALSE_POP_r21 999 -#define _GUARD_IS_FALSE_POP_r32 1000 -#define _GUARD_IS_NONE_POP_r00 1001 -#define _GUARD_IS_NONE_POP_r10 1002 -#define _GUARD_IS_NONE_POP_r21 1003 -#define _GUARD_IS_NONE_POP_r32 1004 -#define _GUARD_IS_NOT_NONE_POP_r10 1005 -#define _GUARD_IS_TRUE_POP_r00 1006 -#define _GUARD_IS_TRUE_POP_r10 1007 -#define _GUARD_IS_TRUE_POP_r21 1008 -#define _GUARD_IS_TRUE_POP_r32 1009 -#define _GUARD_KEYS_VERSION_r01 1010 -#define _GUARD_KEYS_VERSION_r11 1011 -#define _GUARD_KEYS_VERSION_r22 1012 -#define _GUARD_KEYS_VERSION_r33 1013 -#define _GUARD_LOAD_SUPER_ATTR_METHOD_r03 1014 -#define _GUARD_LOAD_SUPER_ATTR_METHOD_r13 1015 -#define _GUARD_LOAD_SUPER_ATTR_METHOD_r23 1016 -#define _GUARD_LOAD_SUPER_ATTR_METHOD_r33 1017 -#define _GUARD_NOS_ANY_DICT_r02 1018 -#define _GUARD_NOS_ANY_DICT_r12 1019 -#define _GUARD_NOS_ANY_DICT_r22 1020 -#define _GUARD_NOS_ANY_DICT_r33 1021 -#define _GUARD_NOS_COMPACT_ASCII_r02 1022 -#define _GUARD_NOS_COMPACT_ASCII_r12 1023 -#define _GUARD_NOS_COMPACT_ASCII_r22 1024 -#define _GUARD_NOS_COMPACT_ASCII_r33 1025 -#define _GUARD_NOS_DICT_r02 1026 -#define _GUARD_NOS_DICT_r12 1027 -#define _GUARD_NOS_DICT_r22 1028 -#define _GUARD_NOS_DICT_r33 1029 -#define _GUARD_NOS_FLOAT_r02 1030 -#define _GUARD_NOS_FLOAT_r12 1031 -#define _GUARD_NOS_FLOAT_r22 1032 -#define _GUARD_NOS_FLOAT_r33 1033 -#define _GUARD_NOS_INT_r02 1034 -#define _GUARD_NOS_INT_r12 1035 -#define _GUARD_NOS_INT_r22 1036 -#define _GUARD_NOS_INT_r33 1037 -#define _GUARD_NOS_LIST_r02 1038 -#define _GUARD_NOS_LIST_r12 1039 -#define _GUARD_NOS_LIST_r22 1040 -#define _GUARD_NOS_LIST_r33 1041 -#define _GUARD_NOS_NOT_NULL_r02 1042 -#define _GUARD_NOS_NOT_NULL_r12 1043 -#define _GUARD_NOS_NOT_NULL_r22 1044 -#define _GUARD_NOS_NOT_NULL_r33 1045 -#define _GUARD_NOS_NULL_r02 1046 -#define _GUARD_NOS_NULL_r12 1047 -#define _GUARD_NOS_NULL_r22 1048 -#define _GUARD_NOS_NULL_r33 1049 -#define _GUARD_NOS_OVERFLOWED_r02 1050 -#define _GUARD_NOS_OVERFLOWED_r12 1051 -#define _GUARD_NOS_OVERFLOWED_r22 1052 -#define _GUARD_NOS_OVERFLOWED_r33 1053 -#define _GUARD_NOS_TUPLE_r02 1054 -#define _GUARD_NOS_TUPLE_r12 1055 -#define _GUARD_NOS_TUPLE_r22 1056 -#define _GUARD_NOS_TUPLE_r33 1057 -#define _GUARD_NOS_TYPE_VERSION_r02 1058 -#define _GUARD_NOS_TYPE_VERSION_r12 1059 -#define _GUARD_NOS_TYPE_VERSION_r22 1060 -#define _GUARD_NOS_TYPE_VERSION_r33 1061 -#define _GUARD_NOS_UNICODE_r02 1062 -#define _GUARD_NOS_UNICODE_r12 1063 -#define _GUARD_NOS_UNICODE_r22 1064 -#define _GUARD_NOS_UNICODE_r33 1065 -#define _GUARD_NOT_EXHAUSTED_LIST_r02 1066 -#define _GUARD_NOT_EXHAUSTED_LIST_r12 1067 -#define _GUARD_NOT_EXHAUSTED_LIST_r22 1068 -#define _GUARD_NOT_EXHAUSTED_LIST_r33 1069 -#define _GUARD_NOT_EXHAUSTED_RANGE_r02 1070 -#define _GUARD_NOT_EXHAUSTED_RANGE_r12 1071 -#define _GUARD_NOT_EXHAUSTED_RANGE_r22 1072 -#define _GUARD_NOT_EXHAUSTED_RANGE_r33 1073 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 1074 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 1075 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 1076 -#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 1077 -#define _GUARD_THIRD_NULL_r03 1078 -#define _GUARD_THIRD_NULL_r13 1079 -#define _GUARD_THIRD_NULL_r23 1080 -#define _GUARD_THIRD_NULL_r33 1081 -#define _GUARD_TOS_ANY_DICT_r01 1082 -#define _GUARD_TOS_ANY_DICT_r11 1083 -#define _GUARD_TOS_ANY_DICT_r22 1084 -#define _GUARD_TOS_ANY_DICT_r33 1085 -#define _GUARD_TOS_ANY_SET_r01 1086 -#define _GUARD_TOS_ANY_SET_r11 1087 -#define _GUARD_TOS_ANY_SET_r22 1088 -#define _GUARD_TOS_ANY_SET_r33 1089 -#define _GUARD_TOS_DICT_r01 1090 -#define _GUARD_TOS_DICT_r11 1091 -#define _GUARD_TOS_DICT_r22 1092 -#define _GUARD_TOS_DICT_r33 1093 -#define _GUARD_TOS_FLOAT_r01 1094 -#define _GUARD_TOS_FLOAT_r11 1095 -#define _GUARD_TOS_FLOAT_r22 1096 -#define _GUARD_TOS_FLOAT_r33 1097 -#define _GUARD_TOS_FROZENDICT_r01 1098 -#define _GUARD_TOS_FROZENDICT_r11 1099 -#define _GUARD_TOS_FROZENDICT_r22 1100 -#define _GUARD_TOS_FROZENDICT_r33 1101 -#define _GUARD_TOS_FROZENSET_r01 1102 -#define _GUARD_TOS_FROZENSET_r11 1103 -#define _GUARD_TOS_FROZENSET_r22 1104 -#define _GUARD_TOS_FROZENSET_r33 1105 -#define _GUARD_TOS_INT_r01 1106 -#define _GUARD_TOS_INT_r11 1107 -#define _GUARD_TOS_INT_r22 1108 -#define _GUARD_TOS_INT_r33 1109 -#define _GUARD_TOS_LIST_r01 1110 -#define _GUARD_TOS_LIST_r11 1111 -#define _GUARD_TOS_LIST_r22 1112 -#define _GUARD_TOS_LIST_r33 1113 -#define _GUARD_TOS_OVERFLOWED_r01 1114 -#define _GUARD_TOS_OVERFLOWED_r11 1115 -#define _GUARD_TOS_OVERFLOWED_r22 1116 -#define _GUARD_TOS_OVERFLOWED_r33 1117 -#define _GUARD_TOS_SET_r01 1118 -#define _GUARD_TOS_SET_r11 1119 -#define _GUARD_TOS_SET_r22 1120 -#define _GUARD_TOS_SET_r33 1121 -#define _GUARD_TOS_SLICE_r01 1122 -#define _GUARD_TOS_SLICE_r11 1123 -#define _GUARD_TOS_SLICE_r22 1124 -#define _GUARD_TOS_SLICE_r33 1125 -#define _GUARD_TOS_TUPLE_r01 1126 -#define _GUARD_TOS_TUPLE_r11 1127 -#define _GUARD_TOS_TUPLE_r22 1128 -#define _GUARD_TOS_TUPLE_r33 1129 -#define _GUARD_TOS_UNICODE_r01 1130 -#define _GUARD_TOS_UNICODE_r11 1131 -#define _GUARD_TOS_UNICODE_r22 1132 -#define _GUARD_TOS_UNICODE_r33 1133 -#define _GUARD_TYPE_VERSION_r01 1134 -#define _GUARD_TYPE_VERSION_r11 1135 -#define _GUARD_TYPE_VERSION_r22 1136 -#define _GUARD_TYPE_VERSION_r33 1137 -#define _GUARD_TYPE_VERSION_LOCKED_r01 1138 -#define _GUARD_TYPE_VERSION_LOCKED_r11 1139 -#define _GUARD_TYPE_VERSION_LOCKED_r22 1140 -#define _GUARD_TYPE_VERSION_LOCKED_r33 1141 -#define _HANDLE_PENDING_AND_DEOPT_r00 1142 -#define _HANDLE_PENDING_AND_DEOPT_r10 1143 -#define _HANDLE_PENDING_AND_DEOPT_r20 1144 -#define _HANDLE_PENDING_AND_DEOPT_r30 1145 -#define _IMPORT_FROM_r12 1146 -#define _IMPORT_NAME_r21 1147 -#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1148 -#define _INIT_CALL_PY_EXACT_ARGS_r01 1149 -#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1150 -#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1151 -#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1152 -#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1153 -#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1154 -#define _INSERT_NULL_r10 1155 -#define _INSTRUMENTED_FOR_ITER_r23 1156 -#define _INSTRUMENTED_INSTRUCTION_r00 1157 -#define _INSTRUMENTED_JUMP_FORWARD_r00 1158 -#define _INSTRUMENTED_JUMP_FORWARD_r11 1159 -#define _INSTRUMENTED_JUMP_FORWARD_r22 1160 -#define _INSTRUMENTED_JUMP_FORWARD_r33 1161 -#define _INSTRUMENTED_LINE_r00 1162 -#define _INSTRUMENTED_NOT_TAKEN_r00 1163 -#define _INSTRUMENTED_NOT_TAKEN_r11 1164 -#define _INSTRUMENTED_NOT_TAKEN_r22 1165 -#define _INSTRUMENTED_NOT_TAKEN_r33 1166 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1167 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1168 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1169 -#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1170 -#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1171 -#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1172 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1173 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1174 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1175 -#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1176 -#define _IS_NONE_r11 1177 -#define _IS_OP_r03 1178 -#define _IS_OP_r13 1179 -#define _IS_OP_r23 1180 -#define _ITER_CHECK_LIST_r02 1181 -#define _ITER_CHECK_LIST_r12 1182 -#define _ITER_CHECK_LIST_r22 1183 -#define _ITER_CHECK_LIST_r33 1184 -#define _ITER_CHECK_RANGE_r02 1185 -#define _ITER_CHECK_RANGE_r12 1186 -#define _ITER_CHECK_RANGE_r22 1187 -#define _ITER_CHECK_RANGE_r33 1188 -#define _ITER_CHECK_TUPLE_r02 1189 -#define _ITER_CHECK_TUPLE_r12 1190 -#define _ITER_CHECK_TUPLE_r22 1191 -#define _ITER_CHECK_TUPLE_r33 1192 -#define _ITER_JUMP_LIST_r02 1193 -#define _ITER_JUMP_LIST_r12 1194 -#define _ITER_JUMP_LIST_r22 1195 -#define _ITER_JUMP_LIST_r33 1196 -#define _ITER_JUMP_RANGE_r02 1197 -#define _ITER_JUMP_RANGE_r12 1198 -#define _ITER_JUMP_RANGE_r22 1199 -#define _ITER_JUMP_RANGE_r33 1200 -#define _ITER_JUMP_TUPLE_r02 1201 -#define _ITER_JUMP_TUPLE_r12 1202 -#define _ITER_JUMP_TUPLE_r22 1203 -#define _ITER_JUMP_TUPLE_r33 1204 -#define _ITER_NEXT_LIST_r23 1205 -#define _ITER_NEXT_LIST_TIER_TWO_r23 1206 -#define _ITER_NEXT_RANGE_r03 1207 -#define _ITER_NEXT_RANGE_r13 1208 -#define _ITER_NEXT_RANGE_r23 1209 -#define _ITER_NEXT_TUPLE_r03 1210 -#define _ITER_NEXT_TUPLE_r13 1211 -#define _ITER_NEXT_TUPLE_r23 1212 -#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1213 -#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1214 -#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1215 -#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1216 -#define _JUMP_TO_TOP_r00 1217 -#define _LIST_APPEND_r10 1218 -#define _LIST_EXTEND_r11 1219 -#define _LOAD_ATTR_r10 1220 -#define _LOAD_ATTR_CLASS_r11 1221 -#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_r11 1222 -#define _LOAD_ATTR_INSTANCE_VALUE_r02 1223 -#define _LOAD_ATTR_INSTANCE_VALUE_r12 1224 -#define _LOAD_ATTR_INSTANCE_VALUE_r23 1225 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1226 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1227 -#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1228 -#define _LOAD_ATTR_METHOD_NO_DICT_r02 1229 -#define _LOAD_ATTR_METHOD_NO_DICT_r12 1230 -#define _LOAD_ATTR_METHOD_NO_DICT_r23 1231 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1232 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1233 -#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1234 -#define _LOAD_ATTR_MODULE_r12 1235 -#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1236 -#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1237 -#define _LOAD_ATTR_PROPERTY_FRAME_r01 1238 -#define _LOAD_ATTR_PROPERTY_FRAME_r11 1239 -#define _LOAD_ATTR_PROPERTY_FRAME_r22 1240 -#define _LOAD_ATTR_PROPERTY_FRAME_r33 1241 -#define _LOAD_ATTR_SLOT_r02 1242 -#define _LOAD_ATTR_SLOT_r12 1243 -#define _LOAD_ATTR_SLOT_r23 1244 -#define _LOAD_ATTR_WITH_HINT_r12 1245 -#define _LOAD_BUILD_CLASS_r01 1246 -#define _LOAD_BYTECODE_r00 1247 -#define _LOAD_COMMON_CONSTANT_r01 1248 -#define _LOAD_COMMON_CONSTANT_r12 1249 -#define _LOAD_COMMON_CONSTANT_r23 1250 -#define _LOAD_CONST_r01 1251 -#define _LOAD_CONST_r12 1252 -#define _LOAD_CONST_r23 1253 -#define _LOAD_CONST_INLINE_r01 1254 -#define _LOAD_CONST_INLINE_r12 1255 -#define _LOAD_CONST_INLINE_r23 1256 -#define _LOAD_CONST_INLINE_BORROW_r01 1257 -#define _LOAD_CONST_INLINE_BORROW_r12 1258 -#define _LOAD_CONST_INLINE_BORROW_r23 1259 -#define _LOAD_DEREF_r01 1260 -#define _LOAD_FAST_r01 1261 -#define _LOAD_FAST_r12 1262 -#define _LOAD_FAST_r23 1263 -#define _LOAD_FAST_0_r01 1264 -#define _LOAD_FAST_0_r12 1265 -#define _LOAD_FAST_0_r23 1266 -#define _LOAD_FAST_1_r01 1267 -#define _LOAD_FAST_1_r12 1268 -#define _LOAD_FAST_1_r23 1269 -#define _LOAD_FAST_2_r01 1270 -#define _LOAD_FAST_2_r12 1271 -#define _LOAD_FAST_2_r23 1272 -#define _LOAD_FAST_3_r01 1273 -#define _LOAD_FAST_3_r12 1274 -#define _LOAD_FAST_3_r23 1275 -#define _LOAD_FAST_4_r01 1276 -#define _LOAD_FAST_4_r12 1277 -#define _LOAD_FAST_4_r23 1278 -#define _LOAD_FAST_5_r01 1279 -#define _LOAD_FAST_5_r12 1280 -#define _LOAD_FAST_5_r23 1281 -#define _LOAD_FAST_6_r01 1282 -#define _LOAD_FAST_6_r12 1283 -#define _LOAD_FAST_6_r23 1284 -#define _LOAD_FAST_7_r01 1285 -#define _LOAD_FAST_7_r12 1286 -#define _LOAD_FAST_7_r23 1287 -#define _LOAD_FAST_AND_CLEAR_r01 1288 -#define _LOAD_FAST_AND_CLEAR_r12 1289 -#define _LOAD_FAST_AND_CLEAR_r23 1290 -#define _LOAD_FAST_BORROW_r01 1291 -#define _LOAD_FAST_BORROW_r12 1292 -#define _LOAD_FAST_BORROW_r23 1293 -#define _LOAD_FAST_BORROW_0_r01 1294 -#define _LOAD_FAST_BORROW_0_r12 1295 -#define _LOAD_FAST_BORROW_0_r23 1296 -#define _LOAD_FAST_BORROW_1_r01 1297 -#define _LOAD_FAST_BORROW_1_r12 1298 -#define _LOAD_FAST_BORROW_1_r23 1299 -#define _LOAD_FAST_BORROW_2_r01 1300 -#define _LOAD_FAST_BORROW_2_r12 1301 -#define _LOAD_FAST_BORROW_2_r23 1302 -#define _LOAD_FAST_BORROW_3_r01 1303 -#define _LOAD_FAST_BORROW_3_r12 1304 -#define _LOAD_FAST_BORROW_3_r23 1305 -#define _LOAD_FAST_BORROW_4_r01 1306 -#define _LOAD_FAST_BORROW_4_r12 1307 -#define _LOAD_FAST_BORROW_4_r23 1308 -#define _LOAD_FAST_BORROW_5_r01 1309 -#define _LOAD_FAST_BORROW_5_r12 1310 -#define _LOAD_FAST_BORROW_5_r23 1311 -#define _LOAD_FAST_BORROW_6_r01 1312 -#define _LOAD_FAST_BORROW_6_r12 1313 -#define _LOAD_FAST_BORROW_6_r23 1314 -#define _LOAD_FAST_BORROW_7_r01 1315 -#define _LOAD_FAST_BORROW_7_r12 1316 -#define _LOAD_FAST_BORROW_7_r23 1317 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1318 -#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1319 -#define _LOAD_FAST_CHECK_r01 1320 -#define _LOAD_FAST_CHECK_r12 1321 -#define _LOAD_FAST_CHECK_r23 1322 -#define _LOAD_FAST_LOAD_FAST_r02 1323 -#define _LOAD_FAST_LOAD_FAST_r13 1324 -#define _LOAD_FROM_DICT_OR_DEREF_r11 1325 -#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1326 -#define _LOAD_GLOBAL_r00 1327 -#define _LOAD_GLOBAL_BUILTINS_r01 1328 -#define _LOAD_GLOBAL_MODULE_r01 1329 -#define _LOAD_LOCALS_r01 1330 -#define _LOAD_LOCALS_r12 1331 -#define _LOAD_LOCALS_r23 1332 -#define _LOAD_NAME_r01 1333 -#define _LOAD_SMALL_INT_r01 1334 -#define _LOAD_SMALL_INT_r12 1335 -#define _LOAD_SMALL_INT_r23 1336 -#define _LOAD_SMALL_INT_0_r01 1337 -#define _LOAD_SMALL_INT_0_r12 1338 -#define _LOAD_SMALL_INT_0_r23 1339 -#define _LOAD_SMALL_INT_1_r01 1340 -#define _LOAD_SMALL_INT_1_r12 1341 -#define _LOAD_SMALL_INT_1_r23 1342 -#define _LOAD_SMALL_INT_2_r01 1343 -#define _LOAD_SMALL_INT_2_r12 1344 -#define _LOAD_SMALL_INT_2_r23 1345 -#define _LOAD_SMALL_INT_3_r01 1346 -#define _LOAD_SMALL_INT_3_r12 1347 -#define _LOAD_SMALL_INT_3_r23 1348 -#define _LOAD_SPECIAL_r00 1349 -#define _LOAD_SUPER_ATTR_ATTR_r31 1350 -#define _LOAD_SUPER_ATTR_METHOD_r32 1351 -#define _LOCK_OBJECT_r01 1352 -#define _LOCK_OBJECT_r11 1353 -#define _LOCK_OBJECT_r22 1354 -#define _LOCK_OBJECT_r33 1355 -#define _MAKE_CALLARGS_A_TUPLE_r33 1356 -#define _MAKE_CELL_r00 1357 -#define _MAKE_FUNCTION_r12 1358 -#define _MAKE_HEAP_SAFE_r01 1359 -#define _MAKE_HEAP_SAFE_r11 1360 -#define _MAKE_HEAP_SAFE_r22 1361 -#define _MAKE_HEAP_SAFE_r33 1362 -#define _MAKE_WARM_r00 1363 -#define _MAKE_WARM_r11 1364 -#define _MAKE_WARM_r22 1365 -#define _MAKE_WARM_r33 1366 -#define _MAP_ADD_r20 1367 -#define _MATCH_CLASS_r33 1368 -#define _MATCH_KEYS_r23 1369 -#define _MATCH_MAPPING_r02 1370 -#define _MATCH_MAPPING_r12 1371 -#define _MATCH_MAPPING_r23 1372 -#define _MATCH_SEQUENCE_r02 1373 -#define _MATCH_SEQUENCE_r12 1374 -#define _MATCH_SEQUENCE_r23 1375 -#define _MAYBE_EXPAND_METHOD_r00 1376 -#define _MAYBE_EXPAND_METHOD_KW_r11 1377 -#define _MONITOR_CALL_r00 1378 -#define _MONITOR_CALL_KW_r11 1379 -#define _MONITOR_JUMP_BACKWARD_r00 1380 -#define _MONITOR_JUMP_BACKWARD_r11 1381 -#define _MONITOR_JUMP_BACKWARD_r22 1382 -#define _MONITOR_JUMP_BACKWARD_r33 1383 -#define _MONITOR_RESUME_r00 1384 -#define _NOP_r00 1385 -#define _NOP_r11 1386 -#define _NOP_r22 1387 -#define _NOP_r33 1388 -#define _POP_EXCEPT_r10 1389 -#define _POP_ITER_r20 1390 -#define _POP_JUMP_IF_FALSE_r00 1391 -#define _POP_JUMP_IF_FALSE_r10 1392 -#define _POP_JUMP_IF_FALSE_r21 1393 -#define _POP_JUMP_IF_FALSE_r32 1394 -#define _POP_JUMP_IF_TRUE_r00 1395 -#define _POP_JUMP_IF_TRUE_r10 1396 -#define _POP_JUMP_IF_TRUE_r21 1397 -#define _POP_JUMP_IF_TRUE_r32 1398 -#define _POP_TOP_r10 1399 -#define _POP_TOP_FLOAT_r00 1400 -#define _POP_TOP_FLOAT_r10 1401 -#define _POP_TOP_FLOAT_r21 1402 -#define _POP_TOP_FLOAT_r32 1403 -#define _POP_TOP_INT_r00 1404 -#define _POP_TOP_INT_r10 1405 -#define _POP_TOP_INT_r21 1406 -#define _POP_TOP_INT_r32 1407 -#define _POP_TOP_NOP_r00 1408 -#define _POP_TOP_NOP_r10 1409 -#define _POP_TOP_NOP_r21 1410 -#define _POP_TOP_NOP_r32 1411 -#define _POP_TOP_OPARG_r00 1412 -#define _POP_TOP_UNICODE_r00 1413 -#define _POP_TOP_UNICODE_r10 1414 -#define _POP_TOP_UNICODE_r21 1415 -#define _POP_TOP_UNICODE_r32 1416 -#define _PUSH_EXC_INFO_r02 1417 -#define _PUSH_EXC_INFO_r12 1418 -#define _PUSH_EXC_INFO_r23 1419 -#define _PUSH_FRAME_r10 1420 -#define _PUSH_NULL_r01 1421 -#define _PUSH_NULL_r12 1422 -#define _PUSH_NULL_r23 1423 -#define _PUSH_NULL_CONDITIONAL_r00 1424 -#define _PY_FRAME_EX_r31 1425 -#define _PY_FRAME_GENERAL_r01 1426 -#define _PY_FRAME_KW_r11 1427 -#define _REPLACE_WITH_TRUE_r02 1428 -#define _REPLACE_WITH_TRUE_r12 1429 -#define _REPLACE_WITH_TRUE_r23 1430 -#define _RESUME_CHECK_r00 1431 -#define _RESUME_CHECK_r11 1432 -#define _RESUME_CHECK_r22 1433 -#define _RESUME_CHECK_r33 1434 -#define _RETURN_GENERATOR_r01 1435 -#define _RETURN_VALUE_r11 1436 -#define _SAVE_RETURN_OFFSET_r00 1437 -#define _SAVE_RETURN_OFFSET_r11 1438 -#define _SAVE_RETURN_OFFSET_r22 1439 -#define _SAVE_RETURN_OFFSET_r33 1440 -#define _SEND_r33 1441 -#define _SEND_GEN_FRAME_r33 1442 -#define _SETUP_ANNOTATIONS_r00 1443 -#define _SET_ADD_r10 1444 -#define _SET_FUNCTION_ATTRIBUTE_r01 1445 -#define _SET_FUNCTION_ATTRIBUTE_r11 1446 -#define _SET_FUNCTION_ATTRIBUTE_r21 1447 -#define _SET_FUNCTION_ATTRIBUTE_r32 1448 -#define _SET_IP_r00 1449 -#define _SET_IP_r11 1450 -#define _SET_IP_r22 1451 -#define _SET_IP_r33 1452 -#define _SET_UPDATE_r11 1453 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1454 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1455 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1456 -#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1457 -#define _SPILL_OR_RELOAD_r01 1458 -#define _SPILL_OR_RELOAD_r02 1459 -#define _SPILL_OR_RELOAD_r03 1460 -#define _SPILL_OR_RELOAD_r10 1461 -#define _SPILL_OR_RELOAD_r12 1462 -#define _SPILL_OR_RELOAD_r13 1463 -#define _SPILL_OR_RELOAD_r20 1464 -#define _SPILL_OR_RELOAD_r21 1465 -#define _SPILL_OR_RELOAD_r23 1466 -#define _SPILL_OR_RELOAD_r30 1467 -#define _SPILL_OR_RELOAD_r31 1468 -#define _SPILL_OR_RELOAD_r32 1469 -#define _START_EXECUTOR_r00 1470 -#define _STORE_ATTR_r20 1471 -#define _STORE_ATTR_INSTANCE_VALUE_r21 1472 -#define _STORE_ATTR_SLOT_r21 1473 -#define _STORE_ATTR_WITH_HINT_r21 1474 -#define _STORE_DEREF_r10 1475 -#define _STORE_FAST_LOAD_FAST_r11 1476 -#define _STORE_FAST_STORE_FAST_r20 1477 -#define _STORE_GLOBAL_r10 1478 -#define _STORE_NAME_r10 1479 -#define _STORE_SLICE_r30 1480 -#define _STORE_SUBSCR_r30 1481 -#define _STORE_SUBSCR_DICT_r31 1482 -#define _STORE_SUBSCR_DICT_KNOWN_HASH_r31 1483 -#define _STORE_SUBSCR_LIST_INT_r32 1484 -#define _SWAP_r11 1485 -#define _SWAP_2_r02 1486 -#define _SWAP_2_r12 1487 -#define _SWAP_2_r22 1488 -#define _SWAP_2_r33 1489 -#define _SWAP_3_r03 1490 -#define _SWAP_3_r13 1491 -#define _SWAP_3_r23 1492 -#define _SWAP_3_r33 1493 -#define _SWAP_FAST_r01 1494 -#define _SWAP_FAST_r11 1495 -#define _SWAP_FAST_r22 1496 -#define _SWAP_FAST_r33 1497 -#define _SWAP_FAST_0_r01 1498 -#define _SWAP_FAST_0_r11 1499 -#define _SWAP_FAST_0_r22 1500 -#define _SWAP_FAST_0_r33 1501 -#define _SWAP_FAST_1_r01 1502 -#define _SWAP_FAST_1_r11 1503 -#define _SWAP_FAST_1_r22 1504 -#define _SWAP_FAST_1_r33 1505 -#define _SWAP_FAST_2_r01 1506 -#define _SWAP_FAST_2_r11 1507 -#define _SWAP_FAST_2_r22 1508 -#define _SWAP_FAST_2_r33 1509 -#define _SWAP_FAST_3_r01 1510 -#define _SWAP_FAST_3_r11 1511 -#define _SWAP_FAST_3_r22 1512 -#define _SWAP_FAST_3_r33 1513 -#define _SWAP_FAST_4_r01 1514 -#define _SWAP_FAST_4_r11 1515 -#define _SWAP_FAST_4_r22 1516 -#define _SWAP_FAST_4_r33 1517 -#define _SWAP_FAST_5_r01 1518 -#define _SWAP_FAST_5_r11 1519 -#define _SWAP_FAST_5_r22 1520 -#define _SWAP_FAST_5_r33 1521 -#define _SWAP_FAST_6_r01 1522 -#define _SWAP_FAST_6_r11 1523 -#define _SWAP_FAST_6_r22 1524 -#define _SWAP_FAST_6_r33 1525 -#define _SWAP_FAST_7_r01 1526 -#define _SWAP_FAST_7_r11 1527 -#define _SWAP_FAST_7_r22 1528 -#define _SWAP_FAST_7_r33 1529 -#define _TIER2_RESUME_CHECK_r00 1530 -#define _TIER2_RESUME_CHECK_r11 1531 -#define _TIER2_RESUME_CHECK_r22 1532 -#define _TIER2_RESUME_CHECK_r33 1533 -#define _TO_BOOL_r11 1534 -#define _TO_BOOL_BOOL_r01 1535 -#define _TO_BOOL_BOOL_r11 1536 -#define _TO_BOOL_BOOL_r22 1537 -#define _TO_BOOL_BOOL_r33 1538 -#define _TO_BOOL_INT_r02 1539 -#define _TO_BOOL_INT_r12 1540 -#define _TO_BOOL_INT_r23 1541 -#define _TO_BOOL_LIST_r02 1542 -#define _TO_BOOL_LIST_r12 1543 -#define _TO_BOOL_LIST_r23 1544 -#define _TO_BOOL_NONE_r01 1545 -#define _TO_BOOL_NONE_r11 1546 -#define _TO_BOOL_NONE_r22 1547 -#define _TO_BOOL_NONE_r33 1548 -#define _TO_BOOL_STR_r02 1549 -#define _TO_BOOL_STR_r12 1550 -#define _TO_BOOL_STR_r23 1551 -#define _TRACE_RECORD_r00 1552 -#define _UNARY_INVERT_r12 1553 -#define _UNARY_NEGATIVE_r12 1554 -#define _UNARY_NEGATIVE_FLOAT_INPLACE_r02 1555 -#define _UNARY_NEGATIVE_FLOAT_INPLACE_r12 1556 -#define _UNARY_NEGATIVE_FLOAT_INPLACE_r23 1557 -#define _UNARY_NOT_r01 1558 -#define _UNARY_NOT_r11 1559 -#define _UNARY_NOT_r22 1560 -#define _UNARY_NOT_r33 1561 -#define _UNPACK_EX_r10 1562 -#define _UNPACK_SEQUENCE_r10 1563 -#define _UNPACK_SEQUENCE_LIST_r10 1564 -#define _UNPACK_SEQUENCE_TUPLE_r10 1565 -#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1566 -#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE_r03 1567 -#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE_r13 1568 -#define _UNPACK_SEQUENCE_UNIQUE_TUPLE_r10 1569 -#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r02 1570 -#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r12 1571 -#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r23 1572 -#define _WITH_EXCEPT_START_r33 1573 -#define _YIELD_VALUE_r11 1574 -#define MAX_UOP_REGS_ID 1574 +#define _YIELD_VALUE 631 +#define MAX_UOP_ID 631 +#define _ALLOCATE_OBJECT_r00 632 +#define _BINARY_OP_r23 633 +#define _BINARY_OP_ADD_FLOAT_r03 634 +#define _BINARY_OP_ADD_FLOAT_r13 635 +#define _BINARY_OP_ADD_FLOAT_r23 636 +#define _BINARY_OP_ADD_FLOAT_INPLACE_r03 637 +#define _BINARY_OP_ADD_FLOAT_INPLACE_r13 638 +#define _BINARY_OP_ADD_FLOAT_INPLACE_r23 639 +#define _BINARY_OP_ADD_FLOAT_INPLACE_RIGHT_r03 640 +#define _BINARY_OP_ADD_FLOAT_INPLACE_RIGHT_r13 641 +#define _BINARY_OP_ADD_FLOAT_INPLACE_RIGHT_r23 642 +#define _BINARY_OP_ADD_INT_r03 643 +#define _BINARY_OP_ADD_INT_r13 644 +#define _BINARY_OP_ADD_INT_r23 645 +#define _BINARY_OP_ADD_INT_INPLACE_r03 646 +#define _BINARY_OP_ADD_INT_INPLACE_r13 647 +#define _BINARY_OP_ADD_INT_INPLACE_r23 648 +#define _BINARY_OP_ADD_INT_INPLACE_RIGHT_r03 649 +#define _BINARY_OP_ADD_INT_INPLACE_RIGHT_r13 650 +#define _BINARY_OP_ADD_INT_INPLACE_RIGHT_r23 651 +#define _BINARY_OP_ADD_UNICODE_r03 652 +#define _BINARY_OP_ADD_UNICODE_r13 653 +#define _BINARY_OP_ADD_UNICODE_r23 654 +#define _BINARY_OP_EXTEND_r23 655 +#define _BINARY_OP_INPLACE_ADD_UNICODE_r21 656 +#define _BINARY_OP_MULTIPLY_FLOAT_r03 657 +#define _BINARY_OP_MULTIPLY_FLOAT_r13 658 +#define _BINARY_OP_MULTIPLY_FLOAT_r23 659 +#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_r03 660 +#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_r13 661 +#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_r23 662 +#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_RIGHT_r03 663 +#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_RIGHT_r13 664 +#define _BINARY_OP_MULTIPLY_FLOAT_INPLACE_RIGHT_r23 665 +#define _BINARY_OP_MULTIPLY_INT_r03 666 +#define _BINARY_OP_MULTIPLY_INT_r13 667 +#define _BINARY_OP_MULTIPLY_INT_r23 668 +#define _BINARY_OP_MULTIPLY_INT_INPLACE_r03 669 +#define _BINARY_OP_MULTIPLY_INT_INPLACE_r13 670 +#define _BINARY_OP_MULTIPLY_INT_INPLACE_r23 671 +#define _BINARY_OP_MULTIPLY_INT_INPLACE_RIGHT_r03 672 +#define _BINARY_OP_MULTIPLY_INT_INPLACE_RIGHT_r13 673 +#define _BINARY_OP_MULTIPLY_INT_INPLACE_RIGHT_r23 674 +#define _BINARY_OP_SUBSCR_CHECK_FUNC_r23 675 +#define _BINARY_OP_SUBSCR_DICT_r23 676 +#define _BINARY_OP_SUBSCR_DICT_KNOWN_HASH_r23 677 +#define _BINARY_OP_SUBSCR_INIT_CALL_r01 678 +#define _BINARY_OP_SUBSCR_INIT_CALL_r11 679 +#define _BINARY_OP_SUBSCR_INIT_CALL_r21 680 +#define _BINARY_OP_SUBSCR_INIT_CALL_r31 681 +#define _BINARY_OP_SUBSCR_LIST_INT_r23 682 +#define _BINARY_OP_SUBSCR_LIST_SLICE_r23 683 +#define _BINARY_OP_SUBSCR_STR_INT_r23 684 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r03 685 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r13 686 +#define _BINARY_OP_SUBSCR_TUPLE_INT_r23 687 +#define _BINARY_OP_SUBSCR_USTR_INT_r23 688 +#define _BINARY_OP_SUBTRACT_FLOAT_r03 689 +#define _BINARY_OP_SUBTRACT_FLOAT_r13 690 +#define _BINARY_OP_SUBTRACT_FLOAT_r23 691 +#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_r03 692 +#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_r13 693 +#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_r23 694 +#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_RIGHT_r03 695 +#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_RIGHT_r13 696 +#define _BINARY_OP_SUBTRACT_FLOAT_INPLACE_RIGHT_r23 697 +#define _BINARY_OP_SUBTRACT_INT_r03 698 +#define _BINARY_OP_SUBTRACT_INT_r13 699 +#define _BINARY_OP_SUBTRACT_INT_r23 700 +#define _BINARY_OP_SUBTRACT_INT_INPLACE_r03 701 +#define _BINARY_OP_SUBTRACT_INT_INPLACE_r13 702 +#define _BINARY_OP_SUBTRACT_INT_INPLACE_r23 703 +#define _BINARY_OP_SUBTRACT_INT_INPLACE_RIGHT_r03 704 +#define _BINARY_OP_SUBTRACT_INT_INPLACE_RIGHT_r13 705 +#define _BINARY_OP_SUBTRACT_INT_INPLACE_RIGHT_r23 706 +#define _BINARY_SLICE_r31 707 +#define _BUILD_INTERPOLATION_r01 708 +#define _BUILD_LIST_r01 709 +#define _BUILD_MAP_r01 710 +#define _BUILD_SET_r01 711 +#define _BUILD_SLICE_r01 712 +#define _BUILD_STRING_r01 713 +#define _BUILD_TEMPLATE_r21 714 +#define _BUILD_TUPLE_r01 715 +#define _CALL_BUILTIN_CLASS_r00 716 +#define _CALL_BUILTIN_FAST_r00 717 +#define _CALL_BUILTIN_FAST_WITH_KEYWORDS_r00 718 +#define _CALL_BUILTIN_O_r03 719 +#define _CALL_FUNCTION_EX_NON_PY_GENERAL_r31 720 +#define _CALL_INTRINSIC_1_r12 721 +#define _CALL_INTRINSIC_2_r23 722 +#define _CALL_ISINSTANCE_r31 723 +#define _CALL_KW_NON_PY_r11 724 +#define _CALL_LEN_r33 725 +#define _CALL_LIST_APPEND_r03 726 +#define _CALL_LIST_APPEND_r13 727 +#define _CALL_LIST_APPEND_r23 728 +#define _CALL_LIST_APPEND_r33 729 +#define _CALL_METHOD_DESCRIPTOR_FAST_r00 730 +#define _CALL_METHOD_DESCRIPTOR_FAST_INLINE_r00 731 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r00 732 +#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_INLINE_r00 733 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_r03 734 +#define _CALL_METHOD_DESCRIPTOR_NOARGS_INLINE_r03 735 +#define _CALL_METHOD_DESCRIPTOR_O_r03 736 +#define _CALL_METHOD_DESCRIPTOR_O_INLINE_r03 737 +#define _CALL_NON_PY_GENERAL_r01 738 +#define _CALL_STR_1_r32 739 +#define _CALL_TUPLE_1_r32 740 +#define _CALL_TYPE_1_r02 741 +#define _CALL_TYPE_1_r12 742 +#define _CALL_TYPE_1_r22 743 +#define _CALL_TYPE_1_r32 744 +#define _CHECK_ATTR_CLASS_r01 745 +#define _CHECK_ATTR_CLASS_r11 746 +#define _CHECK_ATTR_CLASS_r22 747 +#define _CHECK_ATTR_CLASS_r33 748 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r01 749 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r11 750 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r22 751 +#define _CHECK_ATTR_METHOD_LAZY_DICT_r33 752 +#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS_r00 753 +#define _CHECK_EG_MATCH_r22 754 +#define _CHECK_EXC_MATCH_r22 755 +#define _CHECK_FUNCTION_EXACT_ARGS_r00 756 +#define _CHECK_FUNCTION_VERSION_r00 757 +#define _CHECK_FUNCTION_VERSION_INLINE_r00 758 +#define _CHECK_FUNCTION_VERSION_INLINE_r11 759 +#define _CHECK_FUNCTION_VERSION_INLINE_r22 760 +#define _CHECK_FUNCTION_VERSION_INLINE_r33 761 +#define _CHECK_FUNCTION_VERSION_KW_r11 762 +#define _CHECK_IS_NOT_PY_CALLABLE_r00 763 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r03 764 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r13 765 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r23 766 +#define _CHECK_IS_NOT_PY_CALLABLE_EX_r33 767 +#define _CHECK_IS_NOT_PY_CALLABLE_KW_r11 768 +#define _CHECK_IS_PY_CALLABLE_EX_r03 769 +#define _CHECK_IS_PY_CALLABLE_EX_r13 770 +#define _CHECK_IS_PY_CALLABLE_EX_r23 771 +#define _CHECK_IS_PY_CALLABLE_EX_r33 772 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r01 773 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r11 774 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r22 775 +#define _CHECK_MANAGED_OBJECT_HAS_VALUES_r33 776 +#define _CHECK_METHOD_VERSION_r00 777 +#define _CHECK_METHOD_VERSION_KW_r11 778 +#define _CHECK_OBJECT_r00 779 +#define _CHECK_PEP_523_r00 780 +#define _CHECK_PEP_523_r11 781 +#define _CHECK_PEP_523_r22 782 +#define _CHECK_PEP_523_r33 783 +#define _CHECK_PERIODIC_r00 784 +#define _CHECK_PERIODIC_AT_END_r00 785 +#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM_r00 786 +#define _CHECK_RECURSION_LIMIT_r00 787 +#define _CHECK_RECURSION_LIMIT_r11 788 +#define _CHECK_RECURSION_LIMIT_r22 789 +#define _CHECK_RECURSION_LIMIT_r33 790 +#define _CHECK_RECURSION_REMAINING_r00 791 +#define _CHECK_RECURSION_REMAINING_r11 792 +#define _CHECK_RECURSION_REMAINING_r22 793 +#define _CHECK_RECURSION_REMAINING_r33 794 +#define _CHECK_STACK_SPACE_r00 795 +#define _CHECK_STACK_SPACE_OPERAND_r00 796 +#define _CHECK_STACK_SPACE_OPERAND_r11 797 +#define _CHECK_STACK_SPACE_OPERAND_r22 798 +#define _CHECK_STACK_SPACE_OPERAND_r33 799 +#define _CHECK_VALIDITY_r00 800 +#define _CHECK_VALIDITY_r11 801 +#define _CHECK_VALIDITY_r22 802 +#define _CHECK_VALIDITY_r33 803 +#define _COLD_DYNAMIC_EXIT_r00 804 +#define _COLD_EXIT_r00 805 +#define _COMPARE_OP_r21 806 +#define _COMPARE_OP_FLOAT_r03 807 +#define _COMPARE_OP_FLOAT_r13 808 +#define _COMPARE_OP_FLOAT_r23 809 +#define _COMPARE_OP_INT_r23 810 +#define _COMPARE_OP_STR_r23 811 +#define _CONTAINS_OP_r23 812 +#define _CONTAINS_OP_DICT_r23 813 +#define _CONTAINS_OP_SET_r23 814 +#define _CONVERT_VALUE_r11 815 +#define _COPY_r01 816 +#define _COPY_1_r02 817 +#define _COPY_1_r12 818 +#define _COPY_1_r23 819 +#define _COPY_2_r03 820 +#define _COPY_2_r13 821 +#define _COPY_2_r23 822 +#define _COPY_3_r03 823 +#define _COPY_3_r13 824 +#define _COPY_3_r23 825 +#define _COPY_3_r33 826 +#define _COPY_FREE_VARS_r00 827 +#define _COPY_FREE_VARS_r11 828 +#define _COPY_FREE_VARS_r22 829 +#define _COPY_FREE_VARS_r33 830 +#define _CREATE_INIT_FRAME_r01 831 +#define _DELETE_ATTR_r10 832 +#define _DELETE_DEREF_r00 833 +#define _DELETE_FAST_r00 834 +#define _DELETE_GLOBAL_r00 835 +#define _DELETE_NAME_r00 836 +#define _DELETE_SUBSCR_r20 837 +#define _DEOPT_r00 838 +#define _DEOPT_r10 839 +#define _DEOPT_r20 840 +#define _DEOPT_r30 841 +#define _DICT_MERGE_r11 842 +#define _DICT_UPDATE_r11 843 +#define _DO_CALL_r01 844 +#define _DO_CALL_FUNCTION_EX_r31 845 +#define _DO_CALL_KW_r11 846 +#define _DYNAMIC_EXIT_r00 847 +#define _DYNAMIC_EXIT_r10 848 +#define _DYNAMIC_EXIT_r20 849 +#define _DYNAMIC_EXIT_r30 850 +#define _END_FOR_r10 851 +#define _END_SEND_r31 852 +#define _ERROR_POP_N_r00 853 +#define _EXIT_INIT_CHECK_r10 854 +#define _EXIT_TRACE_r00 855 +#define _EXIT_TRACE_r10 856 +#define _EXIT_TRACE_r20 857 +#define _EXIT_TRACE_r30 858 +#define _EXPAND_METHOD_r00 859 +#define _EXPAND_METHOD_KW_r11 860 +#define _FATAL_ERROR_r00 861 +#define _FATAL_ERROR_r11 862 +#define _FATAL_ERROR_r22 863 +#define _FATAL_ERROR_r33 864 +#define _FORMAT_SIMPLE_r11 865 +#define _FORMAT_WITH_SPEC_r21 866 +#define _FOR_ITER_r23 867 +#define _FOR_ITER_GEN_FRAME_r03 868 +#define _FOR_ITER_GEN_FRAME_r13 869 +#define _FOR_ITER_GEN_FRAME_r23 870 +#define _FOR_ITER_TIER_TWO_r23 871 +#define _GET_AITER_r11 872 +#define _GET_ANEXT_r12 873 +#define _GET_AWAITABLE_r11 874 +#define _GET_ITER_r12 875 +#define _GET_LEN_r12 876 +#define _GUARD_BINARY_OP_EXTEND_r22 877 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r02 878 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r12 879 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r22 880 +#define _GUARD_BINARY_OP_SUBSCR_TUPLE_INT_BOUNDS_r33 881 +#define _GUARD_BIT_IS_SET_POP_r00 882 +#define _GUARD_BIT_IS_SET_POP_r10 883 +#define _GUARD_BIT_IS_SET_POP_r21 884 +#define _GUARD_BIT_IS_SET_POP_r32 885 +#define _GUARD_BIT_IS_SET_POP_4_r00 886 +#define _GUARD_BIT_IS_SET_POP_4_r10 887 +#define _GUARD_BIT_IS_SET_POP_4_r21 888 +#define _GUARD_BIT_IS_SET_POP_4_r32 889 +#define _GUARD_BIT_IS_SET_POP_5_r00 890 +#define _GUARD_BIT_IS_SET_POP_5_r10 891 +#define _GUARD_BIT_IS_SET_POP_5_r21 892 +#define _GUARD_BIT_IS_SET_POP_5_r32 893 +#define _GUARD_BIT_IS_SET_POP_6_r00 894 +#define _GUARD_BIT_IS_SET_POP_6_r10 895 +#define _GUARD_BIT_IS_SET_POP_6_r21 896 +#define _GUARD_BIT_IS_SET_POP_6_r32 897 +#define _GUARD_BIT_IS_SET_POP_7_r00 898 +#define _GUARD_BIT_IS_SET_POP_7_r10 899 +#define _GUARD_BIT_IS_SET_POP_7_r21 900 +#define _GUARD_BIT_IS_SET_POP_7_r32 901 +#define _GUARD_BIT_IS_UNSET_POP_r00 902 +#define _GUARD_BIT_IS_UNSET_POP_r10 903 +#define _GUARD_BIT_IS_UNSET_POP_r21 904 +#define _GUARD_BIT_IS_UNSET_POP_r32 905 +#define _GUARD_BIT_IS_UNSET_POP_4_r00 906 +#define _GUARD_BIT_IS_UNSET_POP_4_r10 907 +#define _GUARD_BIT_IS_UNSET_POP_4_r21 908 +#define _GUARD_BIT_IS_UNSET_POP_4_r32 909 +#define _GUARD_BIT_IS_UNSET_POP_5_r00 910 +#define _GUARD_BIT_IS_UNSET_POP_5_r10 911 +#define _GUARD_BIT_IS_UNSET_POP_5_r21 912 +#define _GUARD_BIT_IS_UNSET_POP_5_r32 913 +#define _GUARD_BIT_IS_UNSET_POP_6_r00 914 +#define _GUARD_BIT_IS_UNSET_POP_6_r10 915 +#define _GUARD_BIT_IS_UNSET_POP_6_r21 916 +#define _GUARD_BIT_IS_UNSET_POP_6_r32 917 +#define _GUARD_BIT_IS_UNSET_POP_7_r00 918 +#define _GUARD_BIT_IS_UNSET_POP_7_r10 919 +#define _GUARD_BIT_IS_UNSET_POP_7_r21 920 +#define _GUARD_BIT_IS_UNSET_POP_7_r32 921 +#define _GUARD_CALLABLE_BUILTIN_CLASS_r00 922 +#define _GUARD_CALLABLE_BUILTIN_FAST_r00 923 +#define _GUARD_CALLABLE_BUILTIN_FAST_WITH_KEYWORDS_r00 924 +#define _GUARD_CALLABLE_BUILTIN_O_r00 925 +#define _GUARD_CALLABLE_ISINSTANCE_r03 926 +#define _GUARD_CALLABLE_ISINSTANCE_r13 927 +#define _GUARD_CALLABLE_ISINSTANCE_r23 928 +#define _GUARD_CALLABLE_ISINSTANCE_r33 929 +#define _GUARD_CALLABLE_LEN_r03 930 +#define _GUARD_CALLABLE_LEN_r13 931 +#define _GUARD_CALLABLE_LEN_r23 932 +#define _GUARD_CALLABLE_LEN_r33 933 +#define _GUARD_CALLABLE_LIST_APPEND_r03 934 +#define _GUARD_CALLABLE_LIST_APPEND_r13 935 +#define _GUARD_CALLABLE_LIST_APPEND_r23 936 +#define _GUARD_CALLABLE_LIST_APPEND_r33 937 +#define _GUARD_CALLABLE_METHOD_DESCRIPTOR_FAST_r00 938 +#define _GUARD_CALLABLE_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS_r00 939 +#define _GUARD_CALLABLE_METHOD_DESCRIPTOR_NOARGS_r00 940 +#define _GUARD_CALLABLE_METHOD_DESCRIPTOR_O_r00 941 +#define _GUARD_CALLABLE_STR_1_r03 942 +#define _GUARD_CALLABLE_STR_1_r13 943 +#define _GUARD_CALLABLE_STR_1_r23 944 +#define _GUARD_CALLABLE_STR_1_r33 945 +#define _GUARD_CALLABLE_TUPLE_1_r03 946 +#define _GUARD_CALLABLE_TUPLE_1_r13 947 +#define _GUARD_CALLABLE_TUPLE_1_r23 948 +#define _GUARD_CALLABLE_TUPLE_1_r33 949 +#define _GUARD_CALLABLE_TYPE_1_r03 950 +#define _GUARD_CALLABLE_TYPE_1_r13 951 +#define _GUARD_CALLABLE_TYPE_1_r23 952 +#define _GUARD_CALLABLE_TYPE_1_r33 953 +#define _GUARD_CODE_VERSION_RETURN_GENERATOR_r00 954 +#define _GUARD_CODE_VERSION_RETURN_GENERATOR_r11 955 +#define _GUARD_CODE_VERSION_RETURN_GENERATOR_r22 956 +#define _GUARD_CODE_VERSION_RETURN_GENERATOR_r33 957 +#define _GUARD_CODE_VERSION_RETURN_VALUE_r00 958 +#define _GUARD_CODE_VERSION_RETURN_VALUE_r11 959 +#define _GUARD_CODE_VERSION_RETURN_VALUE_r22 960 +#define _GUARD_CODE_VERSION_RETURN_VALUE_r33 961 +#define _GUARD_CODE_VERSION_YIELD_VALUE_r00 962 +#define _GUARD_CODE_VERSION_YIELD_VALUE_r11 963 +#define _GUARD_CODE_VERSION_YIELD_VALUE_r22 964 +#define _GUARD_CODE_VERSION_YIELD_VALUE_r33 965 +#define _GUARD_CODE_VERSION__PUSH_FRAME_r00 966 +#define _GUARD_CODE_VERSION__PUSH_FRAME_r11 967 +#define _GUARD_CODE_VERSION__PUSH_FRAME_r22 968 +#define _GUARD_CODE_VERSION__PUSH_FRAME_r33 969 +#define _GUARD_DORV_NO_DICT_r01 970 +#define _GUARD_DORV_NO_DICT_r11 971 +#define _GUARD_DORV_NO_DICT_r22 972 +#define _GUARD_DORV_NO_DICT_r33 973 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r01 974 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r11 975 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r22 976 +#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT_r33 977 +#define _GUARD_GLOBALS_VERSION_r00 978 +#define _GUARD_GLOBALS_VERSION_r11 979 +#define _GUARD_GLOBALS_VERSION_r22 980 +#define _GUARD_GLOBALS_VERSION_r33 981 +#define _GUARD_IP_RETURN_GENERATOR_r00 982 +#define _GUARD_IP_RETURN_GENERATOR_r11 983 +#define _GUARD_IP_RETURN_GENERATOR_r22 984 +#define _GUARD_IP_RETURN_GENERATOR_r33 985 +#define _GUARD_IP_RETURN_VALUE_r00 986 +#define _GUARD_IP_RETURN_VALUE_r11 987 +#define _GUARD_IP_RETURN_VALUE_r22 988 +#define _GUARD_IP_RETURN_VALUE_r33 989 +#define _GUARD_IP_YIELD_VALUE_r00 990 +#define _GUARD_IP_YIELD_VALUE_r11 991 +#define _GUARD_IP_YIELD_VALUE_r22 992 +#define _GUARD_IP_YIELD_VALUE_r33 993 +#define _GUARD_IP__PUSH_FRAME_r00 994 +#define _GUARD_IP__PUSH_FRAME_r11 995 +#define _GUARD_IP__PUSH_FRAME_r22 996 +#define _GUARD_IP__PUSH_FRAME_r33 997 +#define _GUARD_IS_FALSE_POP_r00 998 +#define _GUARD_IS_FALSE_POP_r10 999 +#define _GUARD_IS_FALSE_POP_r21 1000 +#define _GUARD_IS_FALSE_POP_r32 1001 +#define _GUARD_IS_NONE_POP_r00 1002 +#define _GUARD_IS_NONE_POP_r10 1003 +#define _GUARD_IS_NONE_POP_r21 1004 +#define _GUARD_IS_NONE_POP_r32 1005 +#define _GUARD_IS_NOT_NONE_POP_r10 1006 +#define _GUARD_IS_TRUE_POP_r00 1007 +#define _GUARD_IS_TRUE_POP_r10 1008 +#define _GUARD_IS_TRUE_POP_r21 1009 +#define _GUARD_IS_TRUE_POP_r32 1010 +#define _GUARD_KEYS_VERSION_r01 1011 +#define _GUARD_KEYS_VERSION_r11 1012 +#define _GUARD_KEYS_VERSION_r22 1013 +#define _GUARD_KEYS_VERSION_r33 1014 +#define _GUARD_LOAD_SUPER_ATTR_METHOD_r03 1015 +#define _GUARD_LOAD_SUPER_ATTR_METHOD_r13 1016 +#define _GUARD_LOAD_SUPER_ATTR_METHOD_r23 1017 +#define _GUARD_LOAD_SUPER_ATTR_METHOD_r33 1018 +#define _GUARD_NOS_ANY_DICT_r02 1019 +#define _GUARD_NOS_ANY_DICT_r12 1020 +#define _GUARD_NOS_ANY_DICT_r22 1021 +#define _GUARD_NOS_ANY_DICT_r33 1022 +#define _GUARD_NOS_COMPACT_ASCII_r02 1023 +#define _GUARD_NOS_COMPACT_ASCII_r12 1024 +#define _GUARD_NOS_COMPACT_ASCII_r22 1025 +#define _GUARD_NOS_COMPACT_ASCII_r33 1026 +#define _GUARD_NOS_DICT_r02 1027 +#define _GUARD_NOS_DICT_r12 1028 +#define _GUARD_NOS_DICT_r22 1029 +#define _GUARD_NOS_DICT_r33 1030 +#define _GUARD_NOS_FLOAT_r02 1031 +#define _GUARD_NOS_FLOAT_r12 1032 +#define _GUARD_NOS_FLOAT_r22 1033 +#define _GUARD_NOS_FLOAT_r33 1034 +#define _GUARD_NOS_INT_r02 1035 +#define _GUARD_NOS_INT_r12 1036 +#define _GUARD_NOS_INT_r22 1037 +#define _GUARD_NOS_INT_r33 1038 +#define _GUARD_NOS_LIST_r02 1039 +#define _GUARD_NOS_LIST_r12 1040 +#define _GUARD_NOS_LIST_r22 1041 +#define _GUARD_NOS_LIST_r33 1042 +#define _GUARD_NOS_NOT_NULL_r02 1043 +#define _GUARD_NOS_NOT_NULL_r12 1044 +#define _GUARD_NOS_NOT_NULL_r22 1045 +#define _GUARD_NOS_NOT_NULL_r33 1046 +#define _GUARD_NOS_NULL_r02 1047 +#define _GUARD_NOS_NULL_r12 1048 +#define _GUARD_NOS_NULL_r22 1049 +#define _GUARD_NOS_NULL_r33 1050 +#define _GUARD_NOS_OVERFLOWED_r02 1051 +#define _GUARD_NOS_OVERFLOWED_r12 1052 +#define _GUARD_NOS_OVERFLOWED_r22 1053 +#define _GUARD_NOS_OVERFLOWED_r33 1054 +#define _GUARD_NOS_TUPLE_r02 1055 +#define _GUARD_NOS_TUPLE_r12 1056 +#define _GUARD_NOS_TUPLE_r22 1057 +#define _GUARD_NOS_TUPLE_r33 1058 +#define _GUARD_NOS_TYPE_VERSION_r02 1059 +#define _GUARD_NOS_TYPE_VERSION_r12 1060 +#define _GUARD_NOS_TYPE_VERSION_r22 1061 +#define _GUARD_NOS_TYPE_VERSION_r33 1062 +#define _GUARD_NOS_UNICODE_r02 1063 +#define _GUARD_NOS_UNICODE_r12 1064 +#define _GUARD_NOS_UNICODE_r22 1065 +#define _GUARD_NOS_UNICODE_r33 1066 +#define _GUARD_NOT_EXHAUSTED_LIST_r02 1067 +#define _GUARD_NOT_EXHAUSTED_LIST_r12 1068 +#define _GUARD_NOT_EXHAUSTED_LIST_r22 1069 +#define _GUARD_NOT_EXHAUSTED_LIST_r33 1070 +#define _GUARD_NOT_EXHAUSTED_RANGE_r02 1071 +#define _GUARD_NOT_EXHAUSTED_RANGE_r12 1072 +#define _GUARD_NOT_EXHAUSTED_RANGE_r22 1073 +#define _GUARD_NOT_EXHAUSTED_RANGE_r33 1074 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r02 1075 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r12 1076 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r22 1077 +#define _GUARD_NOT_EXHAUSTED_TUPLE_r33 1078 +#define _GUARD_THIRD_NULL_r03 1079 +#define _GUARD_THIRD_NULL_r13 1080 +#define _GUARD_THIRD_NULL_r23 1081 +#define _GUARD_THIRD_NULL_r33 1082 +#define _GUARD_TOS_ANY_DICT_r01 1083 +#define _GUARD_TOS_ANY_DICT_r11 1084 +#define _GUARD_TOS_ANY_DICT_r22 1085 +#define _GUARD_TOS_ANY_DICT_r33 1086 +#define _GUARD_TOS_ANY_SET_r01 1087 +#define _GUARD_TOS_ANY_SET_r11 1088 +#define _GUARD_TOS_ANY_SET_r22 1089 +#define _GUARD_TOS_ANY_SET_r33 1090 +#define _GUARD_TOS_DICT_r01 1091 +#define _GUARD_TOS_DICT_r11 1092 +#define _GUARD_TOS_DICT_r22 1093 +#define _GUARD_TOS_DICT_r33 1094 +#define _GUARD_TOS_FLOAT_r01 1095 +#define _GUARD_TOS_FLOAT_r11 1096 +#define _GUARD_TOS_FLOAT_r22 1097 +#define _GUARD_TOS_FLOAT_r33 1098 +#define _GUARD_TOS_FROZENDICT_r01 1099 +#define _GUARD_TOS_FROZENDICT_r11 1100 +#define _GUARD_TOS_FROZENDICT_r22 1101 +#define _GUARD_TOS_FROZENDICT_r33 1102 +#define _GUARD_TOS_FROZENSET_r01 1103 +#define _GUARD_TOS_FROZENSET_r11 1104 +#define _GUARD_TOS_FROZENSET_r22 1105 +#define _GUARD_TOS_FROZENSET_r33 1106 +#define _GUARD_TOS_INT_r01 1107 +#define _GUARD_TOS_INT_r11 1108 +#define _GUARD_TOS_INT_r22 1109 +#define _GUARD_TOS_INT_r33 1110 +#define _GUARD_TOS_LIST_r01 1111 +#define _GUARD_TOS_LIST_r11 1112 +#define _GUARD_TOS_LIST_r22 1113 +#define _GUARD_TOS_LIST_r33 1114 +#define _GUARD_TOS_OVERFLOWED_r01 1115 +#define _GUARD_TOS_OVERFLOWED_r11 1116 +#define _GUARD_TOS_OVERFLOWED_r22 1117 +#define _GUARD_TOS_OVERFLOWED_r33 1118 +#define _GUARD_TOS_SET_r01 1119 +#define _GUARD_TOS_SET_r11 1120 +#define _GUARD_TOS_SET_r22 1121 +#define _GUARD_TOS_SET_r33 1122 +#define _GUARD_TOS_SLICE_r01 1123 +#define _GUARD_TOS_SLICE_r11 1124 +#define _GUARD_TOS_SLICE_r22 1125 +#define _GUARD_TOS_SLICE_r33 1126 +#define _GUARD_TOS_TUPLE_r01 1127 +#define _GUARD_TOS_TUPLE_r11 1128 +#define _GUARD_TOS_TUPLE_r22 1129 +#define _GUARD_TOS_TUPLE_r33 1130 +#define _GUARD_TOS_UNICODE_r01 1131 +#define _GUARD_TOS_UNICODE_r11 1132 +#define _GUARD_TOS_UNICODE_r22 1133 +#define _GUARD_TOS_UNICODE_r33 1134 +#define _GUARD_TYPE_VERSION_r01 1135 +#define _GUARD_TYPE_VERSION_r11 1136 +#define _GUARD_TYPE_VERSION_r22 1137 +#define _GUARD_TYPE_VERSION_r33 1138 +#define _GUARD_TYPE_VERSION_LOCKED_r01 1139 +#define _GUARD_TYPE_VERSION_LOCKED_r11 1140 +#define _GUARD_TYPE_VERSION_LOCKED_r22 1141 +#define _GUARD_TYPE_VERSION_LOCKED_r33 1142 +#define _HANDLE_PENDING_AND_DEOPT_r00 1143 +#define _HANDLE_PENDING_AND_DEOPT_r10 1144 +#define _HANDLE_PENDING_AND_DEOPT_r20 1145 +#define _HANDLE_PENDING_AND_DEOPT_r30 1146 +#define _IMPORT_FROM_r12 1147 +#define _IMPORT_NAME_r21 1148 +#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS_r00 1149 +#define _INIT_CALL_PY_EXACT_ARGS_r01 1150 +#define _INIT_CALL_PY_EXACT_ARGS_0_r01 1151 +#define _INIT_CALL_PY_EXACT_ARGS_1_r01 1152 +#define _INIT_CALL_PY_EXACT_ARGS_2_r01 1153 +#define _INIT_CALL_PY_EXACT_ARGS_3_r01 1154 +#define _INIT_CALL_PY_EXACT_ARGS_4_r01 1155 +#define _INSERT_NULL_r10 1156 +#define _INSTRUMENTED_FOR_ITER_r23 1157 +#define _INSTRUMENTED_INSTRUCTION_r00 1158 +#define _INSTRUMENTED_JUMP_FORWARD_r00 1159 +#define _INSTRUMENTED_JUMP_FORWARD_r11 1160 +#define _INSTRUMENTED_JUMP_FORWARD_r22 1161 +#define _INSTRUMENTED_JUMP_FORWARD_r33 1162 +#define _INSTRUMENTED_LINE_r00 1163 +#define _INSTRUMENTED_NOT_TAKEN_r00 1164 +#define _INSTRUMENTED_NOT_TAKEN_r11 1165 +#define _INSTRUMENTED_NOT_TAKEN_r22 1166 +#define _INSTRUMENTED_NOT_TAKEN_r33 1167 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r00 1168 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r10 1169 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r21 1170 +#define _INSTRUMENTED_POP_JUMP_IF_FALSE_r32 1171 +#define _INSTRUMENTED_POP_JUMP_IF_NONE_r10 1172 +#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE_r10 1173 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r00 1174 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r10 1175 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r21 1176 +#define _INSTRUMENTED_POP_JUMP_IF_TRUE_r32 1177 +#define _IS_NONE_r11 1178 +#define _IS_OP_r03 1179 +#define _IS_OP_r13 1180 +#define _IS_OP_r23 1181 +#define _ITER_CHECK_LIST_r02 1182 +#define _ITER_CHECK_LIST_r12 1183 +#define _ITER_CHECK_LIST_r22 1184 +#define _ITER_CHECK_LIST_r33 1185 +#define _ITER_CHECK_RANGE_r02 1186 +#define _ITER_CHECK_RANGE_r12 1187 +#define _ITER_CHECK_RANGE_r22 1188 +#define _ITER_CHECK_RANGE_r33 1189 +#define _ITER_CHECK_TUPLE_r02 1190 +#define _ITER_CHECK_TUPLE_r12 1191 +#define _ITER_CHECK_TUPLE_r22 1192 +#define _ITER_CHECK_TUPLE_r33 1193 +#define _ITER_JUMP_LIST_r02 1194 +#define _ITER_JUMP_LIST_r12 1195 +#define _ITER_JUMP_LIST_r22 1196 +#define _ITER_JUMP_LIST_r33 1197 +#define _ITER_JUMP_RANGE_r02 1198 +#define _ITER_JUMP_RANGE_r12 1199 +#define _ITER_JUMP_RANGE_r22 1200 +#define _ITER_JUMP_RANGE_r33 1201 +#define _ITER_JUMP_TUPLE_r02 1202 +#define _ITER_JUMP_TUPLE_r12 1203 +#define _ITER_JUMP_TUPLE_r22 1204 +#define _ITER_JUMP_TUPLE_r33 1205 +#define _ITER_NEXT_LIST_r23 1206 +#define _ITER_NEXT_LIST_TIER_TWO_r23 1207 +#define _ITER_NEXT_RANGE_r03 1208 +#define _ITER_NEXT_RANGE_r13 1209 +#define _ITER_NEXT_RANGE_r23 1210 +#define _ITER_NEXT_TUPLE_r03 1211 +#define _ITER_NEXT_TUPLE_r13 1212 +#define _ITER_NEXT_TUPLE_r23 1213 +#define _JUMP_BACKWARD_NO_INTERRUPT_r00 1214 +#define _JUMP_BACKWARD_NO_INTERRUPT_r11 1215 +#define _JUMP_BACKWARD_NO_INTERRUPT_r22 1216 +#define _JUMP_BACKWARD_NO_INTERRUPT_r33 1217 +#define _JUMP_TO_TOP_r00 1218 +#define _LIST_APPEND_r10 1219 +#define _LIST_EXTEND_r11 1220 +#define _LOAD_ATTR_r10 1221 +#define _LOAD_ATTR_CLASS_r11 1222 +#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME_r11 1223 +#define _LOAD_ATTR_INSTANCE_VALUE_r02 1224 +#define _LOAD_ATTR_INSTANCE_VALUE_r12 1225 +#define _LOAD_ATTR_INSTANCE_VALUE_r23 1226 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r02 1227 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r12 1228 +#define _LOAD_ATTR_METHOD_LAZY_DICT_r23 1229 +#define _LOAD_ATTR_METHOD_NO_DICT_r02 1230 +#define _LOAD_ATTR_METHOD_NO_DICT_r12 1231 +#define _LOAD_ATTR_METHOD_NO_DICT_r23 1232 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r02 1233 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r12 1234 +#define _LOAD_ATTR_METHOD_WITH_VALUES_r23 1235 +#define _LOAD_ATTR_MODULE_r12 1236 +#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT_r11 1237 +#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES_r11 1238 +#define _LOAD_ATTR_PROPERTY_FRAME_r01 1239 +#define _LOAD_ATTR_PROPERTY_FRAME_r11 1240 +#define _LOAD_ATTR_PROPERTY_FRAME_r22 1241 +#define _LOAD_ATTR_PROPERTY_FRAME_r33 1242 +#define _LOAD_ATTR_SLOT_r02 1243 +#define _LOAD_ATTR_SLOT_r12 1244 +#define _LOAD_ATTR_SLOT_r23 1245 +#define _LOAD_ATTR_WITH_HINT_r12 1246 +#define _LOAD_BUILD_CLASS_r01 1247 +#define _LOAD_BYTECODE_r00 1248 +#define _LOAD_COMMON_CONSTANT_r01 1249 +#define _LOAD_COMMON_CONSTANT_r12 1250 +#define _LOAD_COMMON_CONSTANT_r23 1251 +#define _LOAD_CONST_r01 1252 +#define _LOAD_CONST_r12 1253 +#define _LOAD_CONST_r23 1254 +#define _LOAD_CONST_INLINE_r01 1255 +#define _LOAD_CONST_INLINE_r12 1256 +#define _LOAD_CONST_INLINE_r23 1257 +#define _LOAD_CONST_INLINE_BORROW_r01 1258 +#define _LOAD_CONST_INLINE_BORROW_r12 1259 +#define _LOAD_CONST_INLINE_BORROW_r23 1260 +#define _LOAD_DEREF_r01 1261 +#define _LOAD_FAST_r01 1262 +#define _LOAD_FAST_r12 1263 +#define _LOAD_FAST_r23 1264 +#define _LOAD_FAST_0_r01 1265 +#define _LOAD_FAST_0_r12 1266 +#define _LOAD_FAST_0_r23 1267 +#define _LOAD_FAST_1_r01 1268 +#define _LOAD_FAST_1_r12 1269 +#define _LOAD_FAST_1_r23 1270 +#define _LOAD_FAST_2_r01 1271 +#define _LOAD_FAST_2_r12 1272 +#define _LOAD_FAST_2_r23 1273 +#define _LOAD_FAST_3_r01 1274 +#define _LOAD_FAST_3_r12 1275 +#define _LOAD_FAST_3_r23 1276 +#define _LOAD_FAST_4_r01 1277 +#define _LOAD_FAST_4_r12 1278 +#define _LOAD_FAST_4_r23 1279 +#define _LOAD_FAST_5_r01 1280 +#define _LOAD_FAST_5_r12 1281 +#define _LOAD_FAST_5_r23 1282 +#define _LOAD_FAST_6_r01 1283 +#define _LOAD_FAST_6_r12 1284 +#define _LOAD_FAST_6_r23 1285 +#define _LOAD_FAST_7_r01 1286 +#define _LOAD_FAST_7_r12 1287 +#define _LOAD_FAST_7_r23 1288 +#define _LOAD_FAST_AND_CLEAR_r01 1289 +#define _LOAD_FAST_AND_CLEAR_r12 1290 +#define _LOAD_FAST_AND_CLEAR_r23 1291 +#define _LOAD_FAST_BORROW_r01 1292 +#define _LOAD_FAST_BORROW_r12 1293 +#define _LOAD_FAST_BORROW_r23 1294 +#define _LOAD_FAST_BORROW_0_r01 1295 +#define _LOAD_FAST_BORROW_0_r12 1296 +#define _LOAD_FAST_BORROW_0_r23 1297 +#define _LOAD_FAST_BORROW_1_r01 1298 +#define _LOAD_FAST_BORROW_1_r12 1299 +#define _LOAD_FAST_BORROW_1_r23 1300 +#define _LOAD_FAST_BORROW_2_r01 1301 +#define _LOAD_FAST_BORROW_2_r12 1302 +#define _LOAD_FAST_BORROW_2_r23 1303 +#define _LOAD_FAST_BORROW_3_r01 1304 +#define _LOAD_FAST_BORROW_3_r12 1305 +#define _LOAD_FAST_BORROW_3_r23 1306 +#define _LOAD_FAST_BORROW_4_r01 1307 +#define _LOAD_FAST_BORROW_4_r12 1308 +#define _LOAD_FAST_BORROW_4_r23 1309 +#define _LOAD_FAST_BORROW_5_r01 1310 +#define _LOAD_FAST_BORROW_5_r12 1311 +#define _LOAD_FAST_BORROW_5_r23 1312 +#define _LOAD_FAST_BORROW_6_r01 1313 +#define _LOAD_FAST_BORROW_6_r12 1314 +#define _LOAD_FAST_BORROW_6_r23 1315 +#define _LOAD_FAST_BORROW_7_r01 1316 +#define _LOAD_FAST_BORROW_7_r12 1317 +#define _LOAD_FAST_BORROW_7_r23 1318 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r02 1319 +#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW_r13 1320 +#define _LOAD_FAST_CHECK_r01 1321 +#define _LOAD_FAST_CHECK_r12 1322 +#define _LOAD_FAST_CHECK_r23 1323 +#define _LOAD_FAST_LOAD_FAST_r02 1324 +#define _LOAD_FAST_LOAD_FAST_r13 1325 +#define _LOAD_FROM_DICT_OR_DEREF_r11 1326 +#define _LOAD_FROM_DICT_OR_GLOBALS_r11 1327 +#define _LOAD_GLOBAL_r00 1328 +#define _LOAD_GLOBAL_BUILTINS_r01 1329 +#define _LOAD_GLOBAL_MODULE_r01 1330 +#define _LOAD_LOCALS_r01 1331 +#define _LOAD_LOCALS_r12 1332 +#define _LOAD_LOCALS_r23 1333 +#define _LOAD_NAME_r01 1334 +#define _LOAD_SMALL_INT_r01 1335 +#define _LOAD_SMALL_INT_r12 1336 +#define _LOAD_SMALL_INT_r23 1337 +#define _LOAD_SMALL_INT_0_r01 1338 +#define _LOAD_SMALL_INT_0_r12 1339 +#define _LOAD_SMALL_INT_0_r23 1340 +#define _LOAD_SMALL_INT_1_r01 1341 +#define _LOAD_SMALL_INT_1_r12 1342 +#define _LOAD_SMALL_INT_1_r23 1343 +#define _LOAD_SMALL_INT_2_r01 1344 +#define _LOAD_SMALL_INT_2_r12 1345 +#define _LOAD_SMALL_INT_2_r23 1346 +#define _LOAD_SMALL_INT_3_r01 1347 +#define _LOAD_SMALL_INT_3_r12 1348 +#define _LOAD_SMALL_INT_3_r23 1349 +#define _LOAD_SPECIAL_r00 1350 +#define _LOAD_SUPER_ATTR_ATTR_r31 1351 +#define _LOAD_SUPER_ATTR_METHOD_r32 1352 +#define _LOCK_OBJECT_r01 1353 +#define _LOCK_OBJECT_r11 1354 +#define _LOCK_OBJECT_r22 1355 +#define _LOCK_OBJECT_r33 1356 +#define _MAKE_CALLARGS_A_TUPLE_r33 1357 +#define _MAKE_CELL_r00 1358 +#define _MAKE_FUNCTION_r12 1359 +#define _MAKE_HEAP_SAFE_r01 1360 +#define _MAKE_HEAP_SAFE_r11 1361 +#define _MAKE_HEAP_SAFE_r22 1362 +#define _MAKE_HEAP_SAFE_r33 1363 +#define _MAKE_WARM_r00 1364 +#define _MAKE_WARM_r11 1365 +#define _MAKE_WARM_r22 1366 +#define _MAKE_WARM_r33 1367 +#define _MAP_ADD_r20 1368 +#define _MATCH_CLASS_r33 1369 +#define _MATCH_KEYS_r23 1370 +#define _MATCH_MAPPING_r02 1371 +#define _MATCH_MAPPING_r12 1372 +#define _MATCH_MAPPING_r23 1373 +#define _MATCH_SEQUENCE_r02 1374 +#define _MATCH_SEQUENCE_r12 1375 +#define _MATCH_SEQUENCE_r23 1376 +#define _MAYBE_EXPAND_METHOD_r00 1377 +#define _MAYBE_EXPAND_METHOD_KW_r11 1378 +#define _MONITOR_CALL_r00 1379 +#define _MONITOR_CALL_KW_r11 1380 +#define _MONITOR_JUMP_BACKWARD_r00 1381 +#define _MONITOR_JUMP_BACKWARD_r11 1382 +#define _MONITOR_JUMP_BACKWARD_r22 1383 +#define _MONITOR_JUMP_BACKWARD_r33 1384 +#define _MONITOR_RESUME_r00 1385 +#define _NOP_r00 1386 +#define _NOP_r11 1387 +#define _NOP_r22 1388 +#define _NOP_r33 1389 +#define _POP_EXCEPT_r10 1390 +#define _POP_ITER_r20 1391 +#define _POP_JUMP_IF_FALSE_r00 1392 +#define _POP_JUMP_IF_FALSE_r10 1393 +#define _POP_JUMP_IF_FALSE_r21 1394 +#define _POP_JUMP_IF_FALSE_r32 1395 +#define _POP_JUMP_IF_TRUE_r00 1396 +#define _POP_JUMP_IF_TRUE_r10 1397 +#define _POP_JUMP_IF_TRUE_r21 1398 +#define _POP_JUMP_IF_TRUE_r32 1399 +#define _POP_TOP_r10 1400 +#define _POP_TOP_FLOAT_r00 1401 +#define _POP_TOP_FLOAT_r10 1402 +#define _POP_TOP_FLOAT_r21 1403 +#define _POP_TOP_FLOAT_r32 1404 +#define _POP_TOP_INT_r00 1405 +#define _POP_TOP_INT_r10 1406 +#define _POP_TOP_INT_r21 1407 +#define _POP_TOP_INT_r32 1408 +#define _POP_TOP_NOP_r00 1409 +#define _POP_TOP_NOP_r10 1410 +#define _POP_TOP_NOP_r21 1411 +#define _POP_TOP_NOP_r32 1412 +#define _POP_TOP_OPARG_r00 1413 +#define _POP_TOP_UNICODE_r00 1414 +#define _POP_TOP_UNICODE_r10 1415 +#define _POP_TOP_UNICODE_r21 1416 +#define _POP_TOP_UNICODE_r32 1417 +#define _PUSH_EXC_INFO_r02 1418 +#define _PUSH_EXC_INFO_r12 1419 +#define _PUSH_EXC_INFO_r23 1420 +#define _PUSH_FRAME_r10 1421 +#define _PUSH_NULL_r01 1422 +#define _PUSH_NULL_r12 1423 +#define _PUSH_NULL_r23 1424 +#define _PUSH_NULL_CONDITIONAL_r00 1425 +#define _PY_FRAME_EX_r31 1426 +#define _PY_FRAME_GENERAL_r01 1427 +#define _PY_FRAME_KW_r11 1428 +#define _REPLACE_WITH_TRUE_r02 1429 +#define _REPLACE_WITH_TRUE_r12 1430 +#define _REPLACE_WITH_TRUE_r23 1431 +#define _RESUME_CHECK_r00 1432 +#define _RESUME_CHECK_r11 1433 +#define _RESUME_CHECK_r22 1434 +#define _RESUME_CHECK_r33 1435 +#define _RETURN_GENERATOR_r01 1436 +#define _RETURN_VALUE_r11 1437 +#define _SAVE_RETURN_OFFSET_r00 1438 +#define _SAVE_RETURN_OFFSET_r11 1439 +#define _SAVE_RETURN_OFFSET_r22 1440 +#define _SAVE_RETURN_OFFSET_r33 1441 +#define _SEND_r33 1442 +#define _SEND_GEN_FRAME_r33 1443 +#define _SETUP_ANNOTATIONS_r00 1444 +#define _SET_ADD_r10 1445 +#define _SET_FUNCTION_ATTRIBUTE_r01 1446 +#define _SET_FUNCTION_ATTRIBUTE_r11 1447 +#define _SET_FUNCTION_ATTRIBUTE_r21 1448 +#define _SET_FUNCTION_ATTRIBUTE_r32 1449 +#define _SET_IP_r00 1450 +#define _SET_IP_r11 1451 +#define _SET_IP_r22 1452 +#define _SET_IP_r33 1453 +#define _SET_UPDATE_r11 1454 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r03 1455 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r13 1456 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r23 1457 +#define _SHUFFLE_3_LOAD_CONST_INLINE_BORROW_r33 1458 +#define _SPILL_OR_RELOAD_r01 1459 +#define _SPILL_OR_RELOAD_r02 1460 +#define _SPILL_OR_RELOAD_r03 1461 +#define _SPILL_OR_RELOAD_r10 1462 +#define _SPILL_OR_RELOAD_r12 1463 +#define _SPILL_OR_RELOAD_r13 1464 +#define _SPILL_OR_RELOAD_r20 1465 +#define _SPILL_OR_RELOAD_r21 1466 +#define _SPILL_OR_RELOAD_r23 1467 +#define _SPILL_OR_RELOAD_r30 1468 +#define _SPILL_OR_RELOAD_r31 1469 +#define _SPILL_OR_RELOAD_r32 1470 +#define _START_EXECUTOR_r00 1471 +#define _STORE_ATTR_r20 1472 +#define _STORE_ATTR_INSTANCE_VALUE_r21 1473 +#define _STORE_ATTR_SLOT_r21 1474 +#define _STORE_ATTR_WITH_HINT_r21 1475 +#define _STORE_DEREF_r10 1476 +#define _STORE_FAST_LOAD_FAST_r11 1477 +#define _STORE_FAST_STORE_FAST_r20 1478 +#define _STORE_GLOBAL_r10 1479 +#define _STORE_NAME_r10 1480 +#define _STORE_SLICE_r30 1481 +#define _STORE_SUBSCR_r30 1482 +#define _STORE_SUBSCR_DICT_r31 1483 +#define _STORE_SUBSCR_DICT_KNOWN_HASH_r31 1484 +#define _STORE_SUBSCR_LIST_INT_r32 1485 +#define _SWAP_r11 1486 +#define _SWAP_2_r02 1487 +#define _SWAP_2_r12 1488 +#define _SWAP_2_r22 1489 +#define _SWAP_2_r33 1490 +#define _SWAP_3_r03 1491 +#define _SWAP_3_r13 1492 +#define _SWAP_3_r23 1493 +#define _SWAP_3_r33 1494 +#define _SWAP_FAST_r01 1495 +#define _SWAP_FAST_r11 1496 +#define _SWAP_FAST_r22 1497 +#define _SWAP_FAST_r33 1498 +#define _SWAP_FAST_0_r01 1499 +#define _SWAP_FAST_0_r11 1500 +#define _SWAP_FAST_0_r22 1501 +#define _SWAP_FAST_0_r33 1502 +#define _SWAP_FAST_1_r01 1503 +#define _SWAP_FAST_1_r11 1504 +#define _SWAP_FAST_1_r22 1505 +#define _SWAP_FAST_1_r33 1506 +#define _SWAP_FAST_2_r01 1507 +#define _SWAP_FAST_2_r11 1508 +#define _SWAP_FAST_2_r22 1509 +#define _SWAP_FAST_2_r33 1510 +#define _SWAP_FAST_3_r01 1511 +#define _SWAP_FAST_3_r11 1512 +#define _SWAP_FAST_3_r22 1513 +#define _SWAP_FAST_3_r33 1514 +#define _SWAP_FAST_4_r01 1515 +#define _SWAP_FAST_4_r11 1516 +#define _SWAP_FAST_4_r22 1517 +#define _SWAP_FAST_4_r33 1518 +#define _SWAP_FAST_5_r01 1519 +#define _SWAP_FAST_5_r11 1520 +#define _SWAP_FAST_5_r22 1521 +#define _SWAP_FAST_5_r33 1522 +#define _SWAP_FAST_6_r01 1523 +#define _SWAP_FAST_6_r11 1524 +#define _SWAP_FAST_6_r22 1525 +#define _SWAP_FAST_6_r33 1526 +#define _SWAP_FAST_7_r01 1527 +#define _SWAP_FAST_7_r11 1528 +#define _SWAP_FAST_7_r22 1529 +#define _SWAP_FAST_7_r33 1530 +#define _TIER2_RESUME_CHECK_r00 1531 +#define _TIER2_RESUME_CHECK_r11 1532 +#define _TIER2_RESUME_CHECK_r22 1533 +#define _TIER2_RESUME_CHECK_r33 1534 +#define _TO_BOOL_r11 1535 +#define _TO_BOOL_BOOL_r01 1536 +#define _TO_BOOL_BOOL_r11 1537 +#define _TO_BOOL_BOOL_r22 1538 +#define _TO_BOOL_BOOL_r33 1539 +#define _TO_BOOL_INT_r02 1540 +#define _TO_BOOL_INT_r12 1541 +#define _TO_BOOL_INT_r23 1542 +#define _TO_BOOL_LIST_r02 1543 +#define _TO_BOOL_LIST_r12 1544 +#define _TO_BOOL_LIST_r23 1545 +#define _TO_BOOL_NONE_r01 1546 +#define _TO_BOOL_NONE_r11 1547 +#define _TO_BOOL_NONE_r22 1548 +#define _TO_BOOL_NONE_r33 1549 +#define _TO_BOOL_STR_r02 1550 +#define _TO_BOOL_STR_r12 1551 +#define _TO_BOOL_STR_r23 1552 +#define _TRACE_RECORD_r00 1553 +#define _UNARY_INVERT_r12 1554 +#define _UNARY_NEGATIVE_r12 1555 +#define _UNARY_NEGATIVE_FLOAT_INPLACE_r02 1556 +#define _UNARY_NEGATIVE_FLOAT_INPLACE_r12 1557 +#define _UNARY_NEGATIVE_FLOAT_INPLACE_r23 1558 +#define _UNARY_NOT_r01 1559 +#define _UNARY_NOT_r11 1560 +#define _UNARY_NOT_r22 1561 +#define _UNARY_NOT_r33 1562 +#define _UNPACK_EX_r10 1563 +#define _UNPACK_SEQUENCE_r10 1564 +#define _UNPACK_SEQUENCE_LIST_r10 1565 +#define _UNPACK_SEQUENCE_TUPLE_r10 1566 +#define _UNPACK_SEQUENCE_TWO_TUPLE_r12 1567 +#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE_r03 1568 +#define _UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE_r13 1569 +#define _UNPACK_SEQUENCE_UNIQUE_TUPLE_r10 1570 +#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r02 1571 +#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r12 1572 +#define _UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE_r23 1573 +#define _WITH_EXCEPT_START_r33 1574 +#define _YIELD_VALUE_r11 1575 +#define MAX_UOP_REGS_ID 1575 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index bb3e3b9950c577..a239f6a80c8c89 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -223,6 +223,7 @@ const uint32_t _PyUop_Flags[MAX_UOP_ID+1] = { [_CHECK_ATTR_CLASS] = HAS_EXIT_FLAG, [_LOAD_ATTR_CLASS] = HAS_ESCAPES_FLAG, [_LOAD_ATTR_PROPERTY_FRAME] = HAS_ARG_FLAG | HAS_EXIT_FLAG, + [_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME] = HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG, [_GUARD_DORV_NO_DICT] = HAS_EXIT_FLAG, [_STORE_ATTR_INSTANCE_VALUE] = HAS_ESCAPES_FLAG, [_LOCK_OBJECT] = HAS_DEOPT_FLAG, @@ -2120,6 +2121,15 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = { { 3, 3, _LOAD_ATTR_PROPERTY_FRAME_r33 }, }, }, + [_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME] = { + .best = { 1, 1, 1, 1 }, + .entries = { + { -1, -1, -1 }, + { 1, 1, _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME_r11 }, + { -1, -1, -1 }, + { -1, -1, -1 }, + }, + }, [_GUARD_DORV_NO_DICT] = { .best = { 0, 1, 2, 3 }, .entries = { @@ -4184,6 +4194,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = { [_LOAD_ATTR_PROPERTY_FRAME_r11] = _LOAD_ATTR_PROPERTY_FRAME, [_LOAD_ATTR_PROPERTY_FRAME_r22] = _LOAD_ATTR_PROPERTY_FRAME, [_LOAD_ATTR_PROPERTY_FRAME_r33] = _LOAD_ATTR_PROPERTY_FRAME, + [_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME_r11] = _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME, [_GUARD_DORV_NO_DICT_r01] = _GUARD_DORV_NO_DICT, [_GUARD_DORV_NO_DICT_r11] = _GUARD_DORV_NO_DICT, [_GUARD_DORV_NO_DICT_r22] = _GUARD_DORV_NO_DICT, @@ -5405,6 +5416,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = { [_LOAD_ATTR_r10] = "_LOAD_ATTR_r10", [_LOAD_ATTR_CLASS] = "_LOAD_ATTR_CLASS", [_LOAD_ATTR_CLASS_r11] = "_LOAD_ATTR_CLASS_r11", + [_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME] = "_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME", + [_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME_r11] = "_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME_r11", [_LOAD_ATTR_INSTANCE_VALUE] = "_LOAD_ATTR_INSTANCE_VALUE", [_LOAD_ATTR_INSTANCE_VALUE_r02] = "_LOAD_ATTR_INSTANCE_VALUE_r02", [_LOAD_ATTR_INSTANCE_VALUE_r12] = "_LOAD_ATTR_INSTANCE_VALUE_r12", @@ -6260,6 +6273,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 1; case _LOAD_ATTR_PROPERTY_FRAME: return 1; + case _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME: + return 1; case _GUARD_DORV_NO_DICT: return 0; case _STORE_ATTR_INSTANCE_VALUE: diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index 32da5e6159d532..c144ab1106ccea 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -4928,6 +4928,25 @@ def testfunc(*args): # This is a sign the optimizer ran and didn't hit contradiction. self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) + def test_load_attr_getattribute_frame(self): + class B: + def __getattribute__(self, name): + return len(name) + + def testfunc(n): + b = B() + y = 0 + for _ in range(n): + y += b.x + b.y + return y + + res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + self.assertEqual(res, 2 * TIER2_THRESHOLD) + uops = get_opnames(ex) + self.assertIn("_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME", uops) + self.assertNotIn("_LOAD_GLOBAL_BUILTINS", uops) + def test_load_attr_property_frame_invalidates_on_code_change(self): class C: @property diff --git a/Modules/_testinternalcapi/test_cases.c.h b/Modules/_testinternalcapi/test_cases.c.h index afbc88381d65b4..2253e3550fb3c5 100644 --- a/Modules/_testinternalcapi/test_cases.c.h +++ b/Modules/_testinternalcapi/test_cases.c.h @@ -8308,50 +8308,81 @@ INSTRUCTION_STATS(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); _PyStackRef owner; + _PyStackRef new_frame; /* Skip 1 cache entry */ - owner = stack_pointer[-1]; - uint32_t type_version = read_u32(&this_instr[2].cache); - uint32_t func_version = read_u32(&this_instr[4].cache); - PyObject *getattribute = read_obj(&this_instr[6].cache); - PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert((oparg & 1) == 0); - if (IS_PEP523_HOOKED(tstate)) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - PyTypeObject *cls = Py_TYPE(owner_o); - assert(type_version != 0); - if (FT_ATOMIC_LOAD_UINT_RELAXED(cls->tp_version_tag) != type_version) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); - PyFunctionObject *f = (PyFunctionObject *)getattribute; - assert(func_version != 0); - if (f->func_version != func_version) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - PyCodeObject *code = (PyCodeObject *)f->func_code; - assert(code->co_argcount == 2); - if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - STAT_INC(LOAD_ATTR, hit); - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); - _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked( - tstate, PyStackRef_FromPyObjectNew(f), 2, frame); - new_frame->localsplus[0] = owner; - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - new_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name); - frame->return_offset = 10u ; - DISPATCH_INLINED(new_frame); + // _GUARD_TYPE_VERSION + { + owner = stack_pointer[-1]; + uint32_t type_version = read_u32(&this_instr[2].cache); + PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner)); + assert(type_version != 0); + if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { + UPDATE_MISS_STATS(LOAD_ATTR); + assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); + JUMP_TO_PREDICTED(LOAD_ATTR); + } + } + // _CHECK_PEP_523 + { + if (IS_PEP523_HOOKED(tstate)) { + UPDATE_MISS_STATS(LOAD_ATTR); + assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); + JUMP_TO_PREDICTED(LOAD_ATTR); + } + } + // _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME + { + uint32_t func_version = read_u32(&this_instr[4].cache); + PyObject *getattribute = read_obj(&this_instr[6].cache); + assert((oparg & 1) == 0); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + assert(func_version != 0); + if (f->func_version != func_version) { + UPDATE_MISS_STATS(LOAD_ATTR); + assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); + JUMP_TO_PREDICTED(LOAD_ATTR); + } + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 2); + if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { + UPDATE_MISS_STATS(LOAD_ATTR); + assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); + JUMP_TO_PREDICTED(LOAD_ATTR); + } + STAT_INC(LOAD_ATTR, hit); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); + _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked( + tstate, PyStackRef_FromPyObjectNew(f), 2, frame); + pushed_frame->localsplus[0] = owner; + pushed_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name); + new_frame = PyStackRef_Wrap(pushed_frame); + } + // _SAVE_RETURN_OFFSET + { + #if TIER_ONE + frame->return_offset = (uint16_t)(next_instr - this_instr); + #endif + #if TIER_TWO + frame->return_offset = oparg; + #endif + } + // _PUSH_FRAME + { + assert(!IS_PEP523_HOOKED(tstate)); + _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(temp->previous == frame || temp->previous->previous == frame); + CALL_STAT_INC(inlined_py_calls); + frame = tstate->current_frame = temp; + tstate->py_recursion_remaining--; + LOAD_SP(); + LOAD_IP(0); + LLTRACE_RESUME_FRAME(); + } + DISPATCH(); } TARGET(LOAD_ATTR_INSTANCE_VALUE) { diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 1ae6610774e274..dc21f084f74c49 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -2942,35 +2942,34 @@ dummy_func( _SAVE_RETURN_OFFSET + _PUSH_FRAME; - inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused)) { - PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - + op(_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME, (func_version/2, getattribute/4, owner -- new_frame)) { assert((oparg & 1) == 0); - DEOPT_IF(IS_PEP523_HOOKED(tstate)); - PyTypeObject *cls = Py_TYPE(owner_o); - assert(type_version != 0); - DEOPT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(cls->tp_version_tag) != type_version); assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); PyFunctionObject *f = (PyFunctionObject *)getattribute; assert(func_version != 0); - DEOPT_IF(f->func_version != func_version); + EXIT_IF(f->func_version != func_version); PyCodeObject *code = (PyCodeObject *)f->func_code; assert(code->co_argcount == 2); - DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); + EXIT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize)); STAT_INC(LOAD_ATTR, hit); - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); - _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked( + _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked( tstate, PyStackRef_FromPyObjectNew(f), 2, frame); - new_frame->localsplus[0] = owner; + pushed_frame->localsplus[0] = owner; DEAD(owner); - // Manipulate stack directly because we exit with DISPATCH_INLINED(). - SYNC_SP(); - new_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name); - frame->return_offset = INSTRUCTION_SIZE; - DISPATCH_INLINED(new_frame); + pushed_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name); + new_frame = PyStackRef_Wrap(pushed_frame); } + macro(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) = + unused/1 + + _RECORD_TOS_TYPE + + _GUARD_TYPE_VERSION + + _CHECK_PEP_523 + + _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME + + _SAVE_RETURN_OFFSET + + _PUSH_FRAME; + op(_GUARD_DORV_NO_DICT, (owner -- owner)) { PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 3614839499b7ab..7dc45ad7f0467a 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -11605,7 +11605,48 @@ break; } - /* _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN is not a viable micro-op for tier 2 because it has too many cache entries */ + case _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME_r11: { + CHECK_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + _PyStackRef owner; + _PyStackRef new_frame; + _PyStackRef _stack_item_0 = _tos_cache0; + oparg = CURRENT_OPARG(); + owner = _stack_item_0; + uint32_t func_version = (uint32_t)CURRENT_OPERAND0_32(); + PyObject *getattribute = (PyObject *)CURRENT_OPERAND1_64(); + assert((oparg & 1) == 0); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + assert(func_version != 0); + if (f->func_version != func_version) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = owner; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 2); + if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { + UOP_STAT_INC(uopcode, miss); + _tos_cache0 = owner; + SET_CURRENT_CACHED_VALUES(1); + JUMP_TO_JUMP_TARGET(); + } + STAT_INC(LOAD_ATTR, hit); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); + _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked( + tstate, PyStackRef_FromPyObjectNew(f), 2, frame); + pushed_frame->localsplus[0] = owner; + pushed_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name); + new_frame = PyStackRef_Wrap(pushed_frame); + _tos_cache0 = new_frame; + _tos_cache1 = PyStackRef_ZERO_BITS; + _tos_cache2 = PyStackRef_ZERO_BITS; + SET_CURRENT_CACHED_VALUES(1); + assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE()); + break; + } case _GUARD_DORV_NO_DICT_r01: { CHECK_CURRENT_CACHED_VALUES(0); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index cd5131c0f1b68c..8bfdb8a35acf2c 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -8307,50 +8307,81 @@ INSTRUCTION_STATS(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN); static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); _PyStackRef owner; + _PyStackRef new_frame; /* Skip 1 cache entry */ - owner = stack_pointer[-1]; - uint32_t type_version = read_u32(&this_instr[2].cache); - uint32_t func_version = read_u32(&this_instr[4].cache); - PyObject *getattribute = read_obj(&this_instr[6].cache); - PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner); - assert((oparg & 1) == 0); - if (IS_PEP523_HOOKED(tstate)) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - PyTypeObject *cls = Py_TYPE(owner_o); - assert(type_version != 0); - if (FT_ATOMIC_LOAD_UINT_RELAXED(cls->tp_version_tag) != type_version) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); - PyFunctionObject *f = (PyFunctionObject *)getattribute; - assert(func_version != 0); - if (f->func_version != func_version) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - PyCodeObject *code = (PyCodeObject *)f->func_code; - assert(code->co_argcount == 2); - if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { - UPDATE_MISS_STATS(LOAD_ATTR); - assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); - JUMP_TO_PREDICTED(LOAD_ATTR); - } - STAT_INC(LOAD_ATTR, hit); - PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); - _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked( - tstate, PyStackRef_FromPyObjectNew(f), 2, frame); - new_frame->localsplus[0] = owner; - stack_pointer += -1; - ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); - new_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name); - frame->return_offset = 10u ; - DISPATCH_INLINED(new_frame); + // _GUARD_TYPE_VERSION + { + owner = stack_pointer[-1]; + uint32_t type_version = read_u32(&this_instr[2].cache); + PyTypeObject *tp = Py_TYPE(PyStackRef_AsPyObjectBorrow(owner)); + assert(type_version != 0); + if (FT_ATOMIC_LOAD_UINT_RELAXED(tp->tp_version_tag) != type_version) { + UPDATE_MISS_STATS(LOAD_ATTR); + assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); + JUMP_TO_PREDICTED(LOAD_ATTR); + } + } + // _CHECK_PEP_523 + { + if (IS_PEP523_HOOKED(tstate)) { + UPDATE_MISS_STATS(LOAD_ATTR); + assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); + JUMP_TO_PREDICTED(LOAD_ATTR); + } + } + // _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME + { + uint32_t func_version = read_u32(&this_instr[4].cache); + PyObject *getattribute = read_obj(&this_instr[6].cache); + assert((oparg & 1) == 0); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + assert(func_version != 0); + if (f->func_version != func_version) { + UPDATE_MISS_STATS(LOAD_ATTR); + assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); + JUMP_TO_PREDICTED(LOAD_ATTR); + } + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 2); + if (!_PyThreadState_HasStackSpace(tstate, code->co_framesize)) { + UPDATE_MISS_STATS(LOAD_ATTR); + assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR)); + JUMP_TO_PREDICTED(LOAD_ATTR); + } + STAT_INC(LOAD_ATTR, hit); + PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1); + _PyInterpreterFrame *pushed_frame = _PyFrame_PushUnchecked( + tstate, PyStackRef_FromPyObjectNew(f), 2, frame); + pushed_frame->localsplus[0] = owner; + pushed_frame->localsplus[1] = PyStackRef_FromPyObjectNew(name); + new_frame = PyStackRef_Wrap(pushed_frame); + } + // _SAVE_RETURN_OFFSET + { + #if TIER_ONE + frame->return_offset = (uint16_t)(next_instr - this_instr); + #endif + #if TIER_TWO + frame->return_offset = oparg; + #endif + } + // _PUSH_FRAME + { + assert(!IS_PEP523_HOOKED(tstate)); + _PyInterpreterFrame *temp = PyStackRef_Unwrap(new_frame); + stack_pointer += -1; + ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__); + _PyFrame_SetStackPointer(frame, stack_pointer); + assert(temp->previous == frame || temp->previous->previous == frame); + CALL_STAT_INC(inlined_py_calls); + frame = tstate->current_frame = temp; + tstate->py_recursion_remaining--; + LOAD_SP(); + LOAD_IP(0); + LLTRACE_RESUME_FRAME(); + } + DISPATCH(); } TARGET(LOAD_ATTR_INSTANCE_VALUE) { diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index b10c1276f715e1..055e79ed9a3d14 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1016,6 +1016,27 @@ dummy_func(void) { new_frame = PyJitRef_WrapInvalid(f); } + op(_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME, (func_version/2, getattribute/4, owner -- new_frame)) { + PyFunctionObject *func = (PyFunctionObject *)getattribute; + if (sym_get_type_version(owner) == 0 || + func->func_version != func_version) { + ctx->contradiction = true; + ctx->done = true; + break; + } + _Py_BloomFilter_Add(dependencies, func); + PyCodeObject *co = (PyCodeObject *)func->func_code; + _Py_UOpsAbstractFrame *f = frame_new(ctx, co, NULL, 0); + if (f == NULL) { + break; + } + PyObject *name = get_co_name(ctx, oparg >> 1); + f->locals[0] = owner; + f->locals[1] = sym_new_const(ctx, name); + f->func = func; + new_frame = PyJitRef_WrapInvalid(f); + } + op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { PyObject *bound_method = sym_get_probable_value(callable); if (bound_method != NULL && Py_TYPE(bound_method) == &PyMethod_Type) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index fa0694d876159e..620ac604950c0b 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -2636,7 +2636,33 @@ break; } - /* _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN is not a viable micro-op for tier 2 */ + case _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN_FRAME: { + JitOptRef owner; + JitOptRef new_frame; + owner = stack_pointer[-1]; + uint32_t func_version = (uint32_t)this_instr->operand0; + PyObject *getattribute = (PyObject *)this_instr->operand1; + PyFunctionObject *func = (PyFunctionObject *)getattribute; + if (sym_get_type_version(owner) == 0 || + func->func_version != func_version) { + ctx->contradiction = true; + ctx->done = true; + break; + } + _Py_BloomFilter_Add(dependencies, func); + PyCodeObject *co = (PyCodeObject *)func->func_code; + _Py_UOpsAbstractFrame *f = frame_new(ctx, co, NULL, 0); + if (f == NULL) { + break; + } + PyObject *name = get_co_name(ctx, oparg >> 1); + f->locals[0] = owner; + f->locals[1] = sym_new_const(ctx, name); + f->func = func; + new_frame = PyJitRef_WrapInvalid(f); + stack_pointer[-1] = new_frame; + break; + } case _GUARD_DORV_NO_DICT: { break; diff --git a/Python/record_functions.c.h b/Python/record_functions.c.h index 25bca4735726fd..48181961aac582 100644 --- a/Python/record_functions.c.h +++ b/Python/record_functions.c.h @@ -110,6 +110,7 @@ const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = { [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}}, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = {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}}, From 11da7d4e210c6e358c65c7b2bf02360e7b6351ad Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Tue, 14 Apr 2026 23:46:54 +0800 Subject: [PATCH 08/12] gh-148047: Revert "GH-148047: Check early whether tail-calling is possible for MSVC builds on Windows (#148036)" (#148558) This reverts commit cbd81d59cfea4f7b881642e804646da3a328a712. --- .../Build/2026-04-03-20-09-46.gh-issue-148047.HE6iGK.rst | 2 -- PCbuild/pythoncore.vcxproj | 9 --------- 2 files changed, 11 deletions(-) delete mode 100644 Misc/NEWS.d/next/Build/2026-04-03-20-09-46.gh-issue-148047.HE6iGK.rst diff --git a/Misc/NEWS.d/next/Build/2026-04-03-20-09-46.gh-issue-148047.HE6iGK.rst b/Misc/NEWS.d/next/Build/2026-04-03-20-09-46.gh-issue-148047.HE6iGK.rst deleted file mode 100644 index e43a2695a1316e..00000000000000 --- a/Misc/NEWS.d/next/Build/2026-04-03-20-09-46.gh-issue-148047.HE6iGK.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fail fast with an explicit and clear error message if tail-calling is not -possible for MSVC builds on Windows. Patch by Chris Eibl. diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 9356a66dfb4642..61bee29c0af3d6 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -749,13 +749,4 @@ - - - - - - From 3cb7eaec857503e4e343ced1e82c0864e16da729 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Tue, 14 Apr 2026 21:32:23 +0530 Subject: [PATCH 09/12] gh-131798: constant fold special method lookups in JIT (#148432) --- Include/internal/pycore_opcode_metadata.h | 4 ++-- Lib/test/test_capi/test_opt.py | 19 +++++++++++++++++ Python/bytecodes.c | 1 + Python/optimizer_bytecodes.c | 26 +++++++++++++++++++++-- Python/optimizer_cases.c.h | 26 +++++++++++++++++++++-- Python/record_functions.c.h | 1 + 6 files changed, 71 insertions(+), 6 deletions(-) diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index be7105cef5310f..da12e2f087d808 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -1252,7 +1252,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = { [LOAD_LOCALS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG }, [LOAD_NAME] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SMALL_INT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG }, - [LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_SPECIAL] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG }, @@ -1472,7 +1472,7 @@ _PyOpcode_macro_expansion[256] = { [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, OPARG_SIMPLE, 0 } } }, [LOAD_NAME] = { .nuops = 1, .uops = { { _LOAD_NAME, OPARG_SIMPLE, 0 } } }, [LOAD_SMALL_INT] = { .nuops = 1, .uops = { { _LOAD_SMALL_INT, OPARG_SIMPLE, 0 } } }, - [LOAD_SPECIAL] = { .nuops = 2, .uops = { { _INSERT_NULL, OPARG_SIMPLE, 0 }, { _LOAD_SPECIAL, OPARG_SIMPLE, 0 } } }, + [LOAD_SPECIAL] = { .nuops = 3, .uops = { { _RECORD_TOS_TYPE, OPARG_SIMPLE, 0 }, { _INSERT_NULL, OPARG_SIMPLE, 0 }, { _LOAD_SPECIAL, OPARG_SIMPLE, 0 } } }, [LOAD_SUPER_ATTR_ATTR] = { .nuops = 1, .uops = { { _LOAD_SUPER_ATTR_ATTR, OPARG_SIMPLE, 1 } } }, [LOAD_SUPER_ATTR_METHOD] = { .nuops = 3, .uops = { { _RECORD_NOS, OPARG_SIMPLE, 0 }, { _GUARD_LOAD_SUPER_ATTR_METHOD, OPARG_SIMPLE, 1 }, { _LOAD_SUPER_ATTR_METHOD, OPARG_SIMPLE, 1 } } }, [MAKE_CELL] = { .nuops = 1, .uops = { { _MAKE_CELL, OPARG_SIMPLE, 0 } } }, diff --git a/Lib/test/test_capi/test_opt.py b/Lib/test/test_capi/test_opt.py index c144ab1106ccea..9c85f036b39ff4 100644 --- a/Lib/test/test_capi/test_opt.py +++ b/Lib/test/test_capi/test_opt.py @@ -3435,6 +3435,25 @@ def f(n): self.assertNotIn("_LOAD_ATTR_METHOD_NO_DICT", uops) self.assertIn("_LOAD_CONST_INLINE_BORROW", uops) + def test_cached_load_special(self): + class CM: + def __enter__(self): + return self + def __exit__(self, *args): + pass + def f(n): + cm = CM() + x = 0 + for _ in range(n): + with cm: + x += 1 + return x + res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD) + self.assertIsNotNone(ex) + self.assertEqual(res, TIER2_THRESHOLD) + uops = get_opnames(ex) + self.assertNotIn("_LOAD_SPECIAL", uops) + def test_store_fast_refcount_elimination(self): def foo(x): # Since x is known to be diff --git a/Python/bytecodes.c b/Python/bytecodes.c index dc21f084f74c49..6d51679884d57e 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3883,6 +3883,7 @@ dummy_func( } macro(LOAD_SPECIAL) = + _RECORD_TOS_TYPE + _INSERT_NULL + _LOAD_SPECIAL; diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 055e79ed9a3d14..76ce5cffb573e1 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -1845,8 +1845,30 @@ dummy_func(void) { } op(_LOAD_SPECIAL, (method_and_self[2] -- method_and_self[2])) { - method_and_self[0] = sym_new_not_null(ctx); - method_and_self[1] = sym_new_unknown(ctx); + bool optimized = false; + PyTypeObject *type = sym_get_probable_type(method_and_self[1]); + if (type != NULL) { + PyObject *name = _Py_SpecialMethods[oparg].name; + PyObject *descr = _PyType_Lookup(type, name); + if (descr != NULL && (Py_TYPE(descr)->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR)) { + ADD_OP(_GUARD_TYPE_VERSION, 0, type->tp_version_tag); + bool immortal = _Py_IsImmortal(descr) || (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE); + ADD_OP(immortal ? _LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE, + 0, (uintptr_t)descr); + ADD_OP(_SWAP, 3, 0); + ADD_OP(_POP_TOP, 0, 0); + if ((type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) { + PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type); + _Py_BloomFilter_Add(dependencies, type); + } + method_and_self[0] = sym_new_const(ctx, descr); + optimized = true; + } + } + if (!optimized) { + method_and_self[0] = sym_new_not_null(ctx); + method_and_self[1] = sym_new_unknown(ctx); + } } op(_JUMP_TO_TOP, (--)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 620ac604950c0b..547460e1a75581 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -3555,8 +3555,30 @@ case _LOAD_SPECIAL: { JitOptRef *method_and_self; method_and_self = &stack_pointer[-2]; - method_and_self[0] = sym_new_not_null(ctx); - method_and_self[1] = sym_new_unknown(ctx); + bool optimized = false; + PyTypeObject *type = sym_get_probable_type(method_and_self[1]); + if (type != NULL) { + PyObject *name = _Py_SpecialMethods[oparg].name; + PyObject *descr = _PyType_Lookup(type, name); + if (descr != NULL && (Py_TYPE(descr)->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR)) { + ADD_OP(_GUARD_TYPE_VERSION, 0, type->tp_version_tag); + bool immortal = _Py_IsImmortal(descr) || (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE); + ADD_OP(immortal ? _LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE, + 0, (uintptr_t)descr); + ADD_OP(_SWAP, 3, 0); + ADD_OP(_POP_TOP, 0, 0); + if ((type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) == 0) { + PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type); + _Py_BloomFilter_Add(dependencies, type); + } + method_and_self[0] = sym_new_const(ctx, descr); + optimized = true; + } + } + if (!optimized) { + method_and_self[0] = sym_new_not_null(ctx); + method_and_self[1] = sym_new_unknown(ctx); + } break; } diff --git a/Python/record_functions.c.h b/Python/record_functions.c.h index 48181961aac582..376dac501fe622 100644 --- a/Python/record_functions.c.h +++ b/Python/record_functions.c.h @@ -115,6 +115,7 @@ const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = { [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_SPECIAL] = {1, {_RECORD_TOS_TYPE_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}}, From 4286227308ee8dafc867062df4cad73af2a84696 Mon Sep 17 00:00:00 2001 From: Santi Hernandez Date: Tue, 14 Apr 2026 10:24:16 -0600 Subject: [PATCH 10/12] gh-72406: Document argument ordering in argparse help output (#148534) Co-authored-by: Savannah Ostrowski --- Doc/library/argparse.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 0091bf95f0cef0..e37afd6d0b6d5a 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -2032,6 +2032,9 @@ Argument groups Note that any arguments not in your user-defined groups will end up back in the usual "positional arguments" and "optional arguments" sections. + Within each argument group, arguments are displayed in help output in the + order in which they are added. + .. deprecated-removed:: 3.11 3.14 Calling :meth:`add_argument_group` on an argument group now raises an exception. This nesting was never supported, often failed to work From 356a031de504b0eb4b5a2024019cf5fe16de2831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 14 Apr 2026 19:12:47 +0200 Subject: [PATCH 11/12] gh-146563: add exception note for invalid Expat handler return values (#146565) --- Include/internal/pycore_pyerrors.h | 3 +- Lib/test/test_pyexpat.py | 28 +++++++++++++++++++ ...-03-28-11-31-32.gh-issue-146563.cXtSym.rst | 2 ++ Modules/pyexpat.c | 25 +++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-03-28-11-31-32.gh-issue-146563.cXtSym.rst diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h index 1023dbc3395b2f..e38472ab13a9df 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -29,7 +29,8 @@ PyAPI_FUNC(PyObject*) _PyErr_FormatFromCause( ... ); -extern int _PyException_AddNote( +// Export for 'pyexpat' shared extension. +PyAPI_FUNC(int) _PyException_AddNote( PyObject *exc, PyObject *note); diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index cace780f79f515..aaa91aca36e3c4 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -510,6 +510,34 @@ def _test_exception(self, have_source): self.assertIn('call_with_frame("StartElement"', entries[1].line) + def test_invalid_NotStandalone(self): + parser = expat.ParserCreate() + parser.NotStandaloneHandler = mock.Mock(return_value="bad value") + parser.ElementDeclHandler = lambda _1, _2: None + + payload = b"""\ +]> +""" + with self.assertRaises(TypeError) as cm: + parser.Parse(payload, True) + parser.NotStandaloneHandler.assert_called_once() + + notes = ["invalid 'NotStandalone' event handler return value"] + self.assertEqual(cm.exception.__notes__, notes) + + def test_invalid_ExternalEntityRefHandler(self): + parser = expat.ParserCreate() + parser.UseForeignDTD() + parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_ALWAYS) + parser.ExternalEntityRefHandler = mock.Mock(return_value=None) + + with self.assertRaises(TypeError) as cm: + parser.Parse(b"", True) + parser.ExternalEntityRefHandler.assert_called_once() + + notes = ["invalid 'ExternalEntityRef' event handler return value"] + self.assertEqual(cm.exception.__notes__, notes) + # Test Current* members: class PositionTest(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2026-03-28-11-31-32.gh-issue-146563.cXtSym.rst b/Misc/NEWS.d/next/Library/2026-03-28-11-31-32.gh-issue-146563.cXtSym.rst new file mode 100644 index 00000000000000..2103024b616d4e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-28-11-31-32.gh-issue-146563.cXtSym.rst @@ -0,0 +1,2 @@ +:mod:`xml.parsers.expat`: add an exception note when a custom Expat handler +return value cannot be properly interpreted. Patch by Bénédikt Tran. diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 31b883fe8bd548..0f0afe17513ef1 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -503,6 +503,28 @@ my_StartElementHandler(void *userData, } } +static inline void +invalid_expat_handler_rv(const char *name) +{ + PyObject *exc = PyErr_GetRaisedException(); + assert(exc != NULL); + PyObject *note = PyUnicode_FromFormat("invalid '%s' event handler return value", name); + if (note == NULL) { + goto error; + } + int rc = _PyException_AddNote(exc, note); + Py_DECREF(note); + if (rc < 0) { + goto error; + }; + goto done; + +error: + PyErr_Clear(); +done: + PyErr_SetRaisedException(exc); +} + #define RC_HANDLER(RETURN_TYPE, NAME, PARAMS, \ INIT, PARSE_FORMAT, CONVERSION, \ RETURN_VARIABLE, GETUSERDATA) \ @@ -536,6 +558,9 @@ my_ ## NAME ## Handler PARAMS { \ } \ CONVERSION \ Py_DECREF(rv); \ + if (PyErr_Occurred()) { \ + invalid_expat_handler_rv(#NAME); \ + } \ return RETURN_VARIABLE; \ } From bdb0b361926f225a06f1726c278c27346f3c524a Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:15:06 +0300 Subject: [PATCH 12/12] gh-86519: Update docs for `prefixmatch` (#148096) Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> --- Doc/howto/logging-cookbook.rst | 2 +- Doc/howto/regex.rst | 103 ++++++++++++++++----------------- Doc/library/fnmatch.rst | 5 +- Doc/library/glob.rst | 5 +- Doc/library/typing.rst | 2 +- 5 files changed, 58 insertions(+), 59 deletions(-) diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 21df6ba858d8c2..0ee4c0086dd98c 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -3877,7 +3877,7 @@ subclassed handler which looks something like this:: def format(self, record): version = 1 asctime = dt.datetime.fromtimestamp(record.created).isoformat() - m = self.tz_offset.match(time.strftime('%z')) + m = self.tz_offset.prefixmatch(time.strftime('%z')) has_offset = False if m and time.timezone: hrs, mins = m.groups() diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index 84ec535ca98e97..6fc087c3f1c367 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -362,12 +362,13 @@ for a complete listing. +------------------+-----------------------------------------------+ | Method/Attribute | Purpose | +==================+===============================================+ -| ``match()`` | Determine if the RE matches at the beginning | -| | of the string. | -+------------------+-----------------------------------------------+ | ``search()`` | Scan through a string, looking for any | | | location where this RE matches. | +------------------+-----------------------------------------------+ +| ``prefixmatch()``| Determine if the RE matches at the beginning | +| | of the string. Previously named :ref:`match() | +| | `. | ++------------------+-----------------------------------------------+ | ``findall()`` | Find all substrings where the RE matches, and | | | return them as a list. | +------------------+-----------------------------------------------+ @@ -375,7 +376,7 @@ for a complete listing. | | return them as an :term:`iterator`. | +------------------+-----------------------------------------------+ -:meth:`~re.Pattern.match` and :meth:`~re.Pattern.search` return ``None`` if no match can be found. If +:meth:`~re.Pattern.search` and :meth:`~re.Pattern.prefixmatch` return ``None`` if no match can be found. If they're successful, a :ref:`match object ` instance is returned, containing information about the match: where it starts and ends, the substring it matched, and more. @@ -393,19 +394,19 @@ Python interpreter, import the :mod:`re` module, and compile a RE:: Now, you can try matching various strings against the RE ``[a-z]+``. An empty string shouldn't match at all, since ``+`` means 'one or more repetitions'. -:meth:`~re.Pattern.match` should return ``None`` in this case, which will cause the +:meth:`~re.Pattern.search` should return ``None`` in this case, which will cause the interpreter to print no output. You can explicitly print the result of -:meth:`!match` to make this clear. :: +:meth:`!search` to make this clear. :: - >>> p.match("") - >>> print(p.match("")) + >>> p.search("") + >>> print(p.search("")) None Now, let's try it on a string that it should match, such as ``tempo``. In this -case, :meth:`~re.Pattern.match` will return a :ref:`match object `, so you +case, :meth:`~re.Pattern.search` will return a :ref:`match object `, so you should store the result in a variable for later use. :: - >>> m = p.match('tempo') + >>> m = p.search('tempo') >>> m @@ -437,27 +438,28 @@ Trying these methods will soon clarify their meaning:: :meth:`~re.Match.group` returns the substring that was matched by the RE. :meth:`~re.Match.start` and :meth:`~re.Match.end` return the starting and ending index of the match. :meth:`~re.Match.span` -returns both start and end indexes in a single tuple. Since the :meth:`~re.Pattern.match` -method only checks if the RE matches at the start of a string, :meth:`!start` -will always be zero. However, the :meth:`~re.Pattern.search` method of patterns -scans through the string, so the match may not start at zero in that -case. :: +returns both start and end indexes in a single tuple. +The :meth:`~re.Pattern.search` method of patterns +scans through the string, so the match may not start at zero. +However, the :meth:`~re.Pattern.prefixmatch` +method only checks if the RE matches at the start of a string, so :meth:`!start` +will always be zero in that case. :: - >>> print(p.match('::: message')) - None >>> m = p.search('::: message'); print(m) >>> m.group() 'message' >>> m.span() (4, 11) + >>> print(p.prefixmatch('::: message')) + None In actual programs, the most common style is to store the :ref:`match object ` in a variable, and then check if it was ``None``. This usually looks like:: p = re.compile( ... ) - m = p.match( 'string goes here' ) + m = p.search( 'string goes here' ) if m: print('Match found: ', m.group()) else: @@ -495,15 +497,15 @@ Module-level functions ---------------------- You don't have to create a pattern object and call its methods; the -:mod:`re` module also provides top-level functions called :func:`~re.match`, -:func:`~re.search`, :func:`~re.findall`, :func:`~re.sub`, and so forth. These functions +:mod:`re` module also provides top-level functions called :func:`~re.search`, +:func:`~re.prefixmatch`, :func:`~re.findall`, :func:`~re.sub`, and so forth. These functions take the same arguments as the corresponding pattern method with the RE string added as the first argument, and still return either ``None`` or a :ref:`match object ` instance. :: - >>> print(re.match(r'From\s+', 'Fromage amk')) + >>> print(re.prefixmatch(r'From\s+', 'Fromage amk')) None - >>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998') #doctest: +ELLIPSIS + >>> re.prefixmatch(r'From\s+', 'From amk Thu May 14 19:12:10 1998') #doctest: +ELLIPSIS Under the hood, these functions simply create a pattern object for you @@ -812,7 +814,7 @@ of a group with a quantifier, such as ``*``, ``+``, ``?``, or ``ab``. :: >>> p = re.compile('(ab)*') - >>> print(p.match('ababababab').span()) + >>> print(p.search('ababababab').span()) (0, 10) Groups indicated with ``'('``, ``')'`` also capture the starting and ending @@ -825,7 +827,7 @@ argument. Later we'll see how to express groups that don't capture the span of text that they match. :: >>> p = re.compile('(a)b') - >>> m = p.match('ab') + >>> m = p.search('ab') >>> m.group() 'ab' >>> m.group(0) @@ -836,7 +838,7 @@ to determine the number, just count the opening parenthesis characters, going from left to right. :: >>> p = re.compile('(a(b)c)d') - >>> m = p.match('abcd') + >>> m = p.search('abcd') >>> m.group(0) 'abcd' >>> m.group(1) @@ -912,10 +914,10 @@ but aren't interested in retrieving the group's contents. You can make this fact explicit by using a non-capturing group: ``(?:...)``, where you can replace the ``...`` with any other regular expression. :: - >>> m = re.match("([abc])+", "abc") + >>> m = re.search("([abc])+", "abc") >>> m.groups() ('c',) - >>> m = re.match("(?:[abc])+", "abc") + >>> m = re.search("(?:[abc])+", "abc") >>> m.groups() () @@ -949,7 +951,7 @@ given numbers, so you can retrieve information about a group in two ways:: Additionally, you can retrieve named groups as a dictionary with :meth:`~re.Match.groupdict`:: - >>> m = re.match(r'(?P\w+) (?P\w+)', 'Jane Doe') + >>> m = re.search(r'(?P\w+) (?P\w+)', 'Jane Doe') >>> m.groupdict() {'first': 'Jane', 'last': 'Doe'} @@ -1274,21 +1276,26 @@ In short, before turning to the :mod:`re` module, consider whether your problem can be solved with a faster and simpler string method. -match() versus search() ------------------------ +.. _match-versus-search: -The :func:`~re.match` function only checks if the RE matches at the beginning of the -string while :func:`~re.search` will scan forward through the string for a match. -It's important to keep this distinction in mind. Remember, :func:`!match` will -only report a successful match which will start at 0; if the match wouldn't -start at zero, :func:`!match` will *not* report it. :: +prefixmatch() (aka match) versus search() +----------------------------------------- - >>> print(re.match('super', 'superstition').span()) +:func:`~re.prefixmatch` was added in Python 3.15 as the :ref:`preferred name +` for :func:`~re.match`. Before this, it was only known +as :func:`!match` and the distinction with :func:`~re.search` was often +misunderstood. + +:func:`!prefixmatch` aka :func:`!match` only checks if the RE matches at the +beginning of the string while :func:`!search` scans forward through the +string for a match. :: + + >>> print(re.prefixmatch('super', 'superstition').span()) (0, 5) - >>> print(re.match('super', 'insuperable')) + >>> print(re.prefixmatch('super', 'insuperable')) None -On the other hand, :func:`~re.search` will scan forward through the string, +On the other hand, :func:`~re.search` scans forward through the string, reporting the first match it finds. :: >>> print(re.search('super', 'superstition').span()) @@ -1296,18 +1303,8 @@ reporting the first match it finds. :: >>> print(re.search('super', 'insuperable').span()) (2, 7) -Sometimes you'll be tempted to keep using :func:`re.match`, and just add ``.*`` -to the front of your RE. Resist this temptation and use :func:`re.search` -instead. The regular expression compiler does some analysis of REs in order to -speed up the process of looking for a match. One such analysis figures out what -the first character of a match must be; for example, a pattern starting with -``Crow`` must match starting with a ``'C'``. The analysis lets the engine -quickly scan through the string looking for the starting character, only trying -the full match if a ``'C'`` is found. - -Adding ``.*`` defeats this optimization, requiring scanning to the end of the -string and then backtracking to find a match for the rest of the RE. Use -:func:`re.search` instead. +This distinction is important to remember when using the old :func:`~re.match` +name in code requiring compatibility with older Python versions. Greedy versus non-greedy @@ -1322,9 +1319,9 @@ doesn't work because of the greedy nature of ``.*``. :: >>> s = 'Title' >>> len(s) 32 - >>> print(re.match('<.*>', s).span()) + >>> print(re.prefixmatch('<.*>', s).span()) (0, 32) - >>> print(re.match('<.*>', s).group()) + >>> print(re.prefixmatch('<.*>', s).group()) Title The RE matches the ``'<'`` in ``''``, and the ``.*`` consumes the rest of @@ -1340,7 +1337,7 @@ example, the ``'>'`` is tried immediately after the first ``'<'`` matches, and when it fails, the engine advances a character at a time, retrying the ``'>'`` at every step. This produces just the right result:: - >>> print(re.match('<.*?>', s).group()) + >>> print(re.prefixmatch('<.*?>', s).group()) (Note that parsing HTML or XML with regular expressions is painful. diff --git a/Doc/library/fnmatch.rst b/Doc/library/fnmatch.rst index ee654b7a83e203..a213679e4e2dd7 100644 --- a/Doc/library/fnmatch.rst +++ b/Doc/library/fnmatch.rst @@ -103,7 +103,8 @@ functions: :func:`fnmatch`, :func:`fnmatchcase`, :func:`.filter`, :func:`.filter .. function:: translate(pat) Return the shell-style pattern *pat* converted to a regular expression for - using with :func:`re.match`. The pattern is expected to be a :class:`str`. + using with :func:`re.prefixmatch`. The pattern is expected to be a + :class:`str`. Example: @@ -113,7 +114,7 @@ functions: :func:`fnmatch`, :func:`fnmatchcase`, :func:`.filter`, :func:`.filter >>> regex '(?s:.*\\.txt)\\z' >>> reobj = re.compile(regex) - >>> reobj.match('foobar.txt') + >>> reobj.prefixmatch('foobar.txt') diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index b24e4da7bc8c07..942f23d216fc07 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -140,7 +140,8 @@ The :mod:`!glob` module defines the following functions: .. function:: translate(pathname, *, recursive=False, include_hidden=False, seps=None) Convert the given path specification to a regular expression for use with - :func:`re.match`. The path specification can contain shell-style wildcards. + :func:`re.prefixmatch`. The path specification can contain shell-style + wildcards. For example: @@ -150,7 +151,7 @@ The :mod:`!glob` module defines the following functions: >>> regex '(?s:(?:.+/)?[^/]*\\.txt)\\z' >>> reobj = re.compile(regex) - >>> reobj.match('foo/bar/baz.txt') + >>> reobj.prefixmatch('foo/bar/baz.txt') Path separators and segments are meaningful to this function, unlike diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 09e9103e1b80d0..2ce868cf84da9d 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3797,7 +3797,7 @@ Aliases to other concrete types Match Deprecated aliases corresponding to the return types from - :func:`re.compile` and :func:`re.match`. + :func:`re.compile` and :func:`re.search`. These types (and the corresponding functions) are generic over :data:`AnyStr`. ``Pattern`` can be specialised as ``Pattern[str]`` or