@@ -192,6 +192,7 @@ print_object_stats(FILE *out, ObjectStats *stats)
192192 fprintf (out , "Object materialize dict (new key): %" PRIu64 "\n" , stats -> dict_materialized_new_key );
193193 fprintf (out , "Object materialize dict (too big): %" PRIu64 "\n" , stats -> dict_materialized_too_big );
194194 fprintf (out , "Object materialize dict (str subclass): %" PRIu64 "\n" , stats -> dict_materialized_str_subclass );
195+ fprintf (out , "Object dematerialize dict: %" PRIu64 "\n" , stats -> dict_dematerialized );
195196 fprintf (out , "Object method cache hits: %" PRIu64 "\n" , stats -> type_cache_hits );
196197 fprintf (out , "Object method cache misses: %" PRIu64 "\n" , stats -> type_cache_misses );
197198 fprintf (out , "Object method cache collisions: %" PRIu64 "\n" , stats -> type_cache_collisions );
@@ -685,8 +686,10 @@ specialize_dict_access(
685686 return 0 ;
686687 }
687688 _PyAttrCache * cache = (_PyAttrCache * )(instr + 1 );
688- PyDictOrValues dorv = * _PyObject_DictOrValuesPointer (owner );
689- if (_PyDictOrValues_IsValues (dorv )) {
689+ PyDictOrValues * dorv = _PyObject_DictOrValuesPointer (owner );
690+ if (_PyDictOrValues_IsValues (* dorv ) ||
691+ _PyObject_MakeInstanceAttributesFromDict (owner , dorv ))
692+ {
690693 // Virtual dictionary
691694 PyDictKeysObject * keys = ((PyHeapTypeObject * )type )-> ht_cached_keys ;
692695 assert (PyUnicode_CheckExact (name ));
@@ -704,12 +707,16 @@ specialize_dict_access(
704707 instr -> op .code = values_op ;
705708 }
706709 else {
707- PyDictObject * dict = (PyDictObject * )_PyDictOrValues_GetDict (dorv );
710+ PyDictObject * dict = (PyDictObject * )_PyDictOrValues_GetDict (* dorv );
708711 if (dict == NULL || !PyDict_CheckExact (dict )) {
709712 SPECIALIZATION_FAIL (base_op , SPEC_FAIL_NO_DICT );
710713 return 0 ;
711714 }
712715 // We found an instance with a __dict__.
716+ if (dict -> ma_values ) {
717+ SPECIALIZATION_FAIL (base_op , SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT );
718+ return 0 ;
719+ }
713720 Py_ssize_t index =
714721 _PyDict_LookupIndex (dict , name );
715722 if (index != (uint16_t )index ) {
@@ -1100,9 +1107,11 @@ PyObject *descr, DescriptorClassification kind, bool is_method)
11001107 assert (descr != NULL );
11011108 assert ((is_method && kind == METHOD ) || (!is_method && kind == NON_DESCRIPTOR ));
11021109 if (owner_cls -> tp_flags & Py_TPFLAGS_MANAGED_DICT ) {
1103- PyDictOrValues dorv = * _PyObject_DictOrValuesPointer (owner );
1110+ PyDictOrValues * dorv = _PyObject_DictOrValuesPointer (owner );
11041111 PyDictKeysObject * keys = ((PyHeapTypeObject * )owner_cls )-> ht_cached_keys ;
1105- if (!_PyDictOrValues_IsValues (dorv )) {
1112+ if (!_PyDictOrValues_IsValues (* dorv ) &&
1113+ !_PyObject_MakeInstanceAttributesFromDict (owner , dorv ))
1114+ {
11061115 SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_HAS_MANAGED_DICT );
11071116 return 0 ;
11081117 }
0 commit comments