https://github.com/python/cpython/commit/2ca6333065b4cffac7b976e9abeb95f37dd0f727
commit: 2ca6333065b4cffac7b976e9abeb95f37dd0f727
branch: main
author: Neko Asakura <[email protected]>
committer: Fidget-Spinner <[email protected]>
date: 2026-05-02T15:45:38+01:00
summary:

gh-148380: remove all uses of `_PyType_LookupByVersion` in 
`optimizer_bytecodes.c` (GH-148394)

files:
M Include/internal/pycore_opcode_metadata.h
M Python/bytecodes.c
M Python/optimizer_bytecodes.c
M Python/optimizer_cases.c.h
M Python/record_functions.c.h

diff --git a/Include/internal/pycore_opcode_metadata.h 
b/Include/internal/pycore_opcode_metadata.h
index 230335ead3a3b6..4f8b48db23d1ef 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1236,7 +1236,7 @@ const struct opcode_metadata 
_PyOpcode_opcode_metadata[267] = {
     [LIST_APPEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
     [LIST_EXTEND] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | 
HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
     [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] = { true, INSTR_FMT_IBC00000000, HAS_ARG_FLAG | 
HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_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_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 },
@@ -1460,8 +1460,8 @@ _PyOpcode_macro_expansion[256] = {
     [LIST_APPEND] = { .nuops = 1, .uops = { { _LIST_APPEND, OPARG_SIMPLE, 0 } 
} },
     [LIST_EXTEND] = { .nuops = 2, .uops = { { _LIST_EXTEND, OPARG_SIMPLE, 0 }, 
{ _POP_TOP, OPARG_SIMPLE, 0 } } },
     [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_CLASS] = { .nuops = 4, .uops = { { _RECORD_TOS, OPARG_SIMPLE, 1 
}, { _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, 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 } } },
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index d485172c82fa0d..4239ba58bc390b 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -2984,6 +2984,7 @@ dummy_func(
 
         macro(LOAD_ATTR_CLASS) =
             unused/1 +
+            _RECORD_TOS +
             _CHECK_ATTR_CLASS +
             unused/2 +
             _LOAD_ATTR_CLASS +
@@ -2991,7 +2992,7 @@ dummy_func(
 
         macro(LOAD_ATTR_CLASS_WITH_METACLASS_CHECK) =
             unused/1 +
-            _RECORD_TOS_TYPE +
+            _RECORD_TOS +
             _GUARD_TYPE_VERSION +
             _CHECK_ATTR_CLASS +
             _LOAD_ATTR_CLASS +
diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c
index 33b5257fd58281..83ecbf0ec12907 100644
--- a/Python/optimizer_bytecodes.c
+++ b/Python/optimizer_bytecodes.c
@@ -229,8 +229,8 @@ dummy_func(void) {
     }
 
     op(_CHECK_ATTR_CLASS, (type_version/2, owner -- owner)) {
-        PyObject *type = (PyObject *)_PyType_LookupByVersion(type_version);
-        if (type) {
+        PyObject *type = sym_get_probable_value(owner);
+        if (type != NULL && ((PyTypeObject *)type)->tp_version_tag == 
type_version) {
             if (type == sym_get_const(ctx, owner)) {
                 ADD_OP(_NOP, 0, 0);
             }
@@ -246,7 +246,7 @@ dummy_func(void) {
 
     op(_GUARD_TYPE_VERSION, (type_version/2, owner -- owner)) {
         assert(type_version);
-        assert(this_instr[-1].opcode == _RECORD_TOS_TYPE);
+        assert(this_instr[-1].opcode == _RECORD_TOS_TYPE || 
this_instr[-1].opcode == _RECORD_TOS);
         if (sym_matches_type_version(owner, type_version)) {
             ADD_OP(_NOP, 0, 0);
         }
diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h
index 8f208beb86476b..39e98634a6e9c2 100644
--- a/Python/optimizer_cases.c.h
+++ b/Python/optimizer_cases.c.h
@@ -2518,7 +2518,7 @@
             owner = stack_pointer[-1];
             uint32_t type_version = (uint32_t)this_instr->operand0;
             assert(type_version);
-            assert(this_instr[-1].opcode == _RECORD_TOS_TYPE);
+            assert(this_instr[-1].opcode == _RECORD_TOS_TYPE || 
this_instr[-1].opcode == _RECORD_TOS);
             if (sym_matches_type_version(owner, type_version)) {
                 ADD_OP(_NOP, 0, 0);
             }
@@ -2676,8 +2676,8 @@
             JitOptRef owner;
             owner = stack_pointer[-1];
             uint32_t type_version = (uint32_t)this_instr->operand0;
-            PyObject *type = (PyObject *)_PyType_LookupByVersion(type_version);
-            if (type) {
+            PyObject *type = sym_get_probable_value(owner);
+            if (type != NULL && ((PyTypeObject *)type)->tp_version_tag == 
type_version) {
                 if (type == sym_get_const(ctx, owner)) {
                     ADD_OP(_NOP, 0, 0);
                 }
diff --git a/Python/record_functions.c.h b/Python/record_functions.c.h
index 504f6e1d9901c3..3163f45f4bb751 100644
--- a/Python/record_functions.c.h
+++ b/Python/record_functions.c.h
@@ -101,10 +101,11 @@ void _PyOpcode_RecordFunction_CODE(_PyInterpreterFrame 
*frame, _PyStackRef *stac
 #define _RECORD_TOS_TYPE_INDEX 1
 #define _RECORD_NOS_INDEX 2
 #define _RECORD_3OS_GEN_FUNC_INDEX 3
-#define _RECORD_NOS_GEN_FUNC_INDEX 4
-#define _RECORD_CALLABLE_INDEX 5
-#define _RECORD_CALLABLE_KW_INDEX 6
-#define _RECORD_4OS_INDEX 7
+#define _RECORD_TOS_INDEX 4
+#define _RECORD_NOS_GEN_FUNC_INDEX 5
+#define _RECORD_CALLABLE_INDEX 6
+#define _RECORD_CALLABLE_KW_INDEX 7
+#define _RECORD_4OS_INDEX 8
 
 const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = {
         [TO_BOOL_BOOL] = {1, {_RECORD_TOS_TYPE_INDEX}},
@@ -136,15 +137,15 @@ const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = 
{
         [STORE_ATTR] = {1, {_RECORD_TOS_TYPE_INDEX}},
         [LOAD_SUPER_ATTR] = {1, {_RECORD_NOS_INDEX}},
         [LOAD_SUPER_ATTR_METHOD] = {1, {_RECORD_NOS_INDEX}},
-        [LOAD_ATTR] = {1, {_RECORD_TOS_TYPE_INDEX}},
-        [LOAD_ATTR_INSTANCE_VALUE] = {1, {_RECORD_TOS_TYPE_INDEX}},
-        [LOAD_ATTR_MODULE] = {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] = {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}},
+        [LOAD_ATTR] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_INSTANCE_VALUE] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_MODULE] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_WITH_HINT] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_SLOT] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_CLASS] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_PROPERTY] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = {1, {_RECORD_TOS_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}},
@@ -158,11 +159,11 @@ const _PyOpcodeRecordEntry _PyOpcode_RecordEntries[256] = 
{
         [FOR_ITER_RANGE] = {1, {_RECORD_NOS_GEN_FUNC_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}},
-        [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = {1, {_RECORD_TOS_TYPE_INDEX}},
-        [LOAD_ATTR_METHOD_LAZY_DICT] = {1, {_RECORD_TOS_TYPE_INDEX}},
+        [LOAD_ATTR_METHOD_WITH_VALUES] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_METHOD_NO_DICT] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = {1, {_RECORD_TOS_INDEX}},
+        [LOAD_ATTR_METHOD_LAZY_DICT] = {1, {_RECORD_TOS_INDEX}},
         [CALL] = {1, {_RECORD_CALLABLE_INDEX}},
         [CALL_PY_GENERAL] = {1, {_RECORD_CALLABLE_INDEX}},
         [CALL_BOUND_METHOD_GENERAL] = {1, {_RECORD_CALLABLE_INDEX}},
@@ -199,12 +200,13 @@ const _PyOpcodeRecordSlotMap 
_PyOpcode_RecordSlotMaps[256] = {
         [BINARY_OP_SUBSCR_GETITEM] = {1, 0, {0}},
         [SEND_GEN] = {1, 0, {0}},
         [LOAD_SUPER_ATTR_METHOD] = {1, 0, {0}},
-        [LOAD_ATTR_INSTANCE_VALUE] = {1, 0, {0}},
-        [LOAD_ATTR_WITH_HINT] = {1, 0, {0}},
-        [LOAD_ATTR_SLOT] = {1, 0, {0}},
+        [LOAD_ATTR_INSTANCE_VALUE] = {1, 1, {0}},
+        [LOAD_ATTR_WITH_HINT] = {1, 1, {0}},
+        [LOAD_ATTR_SLOT] = {1, 1, {0}},
+        [LOAD_ATTR_CLASS] = {1, 0, {0}},
         [LOAD_ATTR_CLASS_WITH_METACLASS_CHECK] = {1, 0, {0}},
-        [LOAD_ATTR_PROPERTY] = {1, 0, {0}},
-        [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = {1, 0, {0}},
+        [LOAD_ATTR_PROPERTY] = {1, 1, {0}},
+        [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = {1, 1, {0}},
         [STORE_ATTR_INSTANCE_VALUE] = {1, 0, {0}},
         [STORE_ATTR_WITH_HINT] = {1, 0, {0}},
         [STORE_ATTR_SLOT] = {1, 0, {0}},
@@ -213,11 +215,11 @@ const _PyOpcodeRecordSlotMap 
_PyOpcode_RecordSlotMaps[256] = {
         [GET_ITER_VIRTUAL] = {1, 0, {0}},
         [FOR_ITER_GEN] = {1, 0, {0}},
         [LOAD_SPECIAL] = {1, 0, {0}},
-        [LOAD_ATTR_METHOD_WITH_VALUES] = {1, 0, {0}},
-        [LOAD_ATTR_METHOD_NO_DICT] = {1, 0, {0}},
-        [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = {1, 0, {0}},
-        [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = {1, 0, {0}},
-        [LOAD_ATTR_METHOD_LAZY_DICT] = {1, 0, {0}},
+        [LOAD_ATTR_METHOD_WITH_VALUES] = {1, 1, {0}},
+        [LOAD_ATTR_METHOD_NO_DICT] = {1, 1, {0}},
+        [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = {1, 1, {0}},
+        [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = {1, 1, {0}},
+        [LOAD_ATTR_METHOD_LAZY_DICT] = {1, 1, {0}},
         [CALL_PY_GENERAL] = {1, 0, {0}},
         [CALL_BOUND_METHOD_GENERAL] = {1, 1, {0}},
         [CALL_NON_PY_GENERAL] = {1, 0, {0}},
@@ -237,11 +239,12 @@ const _PyOpcodeRecordSlotMap 
_PyOpcode_RecordSlotMaps[256] = {
         [BINARY_OP] = {2, 2, {1, 0}},
 };
 
-const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[8] = {
+const _Py_RecordFuncPtr _PyOpcode_RecordFunctions[9] = {
         [0] = NULL,
         [_RECORD_TOS_TYPE_INDEX] = _PyOpcode_RecordFunction_TOS_TYPE,
         [_RECORD_NOS_INDEX] = _PyOpcode_RecordFunction_NOS,
         [_RECORD_3OS_GEN_FUNC_INDEX] = _PyOpcode_RecordFunction_3OS_GEN_FUNC,
+        [_RECORD_TOS_INDEX] = _PyOpcode_RecordFunction_TOS,
         [_RECORD_NOS_GEN_FUNC_INDEX] = _PyOpcode_RecordFunction_NOS_GEN_FUNC,
         [_RECORD_CALLABLE_INDEX] = _PyOpcode_RecordFunction_CALLABLE,
         [_RECORD_CALLABLE_KW_INDEX] = _PyOpcode_RecordFunction_CALLABLE_KW,

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to