summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-06-23 09:33:18 (GMT)
committerGitHub <noreply@github.com>2020-06-23 09:33:18 (GMT)
commitb4e85cadfbc2b1b24ec5f3159e351dbacedaa5e0 (patch)
treea121d0df89bdc965649d65a0ca50543293431e61 /Include
parent26a1ad1c24717990265b71ed093d691500d6301c (diff)
downloadcpython-b4e85cadfbc2b1b24ec5f3159e351dbacedaa5e0.zip
cpython-b4e85cadfbc2b1b24ec5f3159e351dbacedaa5e0.tar.gz
cpython-b4e85cadfbc2b1b24ec5f3159e351dbacedaa5e0.tar.bz2
bpo-40521: Make dict free lists per-interpreter (GH-20645)
Each interpreter now has its own dict free list: * Move dict free lists into PyInterpreterState. * Move PyDict_MAXFREELIST define to pycore_interp.h * Add _Py_dict_state structure. * Add tstate parameter to _PyDict_ClearFreeList() and _PyDict_Fini(). * In debug mode, ensure that the dict free lists are not used after _PyDict_Fini() is called. * Remove "#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS".
Diffstat (limited to 'Include')
-rw-r--r--Include/internal/pycore_gc.h2
-rw-r--r--Include/internal/pycore_interp.h37
-rw-r--r--Include/internal/pycore_pylifecycle.h2
3 files changed, 26 insertions, 15 deletions
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index fd3fb7f..da202a1 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -169,7 +169,7 @@ extern void _PyFrame_ClearFreeList(PyThreadState *tstate);
extern void _PyTuple_ClearFreeList(PyThreadState *tstate);
extern void _PyFloat_ClearFreeList(PyThreadState *tstate);
extern void _PyList_ClearFreeList(PyThreadState *tstate);
-extern void _PyDict_ClearFreeList(void);
+extern void _PyDict_ClearFreeList(PyThreadState *tstate);
extern void _PyAsyncGen_ClearFreeLists(PyThreadState *tstate);
extern void _PyContext_ClearFreeList(PyThreadState *tstate);
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 981b733..3f64edc 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -69,6 +69,14 @@ struct _Py_unicode_state {
struct _Py_unicode_fs_codec fs_codec;
};
+struct _Py_float_state {
+ /* Special free list
+ free_list is a singly-linked list of available PyFloatObjects,
+ linked via abuse of their ob_type members. */
+ int numfree;
+ PyFloatObject *free_list;
+};
+
/* Speed optimization to avoid frequent malloc/free of small tuples */
#ifndef PyTuple_MAXSAVESIZE
// Largest tuple to save on free list
@@ -99,12 +107,16 @@ struct _Py_list_state {
int numfree;
};
-struct _Py_float_state {
- /* Special free list
- free_list is a singly-linked list of available PyFloatObjects,
- linked via abuse of their ob_type members. */
+#ifndef PyDict_MAXFREELIST
+# define PyDict_MAXFREELIST 80
+#endif
+
+struct _Py_dict_state {
+ /* Dictionary reuse scheme to save calls to malloc and free */
+ PyDictObject *free_list[PyDict_MAXFREELIST];
int numfree;
- PyFloatObject *free_list;
+ PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
+ int keys_numfree;
};
struct _Py_frame_state {
@@ -136,7 +148,6 @@ struct _Py_context_state {
};
-
/* interpreter state */
#define _PY_NSMALLPOSINTS 257
@@ -182,8 +193,6 @@ struct _is {
PyObject *codec_error_registry;
int codecs_initialized;
- struct _Py_unicode_state unicode;
-
PyConfig config;
#ifdef HAVE_DLOPEN
int dlopenflags;
@@ -224,16 +233,18 @@ struct _is {
*/
PyLongObject* small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
#endif
+ struct _Py_unicode_state unicode;
+ 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;
+
struct _Py_tuple_state tuple;
struct _Py_list_state list;
- struct _Py_float_state float_state;
+ struct _Py_dict_state dict_state;
struct _Py_frame_state frame;
struct _Py_async_gen_state async_gen;
struct _Py_context_state context;
-
- /* 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 3e36573..dc99737 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -59,7 +59,7 @@ extern PyStatus _PyGC_Init(PyThreadState *tstate);
/* Various internal finalizers */
extern void _PyFrame_Fini(PyThreadState *tstate);
-extern void _PyDict_Fini(void);
+extern void _PyDict_Fini(PyThreadState *tstate);
extern void _PyTuple_Fini(PyThreadState *tstate);
extern void _PyList_Fini(PyThreadState *tstate);
extern void _PySet_Fini(void);