diff options
author | Victor Stinner <vstinner@python.org> | 2020-06-05 00:05:41 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-05 00:05:41 (GMT) |
commit | 88ec9190105c9b03f49aaef601ce02b242a75273 (patch) | |
tree | 699bea45830306ef5cd9943138a8c03d846e33d3 /Include | |
parent | 052d3fc0907be253cfd64b2c737a0b0aca586011 (diff) | |
download | cpython-88ec9190105c9b03f49aaef601ce02b242a75273.zip cpython-88ec9190105c9b03f49aaef601ce02b242a75273.tar.gz cpython-88ec9190105c9b03f49aaef601ce02b242a75273.tar.bz2 |
bpo-40521: Make list free list per-interpreter (GH-20642)
Each interpreter now has its own list free list:
* Move list numfree and free_list into PyInterpreterState.
* Add _Py_list_state structure.
* Add tstate parameter to _PyList_ClearFreeList()
and _PyList_Fini().
* Remove "#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS".
* _PyGC_Fini() clears gcstate->garbage list which can be stored in
the list free list. Call _PyGC_Fini() before _PyList_Fini() to
prevent leaking this list.
Diffstat (limited to 'Include')
-rw-r--r-- | Include/internal/pycore_gc.h | 2 | ||||
-rw-r--r-- | Include/internal/pycore_interp.h | 11 | ||||
-rw-r--r-- | Include/internal/pycore_pylifecycle.h | 2 |
3 files changed, 13 insertions, 2 deletions
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index 01265d3..3388b4d 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -168,7 +168,7 @@ PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); extern void _PyFrame_ClearFreeList(PyThreadState *tstate); extern void _PyTuple_ClearFreeList(PyThreadState *tstate); extern void _PyFloat_ClearFreeList(PyThreadState *tstate); -extern void _PyList_ClearFreeList(void); +extern void _PyList_ClearFreeList(PyThreadState *tstate); extern void _PyDict_ClearFreeList(void); extern void _PyAsyncGen_ClearFreeLists(void); extern void _PyContext_ClearFreeList(void); diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 9b805f0..0eab246 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -84,6 +84,16 @@ struct _Py_tuple_state { #endif }; +/* Empty list reuse scheme to save calls to malloc and free */ +#ifndef PyList_MAXFREELIST +# define PyList_MAXFREELIST 80 +#endif + +struct _Py_list_state { + PyListObject *free_list[PyList_MAXFREELIST]; + int numfree; +}; + struct _Py_float_state { /* Special free list free_list is a singly-linked list of available PyFloatObjects, @@ -192,6 +202,7 @@ struct _is { PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS]; #endif struct _Py_tuple_state tuple; + struct _Py_list_state list; struct _Py_float_state float_state; struct _Py_frame_state frame; diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 06d2ac1..3c35ca2 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -61,7 +61,7 @@ extern PyStatus _PyGC_Init(PyThreadState *tstate); extern void _PyFrame_Fini(PyThreadState *tstate); extern void _PyDict_Fini(void); extern void _PyTuple_Fini(PyThreadState *tstate); -extern void _PyList_Fini(void); +extern void _PyList_Fini(PyThreadState *tstate); extern void _PySet_Fini(void); extern void _PyBytes_Fini(void); extern void _PyFloat_Fini(PyThreadState *tstate); |