mirror of https://github.com/python/cpython
gh-112075: Avoid locking shared keys on every assignment (#116087)
This commit is contained in:
parent
41d5391c55
commit
556749c3e3
|
@ -1597,19 +1597,11 @@ insertion_resize(PyInterpreterState *interp, PyDictObject *mp, int unicode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Py_ssize_t
|
static Py_ssize_t
|
||||||
insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name)
|
insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name, Py_hash_t hash)
|
||||||
{
|
{
|
||||||
assert(PyUnicode_CheckExact(name));
|
assert(PyUnicode_CheckExact(name));
|
||||||
ASSERT_KEYS_LOCKED(keys);
|
ASSERT_KEYS_LOCKED(keys);
|
||||||
|
|
||||||
Py_hash_t hash = unicode_get_hash(name);
|
|
||||||
if (hash == -1) {
|
|
||||||
hash = PyUnicode_Type.tp_hash(name);
|
|
||||||
if (hash == -1) {
|
|
||||||
PyErr_Clear();
|
|
||||||
return DKIX_EMPTY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Py_ssize_t ix = unicodekeys_lookup_unicode(keys, name, hash);
|
Py_ssize_t ix = unicodekeys_lookup_unicode(keys, name, hash);
|
||||||
if (ix == DKIX_EMPTY) {
|
if (ix == DKIX_EMPTY) {
|
||||||
if (keys->dk_usable <= 0) {
|
if (keys->dk_usable <= 0) {
|
||||||
|
@ -6692,8 +6684,25 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
|
||||||
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
|
||||||
Py_ssize_t ix = DKIX_EMPTY;
|
Py_ssize_t ix = DKIX_EMPTY;
|
||||||
if (PyUnicode_CheckExact(name)) {
|
if (PyUnicode_CheckExact(name)) {
|
||||||
LOCK_KEYS(keys);
|
Py_hash_t hash = unicode_get_hash(name);
|
||||||
ix = insert_into_splitdictkeys(keys, name);
|
if (hash == -1) {
|
||||||
|
hash = PyUnicode_Type.tp_hash(name);
|
||||||
|
assert(hash != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef Py_GIL_DISABLED
|
||||||
|
// Try a thread-safe lookup to see if the index is already allocated
|
||||||
|
ix = unicodekeys_lookup_unicode_threadsafe(keys, name, hash);
|
||||||
|
if (ix == DKIX_EMPTY) {
|
||||||
|
// Lock keys and do insert
|
||||||
|
LOCK_KEYS(keys);
|
||||||
|
ix = insert_into_splitdictkeys(keys, name, hash);
|
||||||
|
UNLOCK_KEYS(keys);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ix = insert_into_splitdictkeys(keys, name, hash);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Py_STATS
|
#ifdef Py_STATS
|
||||||
if (ix == DKIX_EMPTY) {
|
if (ix == DKIX_EMPTY) {
|
||||||
if (PyUnicode_CheckExact(name)) {
|
if (PyUnicode_CheckExact(name)) {
|
||||||
|
@ -6709,7 +6718,6 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
UNLOCK_KEYS(keys);
|
|
||||||
}
|
}
|
||||||
if (ix == DKIX_EMPTY) {
|
if (ix == DKIX_EMPTY) {
|
||||||
PyObject *dict = make_dict_from_instance_attributes(
|
PyObject *dict = make_dict_from_instance_attributes(
|
||||||
|
|
Loading…
Reference in New Issue