Skip to content

Commit 945b61c

Browse files
committed
Split specialize_dict_access
1 parent ca1e232 commit 945b61c

File tree

1 file changed

+62
-42
lines changed

1 file changed

+62
-42
lines changed

Python/specialize.c

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,64 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, unsigne
965965
return classify_descriptor(descriptor, has_getattr);
966966
}
967967

968+
static int
969+
specialize_inline_values_access(
970+
PyObject *owner, _Py_CODEUNIT *instr, PyTypeObject *type,
971+
PyObject *name, int base_op, int values_op)
972+
{
973+
PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys;
974+
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
975+
assert(PyUnicode_CheckExact(name));
976+
Py_ssize_t index = _PyDictKeys_StringLookup(keys, name);
977+
assert (index != DKIX_ERROR);
978+
if (index == DKIX_EMPTY) {
979+
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_IN_KEYS);
980+
return 0;
981+
}
982+
assert(index >= 0);
983+
char *value_addr = (char *)&_PyObject_InlineValues(owner)->values[index];
984+
Py_ssize_t offset = value_addr - (char *)owner;
985+
if (offset != (uint16_t)offset) {
986+
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE);
987+
return 0;
988+
}
989+
write_u32(cache->version, type->tp_version_tag);
990+
cache->index = (uint16_t)offset;
991+
specialize(instr, values_op);
992+
return 1;
993+
}
994+
995+
static int
996+
specialize_managed_dict_access(
997+
PyObject *owner, _Py_CODEUNIT *instr, PyTypeObject *type,
998+
PyObject *name, int base_op, int hint_op)
999+
{
1000+
PyDictObject *dict = _PyObject_GetManagedDict(owner);
1001+
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
1002+
if (dict == NULL || !PyDict_CheckExact(dict)) {
1003+
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT);
1004+
return 0;
1005+
}
1006+
// We found an instance with a __dict__.
1007+
if (dict->ma_values) {
1008+
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_SPLIT_DICT);
1009+
return 0;
1010+
}
1011+
Py_ssize_t index =
1012+
_PyDict_LookupIndex(dict, name);
1013+
if (index != (uint16_t)index) {
1014+
SPECIALIZATION_FAIL(base_op,
1015+
index == DKIX_EMPTY ?
1016+
SPEC_FAIL_ATTR_NOT_IN_DICT :
1017+
SPEC_FAIL_OUT_OF_RANGE);
1018+
return 0;
1019+
}
1020+
cache->index = (uint16_t)index;
1021+
write_u32(cache->version, type->tp_version_tag);
1022+
specialize(instr, hint_op);
1023+
return 1;
1024+
}
1025+
9681026
static int
9691027
specialize_dict_access(
9701028
PyObject *owner, _Py_CODEUNIT *instr, PyTypeObject *type,
@@ -979,55 +1037,17 @@ specialize_dict_access(
9791037
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_MANAGED_DICT);
9801038
return 0;
9811039
}
982-
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
9831040
if (type->tp_flags & Py_TPFLAGS_INLINE_VALUES &&
9841041
_PyObject_InlineValues(owner)->valid &&
9851042
!(base_op == STORE_ATTR && _PyObject_GetManagedDict(owner) != NULL))
9861043
{
987-
PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys;
988-
assert(PyUnicode_CheckExact(name));
989-
Py_ssize_t index = _PyDictKeys_StringLookup(keys, name);
990-
assert (index != DKIX_ERROR);
991-
if (index == DKIX_EMPTY) {
992-
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NOT_IN_KEYS);
993-
return 0;
994-
}
995-
assert(index >= 0);
996-
char *value_addr = (char *)&_PyObject_InlineValues(owner)->values[index];
997-
Py_ssize_t offset = value_addr - (char *)owner;
998-
if (offset != (uint16_t)offset) {
999-
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE);
1000-
return 0;
1001-
}
1002-
write_u32(cache->version, type->tp_version_tag);
1003-
cache->index = (uint16_t)offset;
1004-
specialize(instr, values_op);
1044+
return specialize_inline_values_access(
1045+
owner, instr, type, name, base_op, values_op);
10051046
}
10061047
else {
1007-
PyDictObject *dict = _PyObject_GetManagedDict(owner);
1008-
if (dict == NULL || !PyDict_CheckExact(dict)) {
1009-
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT);
1010-
return 0;
1011-
}
1012-
// We found an instance with a __dict__.
1013-
if (dict->ma_values) {
1014-
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_SPLIT_DICT);
1015-
return 0;
1016-
}
1017-
Py_ssize_t index =
1018-
_PyDict_LookupIndex(dict, name);
1019-
if (index != (uint16_t)index) {
1020-
SPECIALIZATION_FAIL(base_op,
1021-
index == DKIX_EMPTY ?
1022-
SPEC_FAIL_ATTR_NOT_IN_DICT :
1023-
SPEC_FAIL_OUT_OF_RANGE);
1024-
return 0;
1025-
}
1026-
cache->index = (uint16_t)index;
1027-
write_u32(cache->version, type->tp_version_tag);
1028-
specialize(instr, hint_op);
1048+
return specialize_managed_dict_access(
1049+
owner, instr, type, name, base_op, hint_op);
10291050
}
1030-
return 1;
10311051
}
10321052

10331053
static int

0 commit comments

Comments
 (0)