@@ -1597,7 +1597,7 @@ insertion_resize(PyInterpreterState *interp, PyDictObject *mp, int unicode)
1597
1597
}
1598
1598
1599
1599
static Py_ssize_t
1600
- insert_into_splitdictkeys (PyDictKeysObject * keys , PyObject * name )
1600
+ insert_into_splitdictkeys_locked (PyDictKeysObject * keys , PyObject * name )
1601
1601
{
1602
1602
assert (PyUnicode_CheckExact (name ));
1603
1603
ASSERT_KEYS_LOCKED (keys );
@@ -1629,6 +1629,15 @@ insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name)
1629
1629
return ix ;
1630
1630
}
1631
1631
1632
+ static Py_ssize_t
1633
+ insert_into_splitdictkeys (PyDictKeysObject * keys , PyObject * name )
1634
+ {
1635
+ LOCK_KEYS (keys );
1636
+ Py_ssize_t ix = insert_into_splitdictkeys_locked (keys , name );
1637
+ UNLOCK_KEYS (keys );
1638
+ return ix ;
1639
+ }
1640
+
1632
1641
static inline int
1633
1642
insert_combined_dict (PyInterpreterState * interp , PyDictObject * mp ,
1634
1643
Py_hash_t hash , PyObject * key , PyObject * value )
@@ -6692,8 +6701,26 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
6692
6701
assert (Py_TYPE (obj )-> tp_flags & Py_TPFLAGS_MANAGED_DICT );
6693
6702
Py_ssize_t ix = DKIX_EMPTY ;
6694
6703
if (PyUnicode_CheckExact (name )) {
6695
- LOCK_KEYS (keys );
6704
+ #ifdef Py_GIL_DISABLED
6705
+ Py_hash_t hash = unicode_get_hash (name );
6706
+ if (hash == -1 ) {
6707
+ hash = PyUnicode_Type .tp_hash (name );
6708
+ if (hash == -1 ) {
6709
+ PyErr_Clear ();
6710
+ return DKIX_EMPTY ;
6711
+ }
6712
+ }
6713
+
6714
+ // Try a thread-safe lookup to see if the index is already allocated
6715
+ ix = unicodekeys_lookup_unicode_threadsafe (keys , name , hash );
6716
+ if (ix == DKIX_EMPTY ) {
6717
+ // Fall back to a version that will lock and maybe insert
6718
+ ix = insert_into_splitdictkeys (keys , name );
6719
+ }
6720
+ #else
6696
6721
ix = insert_into_splitdictkeys (keys , name );
6722
+ #endif
6723
+
6697
6724
#ifdef Py_STATS
6698
6725
if (ix == DKIX_EMPTY ) {
6699
6726
if (PyUnicode_CheckExact (name )) {
@@ -6709,7 +6736,6 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
6709
6736
}
6710
6737
}
6711
6738
#endif
6712
- UNLOCK_KEYS (keys );
6713
6739
}
6714
6740
if (ix == DKIX_EMPTY ) {
6715
6741
PyObject * dict = make_dict_from_instance_attributes (
0 commit comments