mirror of
https://github.com/python/cpython.git
synced 2025-08-22 09:45:06 +00:00
GH-106485: Dematerialize instance dictionaries when possible (GH-106539)
This commit is contained in:
parent
a9caf9cf90
commit
326f0ba1c5
10 changed files with 88 additions and 24 deletions
|
@ -192,6 +192,7 @@ print_object_stats(FILE *out, ObjectStats *stats)
|
|||
fprintf(out, "Object materialize dict (new key): %" PRIu64 "\n", stats->dict_materialized_new_key);
|
||||
fprintf(out, "Object materialize dict (too big): %" PRIu64 "\n", stats->dict_materialized_too_big);
|
||||
fprintf(out, "Object materialize dict (str subclass): %" PRIu64 "\n", stats->dict_materialized_str_subclass);
|
||||
fprintf(out, "Object dematerialize dict: %" PRIu64 "\n", stats->dict_dematerialized);
|
||||
fprintf(out, "Object method cache hits: %" PRIu64 "\n", stats->type_cache_hits);
|
||||
fprintf(out, "Object method cache misses: %" PRIu64 "\n", stats->type_cache_misses);
|
||||
fprintf(out, "Object method cache collisions: %" PRIu64 "\n", stats->type_cache_collisions);
|
||||
|
@ -685,8 +686,10 @@ specialize_dict_access(
|
|||
return 0;
|
||||
}
|
||||
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
|
||||
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
|
||||
if (_PyDictOrValues_IsValues(dorv)) {
|
||||
PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
|
||||
if (_PyDictOrValues_IsValues(*dorv) ||
|
||||
_PyObject_MakeInstanceAttributesFromDict(owner, dorv))
|
||||
{
|
||||
// Virtual dictionary
|
||||
PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys;
|
||||
assert(PyUnicode_CheckExact(name));
|
||||
|
@ -704,12 +707,16 @@ specialize_dict_access(
|
|||
instr->op.code = values_op;
|
||||
}
|
||||
else {
|
||||
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
|
||||
PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(*dorv);
|
||||
if (dict == NULL || !PyDict_CheckExact(dict)) {
|
||||
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT);
|
||||
return 0;
|
||||
}
|
||||
// We found an instance with a __dict__.
|
||||
if (dict->ma_values) {
|
||||
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT);
|
||||
return 0;
|
||||
}
|
||||
Py_ssize_t index =
|
||||
_PyDict_LookupIndex(dict, name);
|
||||
if (index != (uint16_t)index) {
|
||||
|
@ -1100,9 +1107,11 @@ PyObject *descr, DescriptorClassification kind, bool is_method)
|
|||
assert(descr != NULL);
|
||||
assert((is_method && kind == METHOD) || (!is_method && kind == NON_DESCRIPTOR));
|
||||
if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
|
||||
PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
|
||||
PyDictOrValues *dorv = _PyObject_DictOrValuesPointer(owner);
|
||||
PyDictKeysObject *keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys;
|
||||
if (!_PyDictOrValues_IsValues(dorv)) {
|
||||
if (!_PyDictOrValues_IsValues(*dorv) &&
|
||||
!_PyObject_MakeInstanceAttributesFromDict(owner, dorv))
|
||||
{
|
||||
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue