@@ -1951,6 +1951,17 @@ build_indices_unicode(PyDictKeysObject *keys, PyDictUnicodeEntry *ep, Py_ssize_t
19511951 }
19521952}
19531953
1954+
1955+ static void
1956+ invalidate_and_clear_inline_values (PyDictValues * values )
1957+ {
1958+ assert (values -> embedded );
1959+ FT_ATOMIC_STORE_UINT8 (values -> valid , 0 );
1960+ for (int i = 0 ; i < values -> capacity ; i ++ ) {
1961+ FT_ATOMIC_STORE_PTR (values -> values [i ], NULL );
1962+ }
1963+ }
1964+
19541965/*
19551966Restructure the table by allocating a new table and reinserting all
19561967items again. When entries have been deleted, the new table may
@@ -2042,7 +2053,7 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp,
20422053 if (oldvalues -> embedded ) {
20432054 assert (oldvalues -> embedded == 1 );
20442055 assert (oldvalues -> valid == 1 );
2045- FT_ATOMIC_STORE_UINT8 (oldvalues -> valid , 0 );
2056+ invalidate_and_clear_inline_values (oldvalues );
20462057 }
20472058 else {
20482059 free_values (oldvalues , IS_DICT_SHARED (mp ));
@@ -7032,7 +7043,13 @@ _PyObject_TryGetInstanceAttribute(PyObject *obj, PyObject *name, PyObject **attr
70327043
70337044#ifdef Py_GIL_DISABLED
70347045 PyObject * value = _Py_atomic_load_ptr_acquire (& values -> values [ix ]);
7035- if (value == NULL || _Py_TryIncrefCompare (& values -> values [ix ], value )) {
7046+ if (value == NULL ) {
7047+ if (FT_ATOMIC_LOAD_UINT8 (values -> valid )) {
7048+ * attr = NULL ;
7049+ return true;
7050+ }
7051+ }
7052+ else if (_Py_TryIncrefCompare (& values -> values [ix ], value )) {
70367053 * attr = value ;
70377054 return true;
70387055 }
@@ -7370,7 +7387,7 @@ _PyDict_DetachFromObject(PyDictObject *mp, PyObject *obj)
73707387 }
73717388 mp -> ma_values = values ;
73727389
7373- FT_ATOMIC_STORE_UINT8 (_PyObject_InlineValues (obj )-> valid , 0 );
7390+ invalidate_and_clear_inline_values (_PyObject_InlineValues (obj ));
73747391
73757392 assert (_PyObject_InlineValuesConsistencyCheck (obj ));
73767393 ASSERT_CONSISTENT (mp );
0 commit comments