diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index c0eed00f36581f..70054efe7ec718 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -187,6 +187,10 @@ struct _is { #endif struct _Py_tuple_state tuple; struct _Py_float_state float_state; + + /* Using a cache is very effective since typically only a single slice is + created and then deleted again. */ + PySliceObject *slice_cache; }; /* Used by _PyImport_Cleanup() */ diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 2643abca0f5536..bba9bd9b2bdb22 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -65,7 +65,7 @@ extern void _PyList_Fini(void); extern void _PySet_Fini(void); extern void _PyBytes_Fini(void); extern void _PyFloat_Fini(PyThreadState *tstate); -extern void _PySlice_Fini(void); +extern void _PySlice_Fini(PyThreadState *tstate); extern void _PyAsyncGen_Fini(void); extern void PyOS_FiniInterrupts(void); 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 016f11668ee447..74c7a499bdef0b 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,2 +1,3 @@ -Tuple free lists, empty tuple singleton, and float free list are no longer -shared by all interpreters: each interpreter now its own free lists. +The tuple free lists, the empty tuple singleton, the float free list, and the +slice cache are no longer shared by all interpreters: each interpreter now has +its own free lists and caches. diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 391711f711aae0..f97a570a787f06 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -15,7 +15,7 @@ this type and there is exactly one in existence. #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() -#include "pycore_object.h" +#include "pycore_object.h" // _PyObject_GC_TRACK() #include "structmember.h" // PyMemberDef static PyObject * @@ -95,16 +95,13 @@ PyObject _Py_EllipsisObject = { /* Slice object implementation */ -/* Using a cache is very effective since typically only a single slice is - * created and then deleted again - */ -static PySliceObject *slice_cache = NULL; -void _PySlice_Fini(void) +void _PySlice_Fini(PyThreadState *tstate) { - PySliceObject *obj = slice_cache; + PyInterpreterState *interp = tstate->interp; + PySliceObject *obj = interp->slice_cache; if (obj != NULL) { - slice_cache = NULL; + interp->slice_cache = NULL; PyObject_GC_Del(obj); } } @@ -116,10 +113,11 @@ void _PySlice_Fini(void) PyObject * PySlice_New(PyObject *start, PyObject *stop, PyObject *step) { + PyInterpreterState *interp = _PyInterpreterState_GET(); PySliceObject *obj; - if (slice_cache != NULL) { - obj = slice_cache; - slice_cache = NULL; + if (interp->slice_cache != NULL) { + obj = interp->slice_cache; + interp->slice_cache = NULL; _Py_NewReference((PyObject *)obj); } else { obj = PyObject_GC_New(PySliceObject, &PySlice_Type); @@ -324,14 +322,17 @@ Create a slice object. This is used for extended slicing (e.g. a[0:10:2])."); static void slice_dealloc(PySliceObject *r) { + PyInterpreterState *interp = _PyInterpreterState_GET(); _PyObject_GC_UNTRACK(r); Py_DECREF(r->step); Py_DECREF(r->start); Py_DECREF(r->stop); - if (slice_cache == NULL) - slice_cache = r; - else + if (interp->slice_cache == NULL) { + interp->slice_cache = r; + } + else { PyObject_GC_Del(r); + } } static PyObject * diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 716303cffc7643..ee9d698d7d0890 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1265,9 +1265,9 @@ finalize_interp_types(PyThreadState *tstate, int is_main_interp) if (is_main_interp) { _PyDict_Fini(); - _PySlice_Fini(); } + _PySlice_Fini(tstate); _PyWarnings_Fini(tstate->interp); if (is_main_interp) {
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: