@@ -281,13 +281,37 @@ hashtable_unicode_compare(const void *key1, const void *key2)
281281 }
282282}
283283
284+ /* Return true if this interpreter should share the main interpreter's
285+ intern_dict. That's important for interpreters which load basic
286+ single-phase init extension modules (m_size == -1). There could be interned
287+ immortal strings that are shared between interpreters, due to the
288+ PyDict_Update(mdict, m_copy) call in import_find_extension().
289+
290+ It's not safe to deallocate those strings until all interpreters that
291+ potentially use them are freed. By storing them in the main interpreter, we
292+ ensure they get freed after all other interpreters are freed.
293+ */
294+ static bool
295+ has_shared_intern_dict (PyInterpreterState * interp )
296+ {
297+ PyInterpreterState * main_interp = _PyInterpreterState_Main ();
298+ return interp != main_interp && interp -> feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC ;
299+ }
300+
284301static int
285302init_interned_dict (PyInterpreterState * interp )
286303{
287304 assert (get_interned_dict (interp ) == NULL );
288- PyObject * interned = interned = PyDict_New ();
289- if (interned == NULL ) {
290- return -1 ;
305+ PyObject * interned ;
306+ if (has_shared_intern_dict (interp )) {
307+ interned = get_interned_dict (_PyInterpreterState_Main ());
308+ Py_INCREF (interned );
309+ }
310+ else {
311+ interned = PyDict_New ();
312+ if (interned == NULL ) {
313+ return -1 ;
314+ }
291315 }
292316 _Py_INTERP_CACHED_OBJECT (interp , interned_strings ) = interned ;
293317 return 0 ;
@@ -298,7 +322,10 @@ clear_interned_dict(PyInterpreterState *interp)
298322{
299323 PyObject * interned = get_interned_dict (interp );
300324 if (interned != NULL ) {
301- PyDict_Clear (interned );
325+ if (!has_shared_intern_dict (interp )) {
326+ // only clear if the dict belongs to this interpreter
327+ PyDict_Clear (interned );
328+ }
302329 Py_DECREF (interned );
303330 _Py_INTERP_CACHED_OBJECT (interp , interned_strings ) = NULL ;
304331 }
@@ -15401,6 +15428,10 @@ _PyUnicode_InternStatic(PyInterpreterState *interp, PyObject **p)
1540115428 assert (* p );
1540215429}
1540315430
15431+ #ifdef Py_TRACE_REFS
15432+ extern void _Py_NormalizeImmortalReference (PyObject * );
15433+ #endif
15434+
1540415435static void
1540515436immortalize_interned (PyObject * s )
1540615437{
@@ -15416,6 +15447,10 @@ immortalize_interned(PyObject *s)
1541615447#endif
1541715448 _PyUnicode_STATE (s ).interned = SSTATE_INTERNED_IMMORTAL ;
1541815449 _Py_SetImmortal (s );
15450+ #ifdef Py_TRACE_REFS
15451+ /* Make sure the ref is associated with the right interpreter. */
15452+ _Py_NormalizeImmortalReference (s );
15453+ #endif
1541915454}
1542015455
1542115456static /* non-null */ PyObject *
@@ -15609,6 +15644,13 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
1560915644 }
1561015645 assert (PyDict_CheckExact (interned ));
1561115646
15647+ if (has_shared_intern_dict (interp )) {
15648+ // the dict doesn't belong to this interpreter, skip the debug
15649+ // checks on it and just clear the pointer to it
15650+ clear_interned_dict (interp );
15651+ return ;
15652+ }
15653+
1561215654#ifdef INTERNED_STATS
1561315655 fprintf (stderr , "releasing %zd interned strings\n" ,
1561415656 PyDict_GET_SIZE (interned ));
@@ -16117,8 +16159,10 @@ _PyUnicode_Fini(PyInterpreterState *interp)
1611716159{
1611816160 struct _Py_unicode_state * state = & interp -> unicode ;
1611916161
16120- // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini()
16121- assert (get_interned_dict (interp ) == NULL );
16162+ if (!has_shared_intern_dict (interp )) {
16163+ // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini()
16164+ assert (get_interned_dict (interp ) == NULL );
16165+ }
1612216166
1612316167 _PyUnicode_FiniEncodings (& state -> fs_codec );
1612416168
0 commit comments