gh-111968: Use per-thread freelists for dict in free-threading (gh-114323)

This commit is contained in:
Donghee Na 2024-02-02 05:53:53 +09:00 committed by GitHub
parent 587d480203
commit 13907968d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 75 additions and 75 deletions

View file

@ -9,6 +9,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
#include "pycore_freelist.h" // _PyFreeListState
#include "pycore_identifier.h" // _Py_Identifier
#include "pycore_object.h" // PyDictOrValues
@ -69,7 +70,7 @@ extern PyObject* _PyDictView_Intersect(PyObject* self, PyObject *other);
/* runtime lifecycle */
extern void _PyDict_Fini(PyInterpreterState *interp);
extern void _PyDict_Fini(PyInterpreterState *state);
/* other API */

View file

@ -8,16 +8,6 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
#ifndef WITH_FREELISTS
// without freelists
# define PyDict_MAXFREELIST 0
#endif
#ifndef PyDict_MAXFREELIST
# define PyDict_MAXFREELIST 80
#endif
#define DICT_MAX_WATCHERS 8
struct _Py_dict_state {
@ -26,15 +16,6 @@ struct _Py_dict_state {
* time that a dictionary is modified. */
uint64_t global_version;
uint32_t next_keys_version;
#if PyDict_MAXFREELIST > 0
/* Dictionary reuse scheme to save calls to malloc and free */
PyDictObject *free_list[PyDict_MAXFREELIST];
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
int numfree;
int keys_numfree;
#endif
PyDict_WatchCallback watchers[DICT_MAX_WATCHERS];
};

View file

@ -17,6 +17,7 @@ extern "C" {
# define PyTuple_NFREELISTS PyTuple_MAXSAVESIZE
# define PyTuple_MAXFREELIST 2000
# define PyList_MAXFREELIST 80
# define PyDict_MAXFREELIST 80
# define PyFloat_MAXFREELIST 100
# define PyContext_MAXFREELIST 255
# define _PyAsyncGen_MAXFREELIST 80
@ -25,6 +26,7 @@ extern "C" {
# define PyTuple_NFREELISTS 0
# define PyTuple_MAXFREELIST 0
# define PyList_MAXFREELIST 0
# define PyDict_MAXFREELIST 0
# define PyFloat_MAXFREELIST 0
# define PyContext_MAXFREELIST 0
# define _PyAsyncGen_MAXFREELIST 0
@ -65,6 +67,16 @@ struct _Py_float_state {
#endif
};
struct _Py_dict_freelist {
#ifdef WITH_FREELISTS
/* Dictionary reuse scheme to save calls to malloc and free */
PyDictObject *free_list[PyDict_MAXFREELIST];
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
int numfree;
int keys_numfree;
#endif
};
struct _Py_slice_state {
#ifdef WITH_FREELISTS
/* Using a cache is very effective since typically only a single slice is
@ -106,6 +118,7 @@ typedef struct _Py_freelist_state {
struct _Py_float_state floats;
struct _Py_tuple_state tuples;
struct _Py_list_state lists;
struct _Py_dict_freelist dicts;
struct _Py_slice_state slices;
struct _Py_context_state contexts;
struct _Py_async_gen_state async_gens;

View file

@ -267,7 +267,7 @@ extern void _PyTuple_ClearFreeList(_PyFreeListState *state, int is_finalization)
extern void _PyFloat_ClearFreeList(_PyFreeListState *state, int is_finalization);
extern void _PyList_ClearFreeList(_PyFreeListState *state, int is_finalization);
extern void _PySlice_ClearCache(_PyFreeListState *state);
extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
extern void _PyDict_ClearFreeList(_PyFreeListState *state, int is_finalization);
extern void _PyAsyncGen_ClearFreeLists(_PyFreeListState *state, int is_finalization);
extern void _PyContext_ClearFreeList(_PyFreeListState *state, int is_finalization);
extern void _Py_ScheduleGC(PyInterpreterState *interp);

View file

@ -20,6 +20,7 @@ extern "C" {
#include "pycore_dtoa.h" // struct _dtoa_state
#include "pycore_exceptions.h" // struct _Py_exc_state
#include "pycore_floatobject.h" // struct _Py_float_state
#include "pycore_freelist.h" // struct _Py_freelist_state
#include "pycore_function.h" // FUNC_MAX_WATCHERS
#include "pycore_gc.h" // struct _gc_runtime_state
#include "pycore_genobject.h" // struct _Py_async_gen_state
@ -230,7 +231,6 @@ struct _is {
struct _dtoa_state dtoa;
struct _py_func_state func_state;
struct _Py_tuple_state tuple;
struct _Py_dict_state dict_state;
struct _Py_exc_state exc_state;