diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index f33026dbd6be586..c4321c793cc2dda 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -105,7 +105,7 @@ PyAPI_FUNC(PyObject *)_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObjec /* Consumes references to key and value */ PyAPI_FUNC(int) _PyDict_SetItem_Take2(PyDictObject *op, PyObject *key, PyObject *value); -extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value); +extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr, PyObject *name, PyObject *value); extern int _PyDict_Pop_KnownHash( PyDictObject *dict, diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 1f21f70f149c803..b91a8dddbc50ec3 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -7213,7 +7213,7 @@ PyObject_GenericGetDict(PyObject *obj, void *context) } int -_PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, +_PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr, PyObject *key, PyObject *value) { PyObject *dict; @@ -7222,37 +7222,36 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyInterpreterState *interp = _PyInterpreterState_GET(); assert(dictptr != NULL); - if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) { - assert(dictptr != NULL); + dict = *dictptr; + if (dict == NULL) { +#ifdef Py_GIL_DISABLED + Py_BEGIN_CRITICAL_SECTION(obj); dict = *dictptr; - if (dict == NULL) { + if (dict != NULL) { + goto done; + } +#endif + if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) { assert(!_PyType_HasFeature(tp, Py_TPFLAGS_INLINE_VALUES)); dictkeys_incref(cached); dict = new_dict_with_shared_keys(interp, cached); - if (dict == NULL) - return -1; - *dictptr = dict; - } - if (value == NULL) { - res = PyDict_DelItem(dict, key); } else { - res = PyDict_SetItem(dict, key, value); - } - } else { - dict = *dictptr; - if (dict == NULL) { dict = PyDict_New(); - if (dict == NULL) - return -1; - *dictptr = dict; } - if (value == NULL) { - res = PyDict_DelItem(dict, key); - } else { - res = PyDict_SetItem(dict, key, value); + *dictptr = dict; +#ifdef Py_GIL_DISABLED +done: + Py_END_CRITICAL_SECTION(); +#endif + if (dict == NULL) { + return -1; } } + + Py_BEGIN_CRITICAL_SECTION(dict); + res = set_or_del_lock_held((PyDictObject *)dict, key, value); + Py_END_CRITICAL_SECTION(); ASSERT_CONSISTENT(dict); return res; } diff --git a/Objects/object.c b/Objects/object.c index 45310a6c22d6774..8cf62f005f23b56 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1732,7 +1732,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, goto done; } else { - res = _PyObjectDict_SetItem(tp, dictptr, name, value); + res = _PyObjectDict_SetItem(tp, obj, dictptr, name, value); } } else {