@@ -266,6 +266,23 @@ hashtable_unicode_compare(const void *key1, const void *key2)
266266 }
267267}
268268
269+ /* Return true if this interpreter should share the main interpreter's
270+ intern_dict. That's important for interpreters which load basic
271+ single-phase init extension modules (m_size == -1). There could be interned
272+ immortal strings that are shared between interpreters, due to the
273+ PyDict_Update(mdict, m_copy) call in import_find_extension().
274+
275+ It's not safe to deallocate those strings until all interpreters that
276+ potentially use them are freed. By storing them in the main interpreter, we
277+ ensure they get freed after all other interpreters are freed.
278+ */
279+ static bool
280+ has_shared_intern_dict (PyInterpreterState * interp )
281+ {
282+ PyInterpreterState * main_interp = _PyInterpreterState_Main ();
283+ return interp != main_interp && interp -> feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC ;
284+ }
285+
269286static int
270287init_interned_dict (PyInterpreterState * interp )
271288{
@@ -284,9 +301,16 @@ init_interned_dict(PyInterpreterState *interp)
284301 }
285302 }
286303 assert (get_interned_dict (interp ) == NULL );
287- PyObject * interned = interned = PyDict_New ();
288- if (interned == NULL ) {
289- return -1 ;
304+ PyObject * interned ;
305+ if (has_shared_intern_dict (interp )) {
306+ interned = get_interned_dict (_PyInterpreterState_Main ());
307+ Py_INCREF (interned );
308+ }
309+ else {
310+ interned = PyDict_New ();
311+ if (interned == NULL ) {
312+ return -1 ;
313+ }
290314 }
291315 _Py_INTERP_CACHED_OBJECT (interp , interned_strings ) = interned ;
292316 return 0 ;
@@ -297,7 +321,10 @@ clear_interned_dict(PyInterpreterState *interp)
297321{
298322 PyObject * interned = get_interned_dict (interp );
299323 if (interned != NULL ) {
300- PyDict_Clear (interned );
324+ if (!has_shared_intern_dict (interp )) {
325+ // only clear if the dict belongs to this interpreter
326+ PyDict_Clear (interned );
327+ }
301328 Py_DECREF (interned );
302329 _Py_INTERP_CACHED_OBJECT (interp , interned_strings ) = NULL ;
303330 }
@@ -14861,6 +14888,13 @@ _PyUnicode_ClearInterned(PyInterpreterState *interp)
1486114888 }
1486214889 assert (PyDict_CheckExact (interned ));
1486314890
14891+ if (has_shared_intern_dict (interp )) {
14892+ // the dict doesn't belong to this interpreter, skip the debug
14893+ // checks on it and just clear the pointer to it
14894+ clear_interned_dict (interp );
14895+ return ;
14896+ }
14897+
1486414898 /* TODO:
1486514899 * Currently, the runtime is not able to guarantee that it can exit without
1486614900 * allocations that carry over to a future initialization of Python within
@@ -15364,8 +15398,10 @@ _PyUnicode_Fini(PyInterpreterState *interp)
1536415398{
1536515399 struct _Py_unicode_state * state = & interp -> unicode ;
1536615400
15367- // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini()
15368- assert (get_interned_dict (interp ) == NULL );
15401+ if (!has_shared_intern_dict (interp )) {
15402+ // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini()
15403+ assert (get_interned_dict (interp ) == NULL );
15404+ }
1536915405
1537015406 _PyUnicode_FiniEncodings (& state -> fs_codec );
1537115407
0 commit comments