bpo-38858: Small integer per interpreter (GH-17315)

Each Python subinterpreter now has its own "small integer
singletons": numbers in [-5; 257] range.

It is no longer possible to change the number of small integers at
build time by overriding NSMALLNEGINTS and NSMALLPOSINTS macros:
macros should now be modified manually in pycore_pystate.h header
file.

For now, continue to share _PyLong_Zero and _PyLong_One singletons
between all subinterpreters.
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 4e4bbc2..7292349 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -33,7 +33,7 @@
 
 extern PyStatus _PyUnicode_Init(void);
 extern int _PyStructSequence_Init(void);
-extern int _PyLong_Init(void);
+extern int _PyLong_Init(PyThreadState *tstate);
 extern PyStatus _PyFaulthandler_Init(int enable);
 extern int _PyTraceMalloc_Init(int enable);
 extern PyObject * _PyBuiltin_Init(PyThreadState *tstate);
@@ -76,7 +76,7 @@
 extern void _PyType_Fini(void);
 extern void _Py_HashRandomization_Fini(void);
 extern void _PyUnicode_Fini(PyThreadState *tstate);
-extern void _PyLong_Fini(void);
+extern void _PyLong_Fini(PyThreadState *tstate);
 extern void _PyFaulthandler_Fini(void);
 extern void _PyHash_Fini(void);
 extern void _PyTraceMalloc_Fini(void);
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index aa2103f..b78ed69 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -56,6 +56,9 @@
 
 typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
 
+#define _PY_NSMALLPOSINTS           257
+#define _PY_NSMALLNEGINTS           5
+
 // The PyInterpreterState typedef is in Include/pystate.h.
 struct _is {
 
@@ -139,6 +142,15 @@
             int atbol;
         } listnode;
     } parser;
+
+#if _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS > 0
+    /* Small integers are preallocated in this array so that they
+       can be shared.
+       The integers that are preallocated are those in the range
+       -_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
+    */
+    PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
+#endif
 };
 
 PyAPI_FUNC(struct _is*) _PyInterpreterState_LookUpID(PY_INT64_T);
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-11-21-09-02-49.bpo-38858.bDLH04.rst b/Misc/NEWS.d/next/Core and Builtins/2019-11-21-09-02-49.bpo-38858.bDLH04.rst
new file mode 100644
index 0000000..e489c94
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-11-21-09-02-49.bpo-38858.bDLH04.rst
@@ -0,0 +1,5 @@
+Each Python subinterpreter now has its own "small integer singletons":
+numbers in [-5; 257] range. It is no longer possible to change the number of
+small integers at build time by overriding ``NSMALLNEGINTS`` and
+``NSMALLPOSINTS`` macros: macros should now be modified manually in
+``pycore_pystate.h`` header file.
diff --git a/Objects/longobject.c b/Objects/longobject.c
index bc87fb2..be9301f 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -3,6 +3,7 @@
 /* XXX The functional organization of this file is terrible */
 
 #include "Python.h"
+#include "pycore_pystate.h"   /* _Py_IsMainInterpreter() */
 #include "longintrepr.h"
 
 #include <float.h>
@@ -15,12 +16,8 @@
 [clinic start generated code]*/
 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec0275e3422a36e3]*/
 
-#ifndef NSMALLPOSINTS
-#define NSMALLPOSINTS           257
-#endif
-#ifndef NSMALLNEGINTS
-#define NSMALLNEGINTS           5
-#endif
+#define NSMALLPOSINTS           _PY_NSMALLPOSINTS
+#define NSMALLNEGINTS           _PY_NSMALLNEGINTS
 
 _Py_IDENTIFIER(little);
 _Py_IDENTIFIER(big);
@@ -35,13 +32,6 @@
 PyObject *_PyLong_One = NULL;
 
 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
-/* Small integers are preallocated in this array so that they
-   can be shared.
-   The integers that are preallocated are those in the range
-   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
-*/
-static PyLongObject* small_ints[NSMALLNEGINTS + NSMALLPOSINTS] = {0};
-
 #define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS)
 #define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS)
 
@@ -53,7 +43,8 @@
 get_small_int(sdigit ival)
 {
     assert(IS_SMALL_INT(ival));
-    PyObject *v = (PyObject*)small_ints[ival + NSMALLNEGINTS];
+    PyThreadState *tstate = _PyThreadState_GET();
+    PyObject *v = (PyObject*)tstate->interp->small_ints[ival + NSMALLNEGINTS];
     Py_INCREF(v);
 #ifdef COUNT_ALLOCS
     if (ival >= 0)
@@ -5782,7 +5773,7 @@
 }
 
 int
-_PyLong_Init(void)
+_PyLong_Init(PyThreadState *tstate)
 {
 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
     for (Py_ssize_t i=0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) {
@@ -5797,37 +5788,43 @@
         Py_SIZE(v) = size;
         v->ob_digit[0] = (digit)abs(ival);
 
-        small_ints[i] = v;
+        tstate->interp->small_ints[i] = v;
     }
 #endif
-    _PyLong_Zero = PyLong_FromLong(0);
-    if (_PyLong_Zero == NULL) {
-        return 0;
-    }
 
-    _PyLong_One = PyLong_FromLong(1);
-    if (_PyLong_One == NULL) {
-        return 0;
-    }
-
-    /* initialize int_info */
-    if (Int_InfoType.tp_name == NULL) {
-        if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) {
+    if (_Py_IsMainInterpreter(tstate)) {
+        _PyLong_Zero = PyLong_FromLong(0);
+        if (_PyLong_Zero == NULL) {
             return 0;
         }
+
+        _PyLong_One = PyLong_FromLong(1);
+        if (_PyLong_One == NULL) {
+            return 0;
+        }
+
+        /* initialize int_info */
+        if (Int_InfoType.tp_name == NULL) {
+            if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) {
+                return 0;
+            }
+        }
     }
 
     return 1;
 }
 
 void
-_PyLong_Fini(void)
+_PyLong_Fini(PyThreadState *tstate)
 {
-    Py_CLEAR(_PyLong_One);
-    Py_CLEAR(_PyLong_Zero);
+    if (_Py_IsMainInterpreter(tstate)) {
+        Py_CLEAR(_PyLong_One);
+        Py_CLEAR(_PyLong_Zero);
+    }
+
 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
     for (Py_ssize_t i = 0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) {
-        Py_CLEAR(small_ints[i]);
+        Py_CLEAR(tstate->interp->small_ints[i]);
     }
 #endif
 }
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 823d96e..4f05dfc 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -576,10 +576,11 @@
         if (_PyStatus_EXCEPTION(status)) {
             return status;
         }
+    }
 
-        if (!_PyLong_Init()) {
-            return _PyStatus_ERR("can't init longs");
-        }
+
+    if (!_PyLong_Init(tstate)) {
+        return _PyStatus_ERR("can't init longs");
     }
 
     if (is_main_interp) {
@@ -1251,7 +1252,11 @@
         _PyList_Fini();
         _PySet_Fini();
         _PyBytes_Fini();
-        _PyLong_Fini();
+    }
+
+    _PyLong_Fini(tstate);
+
+    if (is_main_interp) {
         _PyFloat_Fini();
         _PyDict_Fini();
         _PySlice_Fini();