@@ -1039,14 +1039,6 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
1039
1039
}
1040
1040
}
1041
1041
1042
- typedef enum {
1043
- MANAGED_VALUES = 1 ,
1044
- MANAGED_DICT = 2 ,
1045
- OFFSET_DICT = 3 ,
1046
- NO_DICT = 4 ,
1047
- LAZY_DICT = 5 ,
1048
- } ObjectDictKind ;
1049
-
1050
1042
// Please collect stats carefully before and after modifying. A subtle change
1051
1043
// can cause a significant drop in cache hits. A possible test is
1052
1044
// python.exe -m test_typing test_re test_dis test_zlib.
@@ -1058,71 +1050,45 @@ PyObject *descr, DescriptorClassification kind)
1058
1050
PyTypeObject * owner_cls = Py_TYPE (owner );
1059
1051
1060
1052
assert (kind == METHOD && descr != NULL );
1061
- ObjectDictKind dictkind ;
1062
- PyDictKeysObject * keys ;
1063
1053
if (owner_cls -> tp_flags & Py_TPFLAGS_MANAGED_DICT ) {
1064
1054
PyDictOrValues dorv = * _PyObject_DictOrValuesPointer (owner );
1065
- keys = ((PyHeapTypeObject * )owner_cls )-> ht_cached_keys ;
1066
- if (_PyDictOrValues_IsValues (dorv )) {
1067
- dictkind = MANAGED_VALUES ;
1068
- }
1069
- else {
1070
- dictkind = MANAGED_DICT ;
1071
- }
1072
- }
1073
- else {
1074
- Py_ssize_t dictoffset = owner_cls -> tp_dictoffset ;
1075
- if (dictoffset < 0 || dictoffset > INT16_MAX ) {
1076
- SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OUT_OF_RANGE );
1077
- goto fail ;
1078
- }
1079
- if (dictoffset == 0 ) {
1080
- dictkind = NO_DICT ;
1081
- keys = NULL ;
1082
- }
1083
- else {
1084
- PyObject * dict = * (PyObject * * ) ((char * )owner + dictoffset );
1085
- if (dict == NULL ) {
1086
- // This object will have a dict if user access __dict__
1087
- dictkind = LAZY_DICT ;
1088
- keys = NULL ;
1089
- }
1090
- else {
1091
- keys = ((PyDictObject * )dict )-> ma_keys ;
1092
- dictkind = OFFSET_DICT ;
1093
- }
1055
+ PyDictKeysObject * keys = ((PyHeapTypeObject * )owner_cls )-> ht_cached_keys ;
1056
+ if (!_PyDictOrValues_IsValues (dorv )) {
1057
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_HAS_MANAGED_DICT );
1058
+ return 0 ;
1094
1059
}
1095
- }
1096
- if (dictkind == MANAGED_VALUES || dictkind == OFFSET_DICT ) {
1097
1060
Py_ssize_t index = _PyDictKeys_StringLookup (keys , name );
1098
1061
if (index != DKIX_EMPTY ) {
1099
1062
SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_SHADOWED );
1100
- goto fail ;
1063
+ return 0 ;
1101
1064
}
1102
1065
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState (keys );
1103
1066
if (keys_version == 0 ) {
1104
1067
SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OUT_OF_VERSIONS );
1105
- goto fail ;
1068
+ return 0 ;
1106
1069
}
1107
1070
write_u32 (cache -> keys_version , keys_version );
1071
+ _py_set_opcode (instr , LOAD_ATTR_METHOD_WITH_VALUES );
1108
1072
}
1109
- switch (dictkind ) {
1110
- case NO_DICT :
1073
+ else {
1074
+ Py_ssize_t dictoffset = owner_cls -> tp_dictoffset ;
1075
+ if (dictoffset < 0 || dictoffset > INT16_MAX ) {
1076
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OUT_OF_RANGE );
1077
+ return 0 ;
1078
+ }
1079
+ if (dictoffset == 0 ) {
1111
1080
_py_set_opcode (instr , LOAD_ATTR_METHOD_NO_DICT );
1112
- break ;
1113
- case MANAGED_VALUES :
1114
- _py_set_opcode (instr , LOAD_ATTR_METHOD_WITH_VALUES );
1115
- break ;
1116
- case MANAGED_DICT :
1117
- SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_HAS_MANAGED_DICT );
1118
- goto fail ;
1119
- case OFFSET_DICT :
1120
- SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_NOT_MANAGED_DICT );
1121
- goto fail ;
1122
- case LAZY_DICT :
1123
- assert (owner_cls -> tp_dictoffset > 0 && owner_cls -> tp_dictoffset <= INT16_MAX );
1081
+ }
1082
+ else {
1083
+ PyObject * dict = * (PyObject * * ) ((char * )owner + dictoffset );
1084
+ if (dict ) {
1085
+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_NOT_MANAGED_DICT );
1086
+ return 0 ;
1087
+ }
1088
+ assert (owner_cls -> tp_dictoffset > 0 );
1089
+ assert (owner_cls -> tp_dictoffset <= INT16_MAX );
1124
1090
_py_set_opcode (instr , LOAD_ATTR_METHOD_LAZY_DICT );
1125
- break ;
1091
+ }
1126
1092
}
1127
1093
/* `descr` is borrowed. This is safe for methods (even inherited ones from
1128
1094
* super classes!) as long as tp_version_tag is validated for two main reasons:
@@ -1141,8 +1107,6 @@ PyObject *descr, DescriptorClassification kind)
1141
1107
write_u32 (cache -> type_version , owner_cls -> tp_version_tag );
1142
1108
write_obj (cache -> descr , descr );
1143
1109
return 1 ;
1144
- fail :
1145
- return 0 ;
1146
1110
}
1147
1111
1148
1112
void
0 commit comments