diff options
-rw-r--r-- | Include/internal/pycore_pylifecycle.h | 4 | ||||
-rw-r--r-- | Include/internal/pycore_pystate.h | 12 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2019-11-21-09-02-49.bpo-38858.bDLH04.rst | 5 | ||||
-rw-r--r-- | Objects/longobject.c | 59 | ||||
-rw-r--r-- | Python/pylifecycle.c | 13 |
5 files changed, 56 insertions, 37 deletions
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 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc); 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 _PyGC_Fini(PyThreadState *tstate); 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 @@ struct _ceval_runtime_state { 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 @@ struct _is { 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 @@ class int "PyObject *" "&PyLong_Type" [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_Zero = NULL; 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 @@ static PyObject * 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 @@ PyLong_GetInfo(void) } 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 @@ _PyLong_Init(void) 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; - } + if (_Py_IsMainInterpreter(tstate)) { + _PyLong_Zero = PyLong_FromLong(0); + if (_PyLong_Zero == NULL) { + return 0; + } - /* initialize int_info */ - if (Int_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 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 @@ pycore_init_types(PyThreadState *tstate) 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 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) _PyList_Fini(); _PySet_Fini(); _PyBytes_Fini(); - _PyLong_Fini(); + } + + _PyLong_Fini(tstate); + + if (is_main_interp) { _PyFloat_Fini(); _PyDict_Fini(); _PySlice_Fini(); |