@@ -15954,8 +15954,11 @@ immortalize_interned(PyObject *s)
1595415954 _Py_DecRefTotal (_PyThreadState_GET ());
1595515955 }
1595615956#endif
15957- FT_ATOMIC_STORE_UINT8_RELAXED (_PyUnicode_STATE (s ).interned , SSTATE_INTERNED_IMMORTAL );
1595815957 _Py_SetImmortal (s );
15958+ // The switch to SSTATE_INTERNED_IMMORTAL must be the last thing done here
15959+ // to synchronize with the check in intern_common() that avoids locking if
15960+ // the string is already immortal.
15961+ FT_ATOMIC_STORE_UINT8 (_PyUnicode_STATE (s ).interned , SSTATE_INTERNED_IMMORTAL );
1595915962}
1596015963
1596115964static /* non-null */ PyObject *
@@ -16035,7 +16038,25 @@ intern_common(PyInterpreterState *interp, PyObject *s /* stolen */,
1603516038 /* Do a setdefault on the per-interpreter cache. */
1603616039 PyObject * interned = get_interned_dict (interp );
1603716040 assert (interned != NULL );
16038-
16041+ #ifdef Py_GIL_DISABLED
16042+ // Lock-free fast path: check if there's already an interned copy that
16043+ // is in its final immortal state.
16044+ PyObject * r ;
16045+ int res = PyDict_GetItemRef (interned , s , & r );
16046+ if (res < 0 ) {
16047+ PyErr_Clear ();
16048+ return s ;
16049+ }
16050+ if (res > 0 ) {
16051+ unsigned int state = _Py_atomic_load_uint8 (& _PyUnicode_STATE (r ).interned );
16052+ if (state == SSTATE_INTERNED_IMMORTAL ) {
16053+ Py_DECREF (s );
16054+ return r ;
16055+ }
16056+ // Not yet fully interned; fall through to the locking path.
16057+ Py_DECREF (r );
16058+ }
16059+ #endif
1603916060 LOCK_INTERNED (interp );
1604016061 PyObject * t ;
1604116062 {
@@ -16072,7 +16093,7 @@ intern_common(PyInterpreterState *interp, PyObject *s /* stolen */,
1607216093 Py_DECREF (s );
1607316094 Py_DECREF (s );
1607416095 }
16075- FT_ATOMIC_STORE_UINT8_RELAXED (_PyUnicode_STATE (s ).interned , SSTATE_INTERNED_MORTAL );
16096+ FT_ATOMIC_STORE_UINT8 (_PyUnicode_STATE (s ).interned , SSTATE_INTERNED_MORTAL );
1607616097
1607716098 /* INTERNED_MORTAL -> INTERNED_IMMORTAL (if needed) */
1607816099
0 commit comments