aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/specialize.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/specialize.c')
-rw-r--r--Python/specialize.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/Python/specialize.c b/Python/specialize.c
index 98455ae3efc..2d514c0dc47 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -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;
}