bpo-40521: Make MemoryError free list per interpreter (GH-21086)

Each interpreter now has its own MemoryError free list: it is not
longer shared by all interpreters.

Add _Py_exc_state structure and PyInterpreterState.exc_state member.
Move also errnomap into _Py_exc_state.
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index c22bea7..435a72a 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -152,6 +152,13 @@
     int numfree;
 };
 
+struct _Py_exc_state {
+    // The dict mapping from errno codes to OSError subclasses
+    PyObject *errnomap;
+    PyBaseExceptionObject *memerrors_freelist;
+    int memerrors_numfree;
+};
+
 
 /* interpreter state */
 
@@ -251,6 +258,7 @@
     struct _Py_frame_state frame;
     struct _Py_async_gen_state async_gen;
     struct _Py_context_state context;
+    struct _Py_exc_state exc_state;
 };
 
 /* Used by _PyImport_Cleanup() */
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 30ba484..cd47044 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -43,7 +43,7 @@
 extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
 extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
 extern int _PySys_InitMain(PyThreadState *tstate);
-extern PyStatus _PyExc_Init(void);
+extern PyStatus _PyExc_Init(PyThreadState *tstate);
 extern PyStatus _PyErr_Init(void);
 extern PyStatus _PyBuiltins_AddExceptions(PyObject * bltinmod);
 extern PyStatus _PyImportHooks_Init(PyThreadState *tstate);
@@ -69,7 +69,7 @@
 
 extern void PyOS_FiniInterrupts(void);
 
-extern void _PyExc_Fini(void);
+extern void _PyExc_Fini(PyThreadState *tstate);
 extern void _PyImport_Fini(void);
 extern void _PyImport_Fini2(void);
 extern void _PyGC_Fini(PyThreadState *tstate);
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst
index a62383d..9b94bcc 100644
--- a/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-05-20-01-17-34.bpo-40521.wvAehI.rst
@@ -1,10 +1,9 @@
 Each interpreter now its has own free lists, singletons and caches:
 
 * Free lists: float, tuple, list, dict, frame, context,
-  asynchronous generator.
+  asynchronous generator, MemoryError.
 * Singletons: empty tuple, empty bytes string,
   single byte character.
 * Slice cache.
 
 They are no longer shared by all interpreters.
-
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index db5e3da..1195ba1 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -19,8 +19,13 @@
 PyObject *PyExc_WindowsError = NULL;
 #endif
 
-/* The dict map from errno codes to OSError subclasses */
-static PyObject *errnomap = NULL;
+
+static struct _Py_exc_state*
+get_exc_state(void)
+{
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->exc_state;
+}
 
 
 /* NOTE: If the exception class hierarchy changes, don't forget to update
@@ -985,10 +990,11 @@
             ))
             goto error;
 
+        struct _Py_exc_state *state = get_exc_state();
         if (myerrno && PyLong_Check(myerrno) &&
-            errnomap && (PyObject *) type == PyExc_OSError) {
+            state->errnomap && (PyObject *) type == PyExc_OSError) {
             PyObject *newtype;
-            newtype = PyDict_GetItemWithError(errnomap, myerrno);
+            newtype = PyDict_GetItemWithError(state->errnomap, myerrno);
             if (newtype) {
                 assert(PyType_Check(newtype));
                 type = (PyTypeObject *) newtype;
@@ -2274,8 +2280,6 @@
  */
 
 #define MEMERRORS_SAVE 16
-static PyBaseExceptionObject *memerrors_freelist = NULL;
-static int memerrors_numfree = 0;
 
 static PyObject *
 MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
@@ -2284,16 +2288,22 @@
 
     if (type != (PyTypeObject *) PyExc_MemoryError)
         return BaseException_new(type, args, kwds);
-    if (memerrors_freelist == NULL)
+
+    struct _Py_exc_state *state = get_exc_state();
+    if (state->memerrors_freelist == NULL) {
         return BaseException_new(type, args, kwds);
+    }
+
     /* Fetch object from freelist and revive it */
-    self = memerrors_freelist;
+    self = state->memerrors_freelist;
     self->args = PyTuple_New(0);
     /* This shouldn't happen since the empty tuple is persistent */
-    if (self->args == NULL)
+    if (self->args == NULL) {
         return NULL;
-    memerrors_freelist = (PyBaseExceptionObject *) self->dict;
-    memerrors_numfree--;
+    }
+
+    state->memerrors_freelist = (PyBaseExceptionObject *) self->dict;
+    state->memerrors_numfree--;
     self->dict = NULL;
     _Py_NewReference((PyObject *)self);
     _PyObject_GC_TRACK(self);
@@ -2305,12 +2315,15 @@
 {
     _PyObject_GC_UNTRACK(self);
     BaseException_clear(self);
-    if (memerrors_numfree >= MEMERRORS_SAVE)
+
+    struct _Py_exc_state *state = get_exc_state();
+    if (state->memerrors_numfree >= MEMERRORS_SAVE) {
         Py_TYPE(self)->tp_free((PyObject *)self);
+    }
     else {
-        self->dict = (PyObject *) memerrors_freelist;
-        memerrors_freelist = self;
-        memerrors_numfree++;
+        self->dict = (PyObject *) state->memerrors_freelist;
+        state->memerrors_freelist = self;
+        state->memerrors_numfree++;
     }
 }
 
@@ -2335,11 +2348,11 @@
 }
 
 static void
-free_preallocated_memerrors(void)
+free_preallocated_memerrors(struct _Py_exc_state *state)
 {
-    while (memerrors_freelist != NULL) {
-        PyObject *self = (PyObject *) memerrors_freelist;
-        memerrors_freelist = (PyBaseExceptionObject *) memerrors_freelist->dict;
+    while (state->memerrors_freelist != NULL) {
+        PyObject *self = (PyObject *) state->memerrors_freelist;
+        state->memerrors_freelist = (PyBaseExceptionObject *)state->memerrors_freelist->dict;
         Py_TYPE(self)->tp_free((PyObject *)self);
     }
 }
@@ -2507,8 +2520,10 @@
 #endif /* MS_WINDOWS */
 
 PyStatus
-_PyExc_Init(void)
+_PyExc_Init(PyThreadState *tstate)
 {
+    struct _Py_exc_state *state = &tstate->interp->exc_state;
+
 #define PRE_INIT(TYPE) \
     if (!(_PyExc_ ## TYPE.tp_flags & Py_TPFLAGS_READY)) { \
         if (PyType_Ready(&_PyExc_ ## TYPE) < 0) { \
@@ -2521,7 +2536,7 @@
     do { \
         PyObject *_code = PyLong_FromLong(CODE); \
         assert(_PyObject_RealIsSubclass(PyExc_ ## TYPE, PyExc_OSError)); \
-        if (!_code || PyDict_SetItem(errnomap, _code, PyExc_ ## TYPE)) \
+        if (!_code || PyDict_SetItem(state->errnomap, _code, PyExc_ ## TYPE)) \
             return _PyStatus_ERR("errmap insertion problem."); \
         Py_DECREF(_code); \
     } while (0)
@@ -2595,15 +2610,14 @@
     PRE_INIT(TimeoutError);
 
     if (preallocate_memerrors() < 0) {
-        return _PyStatus_ERR("Could not preallocate MemoryError object");
+        return _PyStatus_NO_MEMORY();
     }
 
     /* Add exceptions to errnomap */
-    if (!errnomap) {
-        errnomap = PyDict_New();
-        if (!errnomap) {
-            return _PyStatus_ERR("Cannot allocate map from errnos to OSError subclasses");
-        }
+    assert(state->errnomap == NULL);
+    state->errnomap = PyDict_New();
+    if (!state->errnomap) {
+        return _PyStatus_NO_MEMORY();
     }
 
     ADD_ERRNO(BlockingIOError, EAGAIN);
@@ -2741,10 +2755,11 @@
 }
 
 void
-_PyExc_Fini(void)
+_PyExc_Fini(PyThreadState *tstate)
 {
-    free_preallocated_memerrors();
-    Py_CLEAR(errnomap);
+    struct _Py_exc_state *state = &tstate->interp->exc_state;
+    free_preallocated_memerrors(state);
+    Py_CLEAR(state->errnomap);
 }
 
 /* Helper to do the equivalent of "raise X from Y" in C, but always using
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 09945a8..f0b40b3 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -602,7 +602,7 @@
         }
     }
 
-    status = _PyExc_Init();
+    status = _PyExc_Init(tstate);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
@@ -1249,6 +1249,7 @@
 static void
 finalize_interp_types(PyThreadState *tstate, int is_main_interp)
 {
+    _PyExc_Fini(tstate);
     _PyFrame_Fini(tstate);
     _PyAsyncGen_Fini(tstate);
     _PyContext_Fini(tstate);
@@ -1289,10 +1290,6 @@
 
     _PyWarnings_Fini(tstate->interp);
 
-    if (is_main_interp) {
-        _PyExc_Fini();
-    }
-
     finalize_interp_types(tstate, is_main_interp);
 }