@@ -1581,32 +1581,47 @@ _Py_dict_lookup_threadsafe(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyOb
1581
1581
return ix ;
1582
1582
}
1583
1583
1584
+ static Py_ssize_t
1585
+ lookup_threadsafe_unicode (PyDictKeysObject * dk , PyObject * key , Py_hash_t hash , _PyStackRef * value_addr )
1586
+ {
1587
+ assert (dk -> dk_kind == DICT_KEYS_UNICODE );
1588
+ assert (PyUnicode_CheckExact (key ));
1589
+
1590
+ Py_ssize_t ix = unicodekeys_lookup_unicode_threadsafe (dk , key , hash );
1591
+ if (ix == DKIX_EMPTY ) {
1592
+ * value_addr = PyStackRef_NULL ;
1593
+ return ix ;
1594
+ }
1595
+ else if (ix >= 0 ) {
1596
+ PyObject * * addr_of_value = & DK_UNICODE_ENTRIES (dk )[ix ].me_value ;
1597
+ PyObject * value = _Py_atomic_load_ptr (addr_of_value );
1598
+ if (value == NULL ) {
1599
+ * value_addr = PyStackRef_NULL ;
1600
+ return DKIX_EMPTY ;
1601
+ }
1602
+ if (_PyObject_HasDeferredRefcount (value )) {
1603
+ * value_addr = (_PyStackRef ){ .bits = (uintptr_t )value | Py_TAG_DEFERRED };
1604
+ return ix ;
1605
+ }
1606
+ if (_Py_TryIncrefCompare (addr_of_value , value )) {
1607
+ * value_addr = PyStackRef_FromPyObjectSteal (value );
1608
+ return ix ;
1609
+ }
1610
+ return DKIX_KEY_CHANGED ;
1611
+ }
1612
+ assert (ix == DKIX_KEY_CHANGED );
1613
+ return ix ;
1614
+ }
1615
+
1584
1616
Py_ssize_t
1585
1617
_Py_dict_lookup_threadsafe_stackref (PyDictObject * mp , PyObject * key , Py_hash_t hash , _PyStackRef * value_addr )
1586
1618
{
1587
1619
PyDictKeysObject * dk = _Py_atomic_load_ptr (& mp -> ma_keys );
1588
1620
if (dk -> dk_kind == DICT_KEYS_UNICODE && PyUnicode_CheckExact (key )) {
1589
- Py_ssize_t ix = unicodekeys_lookup_unicode_threadsafe (dk , key , hash );
1590
- if (ix == DKIX_EMPTY ) {
1591
- * value_addr = PyStackRef_NULL ;
1621
+ Py_ssize_t ix = lookup_threadsafe_unicode (dk , key , hash , value_addr );
1622
+ if (ix != DKIX_KEY_CHANGED ) {
1592
1623
return ix ;
1593
1624
}
1594
- else if (ix >= 0 ) {
1595
- PyObject * * addr_of_value = & DK_UNICODE_ENTRIES (dk )[ix ].me_value ;
1596
- PyObject * value = _Py_atomic_load_ptr (addr_of_value );
1597
- if (value == NULL ) {
1598
- * value_addr = PyStackRef_NULL ;
1599
- return DKIX_EMPTY ;
1600
- }
1601
- if (_PyObject_HasDeferredRefcount (value )) {
1602
- * value_addr = (_PyStackRef ){ .bits = (uintptr_t )value | Py_TAG_DEFERRED };
1603
- return ix ;
1604
- }
1605
- if (_Py_TryIncrefCompare (addr_of_value , value )) {
1606
- * value_addr = PyStackRef_FromPyObjectSteal (value );
1607
- return ix ;
1608
- }
1609
- }
1610
1625
}
1611
1626
1612
1627
PyObject * obj ;
@@ -1646,6 +1661,46 @@ _Py_dict_lookup_threadsafe_stackref(PyDictObject *mp, PyObject *key, Py_hash_t h
1646
1661
1647
1662
#endif
1648
1663
1664
+ // Looks up the unicode key `key` in the dictionary. Note that `*method` may
1665
+ // already contain a valid value! See _PyObject_GetMethodStackRef().
1666
+ int
1667
+ _PyDict_GetMethodStackRef (PyDictObject * mp , PyObject * key , _PyStackRef * method )
1668
+ {
1669
+ assert (PyUnicode_CheckExact (key ));
1670
+ Py_hash_t hash = hash_unicode_key (key );
1671
+
1672
+ #ifdef Py_GIL_DISABLED
1673
+ PyDictKeysObject * dk = _Py_atomic_load_ptr_acquire (& mp -> ma_keys );
1674
+ if (dk -> dk_kind == DICT_KEYS_UNICODE ) {
1675
+ _PyStackRef ref ;
1676
+ Py_ssize_t ix = lookup_threadsafe_unicode (dk , key , hash , & ref );
1677
+ if (ix >= 0 ) {
1678
+ assert (!PyStackRef_IsNull (ref ));
1679
+ PyStackRef_XSETREF (* method , ref );
1680
+ return 1 ;
1681
+ }
1682
+ else if (ix == DKIX_EMPTY ) {
1683
+ return 0 ;
1684
+ }
1685
+ assert (ix == DKIX_KEY_CHANGED );
1686
+ }
1687
+ #endif
1688
+
1689
+ PyObject * obj ;
1690
+ Py_INCREF (mp );
1691
+ Py_ssize_t ix = _Py_dict_lookup_threadsafe (mp , key , hash , & obj );
1692
+ Py_DECREF (mp );
1693
+ if (ix == DKIX_ERROR ) {
1694
+ PyStackRef_CLEAR (* method );
1695
+ return -1 ;
1696
+ }
1697
+ else if (ix >= 0 && obj != NULL ) {
1698
+ PyStackRef_XSETREF (* method , PyStackRef_FromPyObjectSteal (obj ));
1699
+ return 1 ;
1700
+ }
1701
+ return 0 ; // not found
1702
+ }
1703
+
1649
1704
int
1650
1705
_PyDict_HasOnlyStringKeys (PyObject * dict )
1651
1706
{
0 commit comments