8000 gh-112075: Avoid locking shared keys on every assignment (#116087) · python/cpython@556749c · GitHub
[go: up one dir, main page]

Skip to content
Sign in

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 556749c

Browse files
authored
gh-112075: Avoid locking shared keys on every assignment (#116087)
1 parent 41d5391 commit 556749c

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

Objects/dictobject.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,19 +1597,11 @@ insertion_resize(PyInterpreterState *interp, PyDictObject *mp, int unicode)
15971597
}
15981598

15991599
static Py_ssize_t
1600-
insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name)
1600+
insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name, Py_hash_t hash)
16011601
{
16021602
assert(PyUnicode_CheckExact(name));
16031603
ASSERT_KEYS_LOCKED(keys);
16041604

1605-
Py_hash_t hash = unicode_get_hash(name);
1606-
if (hash == -1) {
1607-
hash = PyUnicode_Type.tp_hash(name);
1608-
if (hash == -1) {
1609-
PyErr_Clear();
1610-
return DKIX_EMPTY;
1611-
}
1612-
}
16131605
Py_ssize_t ix = unicodekeys_lookup_unicode(keys, name, hash);
16141606
if (ix == DKIX_EMPTY) {
16151607
if (keys->dk_usable <= 0) {
@@ -6692,8 +6684,25 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
66926684
assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
66936685
Py_ssize_t ix = DKIX_EMPTY;
66946686
if (PyUnicode_CheckExact(name)) {
6695-
LOCK_KEYS(keys);
6696-
ix = insert_into_splitdictkeys(keys, name);
6687+
Py_hash_t hash = unicode_get_hash(name);
6688+
if (hash == -1) {
6689+
hash = PyUnicode_Type.tp_hash(name);
6690+
assert(hash != -1);
6691+
}
6692+
6693+
#ifdef Py_GIL_DISABLED
6694+
// Try a thread-safe lookup to see if the index is already allocated
6695+
ix = unicodekeys_lookup_unicode_threadsafe(keys, name, hash);
6696+
if (ix == DKIX_EMPTY) {
6697+
// Lock keys and do insert
6698+
LOCK_KEYS(keys);
6699+
ix = insert_into_splitdictkeys(keys, name, hash);
6700+
UNLOCK_KEYS(keys);
6701+
}
6702+
#else
6703+
ix = insert_into_splitdictkeys(keys, name, hash);
6704+
#endif
6705+
66976706
#ifdef Py_STATS
66986707
if (ix == DKIX_EMPTY) {
66996708
if (PyUnicode_CheckExact(name)) {
@@ -6709,7 +6718,6 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
67096718
}
67106719
}
67116720
#endif
6712-
UNLOCK_KEYS(keys);
67136721
}
67146722
if (ix == DKIX_EMPTY) {
67156723
PyObject *dict = make_dict_from_instance_attributes(

0 commit comments

Comments
 (0)
0