gh-100288: Specialise LOAD_ATTR_METHOD for managed dictionaries (GH-1… · python/cpython@c3c7848 (original) (raw)

`@@ -335,7 +335,6 @@ _PyCode_Quicken(PyCodeObject *code)

`

335

335

`#define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD 22

`

336

336

`#define SPEC_FAIL_ATTR_CLASS_METHOD_OBJ 23

`

337

337

`#define SPEC_FAIL_ATTR_OBJECT_SLOT 24

`

338

``

`-

#define SPEC_FAIL_ATTR_HAS_MANAGED_DICT 25

`

339

338

`#define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26

`

340

339

`#define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27

`

341

340

`#define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28

`

`@@ -1036,11 +1035,14 @@ PyObject *descr, DescriptorClassification kind)

`

1036

1035

`PyDictKeysObject *keys;

`

1037

1036

`if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) {

`

1038

1037

`PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);

`

1039

``

`-

keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys;

`

1040

1038

`if (_PyDictOrValues_IsValues(dorv)) {

`

``

1039

`+

keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys;

`

1041

1040

`dictkind = MANAGED_VALUES;

`

1042

1041

` }

`

1043

1042

`else {

`

``

1043

`+

PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);

`

``

1044

`+

keys = dict != NULL ? dict->ma_keys : NULL;

`

``

1045

`+

// User has directly accessed dict.

`

1044

1046

`dictkind = MANAGED_DICT;

`

1045

1047

` }

`

1046

1048

` }

`

`@@ -1067,7 +1069,7 @@ PyObject *descr, DescriptorClassification kind)

`

1067

1069

` }

`

1068

1070

` }

`

1069

1071

` }

`

1070

``

`-

if (dictkind == MANAGED_VALUES || dictkind == OFFSET_DICT) {

`

``

1072

`+

if (dictkind == MANAGED_VALUES || dictkind == OFFSET_DICT || (dictkind == MANAGED_DICT && keys != NULL)) {

`

1071

1073

`Py_ssize_t index = _PyDictKeys_StringLookup(keys, name);

`

1072

1074

`if (index != DKIX_EMPTY) {

`

1073

1075

`SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_SHADOWED);

`

`@@ -1088,8 +1090,11 @@ PyObject *descr, DescriptorClassification kind)

`

1088

1090

`_py_set_opcode(instr, LOAD_ATTR_METHOD_WITH_VALUES);

`

1089

1091

`break;

`

1090

1092

`case MANAGED_DICT:

`

1091

``

`-

SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT);

`

1092

``

`-

goto fail;

`

``

1093

`+

if (keys == NULL) {

`

``

1094

`+

write_u32(cache->keys_version, 0);

`

``

1095

`+

}

`

``

1096

`+

_py_set_opcode(instr, LOAD_ATTR_METHOD_MANAGED_DICT);

`

``

1097

`+

break;

`

1093

1098

`case OFFSET_DICT:

`

1094

1099

`assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX);

`

1095

1100

`_py_set_opcode(instr, LOAD_ATTR_METHOD_WITH_DICT);

`