@@ -43,7 +43,8 @@ class object "PyObject *" "&PyBaseObject_Type"
4343 & ((1 << MCACHE_SIZE_EXP) - 1))
4444
4545#define MCACHE_HASH_METHOD (type , name ) \
46- MCACHE_HASH((type)->tp_version_tag, ((Py_ssize_t)(name)) >> 3)
46+ MCACHE_HASH(FT_ATOMIC_LOAD_UINT32_RELAXED((type)->tp_version_tag), \
47+ ((Py_ssize_t)(name)) >> 3)
4748#define MCACHE_CACHEABLE_NAME (name ) \
4849 PyUnicode_CheckExact(name) && \
4950 PyUnicode_IS_READY(name) && \
@@ -907,7 +908,7 @@ type_modified_unlocked(PyTypeObject *type)
907908 }
908909
909910 type -> tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG ;
910- type -> tp_version_tag = 0 ; /* 0 is not a valid version tag */
911+ FT_ATOMIC_STORE_UINT32_RELAXED ( type -> tp_version_tag , 0 ) ; /* 0 is not a valid version tag */
911912 if (PyType_HasFeature (type , Py_TPFLAGS_HEAPTYPE )) {
912913 // This field *must* be invalidated if the type is modified (see the
913914 // comment on struct _specialization_cache):
@@ -984,7 +985,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
984985 clear :
985986 assert (!(type -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ));
986987 type -> tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG ;
987- type -> tp_version_tag = 0 ; /* 0 is not a valid version tag */
988+ FT_ATOMIC_STORE_UINT32_RELAXED ( type -> tp_version_tag , 0 ) ; /* 0 is not a valid version tag */
988989 if (PyType_HasFeature (type , Py_TPFLAGS_HEAPTYPE )) {
989990 // This field *must* be invalidated if the type is modified (see the
990991 // comment on struct _specialization_cache):
@@ -1020,7 +1021,8 @@ assign_version_tag(PyInterpreterState *interp, PyTypeObject *type)
10201021 /* We have run out of version numbers */
10211022 return 0 ;
10221023 }
1023- type -> tp_version_tag = NEXT_GLOBAL_VERSION_TAG ++ ;
1024+ FT_ATOMIC_STORE_UINT32_RELAXED (type -> tp_version_tag ,
1025+ NEXT_GLOBAL_VERSION_TAG ++ );
10241026 assert (type -> tp_version_tag <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG );
10251027 }
10261028 else {
@@ -1029,7 +1031,8 @@ assign_version_tag(PyInterpreterState *interp, PyTypeObject *type)
10291031 /* We have run out of version numbers */
10301032 return 0 ;
10311033 }
1032- type -> tp_version_tag = NEXT_VERSION_TAG (interp )++ ;
1034+ FT_ATOMIC_STORE_UINT32_RELAXED (type -> tp_version_tag ,
1035+ NEXT_VERSION_TAG (interp )++ );
10331036 assert (type -> tp_version_tag != 0 );
10341037 }
10351038
@@ -5085,7 +5088,9 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
50855088 // synchronize-with other writing threads by doing an acquire load on the sequence
50865089 while (1 ) {
50875090 int sequence = _PySeqLock_BeginRead (& entry -> sequence );
5088- if (_Py_atomic_load_uint32_relaxed (& entry -> version ) == type -> tp_version_tag &&
5091+ uint32_t entry_version = _Py_atomic_load_uint32_relaxed (& entry -> version );
5092+ uint32_t type_version = _Py_atomic_load_uint32_relaxed (& type -> tp_version_tag );
5093+ if (entry_version == type_version &&
50895094 _Py_atomic_load_ptr_relaxed (& entry -> name ) == name ) {
50905095 assert (_PyType_HasFeature (type , Py_TPFLAGS_VALID_VERSION_TAG ));
50915096 OBJECT_STAT_INC_COND (type_cache_hits , !is_dunder_name (name ));
0 commit comments