diff options
-rw-r--r-- | Include/internal/pycore_dict.h | 6 | ||||
-rw-r--r-- | Include/internal/pycore_freelist.h | 52 | ||||
-rw-r--r-- | Include/internal/pycore_interp.h | 4 | ||||
-rw-r--r-- | Include/internal/pycore_object_state.h | 4 | ||||
-rw-r--r-- | Include/internal/pycore_pystate.h | 6 | ||||
-rw-r--r-- | Include/internal/pycore_tstate.h | 2 | ||||
-rw-r--r-- | Objects/dictobject.c | 51 | ||||
-rw-r--r-- | Objects/floatobject.c | 38 | ||||
-rw-r--r-- | Objects/genobject.c | 42 | ||||
-rw-r--r-- | Objects/listobject.c | 34 | ||||
-rw-r--r-- | Objects/object.c | 18 | ||||
-rw-r--r-- | Objects/sliceobject.c | 20 | ||||
-rw-r--r-- | Objects/tupleobject.c | 42 | ||||
-rw-r--r-- | Python/context.c | 32 | ||||
-rw-r--r-- | Python/gc_free_threading.c | 2 | ||||
-rw-r--r-- | Python/gc_gil.c | 2 | ||||
-rw-r--r-- | Python/object_stack.c | 34 | ||||
-rw-r--r-- | Python/pylifecycle.c | 4 | ||||
-rw-r--r-- | Python/pystate.c | 4 |
19 files changed, 190 insertions, 207 deletions
diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index 0ebe701..e5ef9a8 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -67,12 +67,6 @@ typedef struct { extern PyObject* _PyDictView_New(PyObject *, PyTypeObject *); extern PyObject* _PyDictView_Intersect(PyObject* self, PyObject *other); - -/* runtime lifecycle */ - -extern void _PyDict_Fini(PyInterpreterState *state); - - /* other API */ typedef struct { diff --git a/Include/internal/pycore_freelist.h b/Include/internal/pycore_freelist.h index 1bc5519..b365ca3 100644 --- a/Include/internal/pycore_freelist.h +++ b/Include/internal/pycore_freelist.h @@ -33,14 +33,14 @@ extern "C" { # define _PyObjectStackChunk_MAXFREELIST 0 #endif -struct _Py_list_state { +struct _Py_list_freelist { #ifdef WITH_FREELISTS PyListObject *free_list[PyList_MAXFREELIST]; int numfree; #endif }; -struct _Py_tuple_state { +struct _Py_tuple_freelist { #if WITH_FREELISTS /* There is one freelist for each size from 1 to PyTuple_MAXSAVESIZE. The empty tuple is handled separately. @@ -57,7 +57,7 @@ struct _Py_tuple_state { #endif }; -struct _Py_float_state { +struct _Py_float_freelist { #ifdef WITH_FREELISTS /* Special free list free_list is a singly-linked list of available PyFloatObjects, @@ -77,7 +77,7 @@ struct _Py_dict_freelist { #endif }; -struct _Py_slice_state { +struct _Py_slice_freelist { #ifdef WITH_FREELISTS /* Using a cache is very effective since typically only a single slice is created and then deleted again. */ @@ -85,7 +85,7 @@ struct _Py_slice_state { #endif }; -struct _Py_context_state { +struct _Py_context_freelist { #ifdef WITH_FREELISTS // List of free PyContext objects PyContext *freelist; @@ -93,7 +93,7 @@ struct _Py_context_state { #endif }; -struct _Py_async_gen_state { +struct _Py_async_gen_freelist { #ifdef WITH_FREELISTS /* Freelists boost performance 6-10%; they also reduce memory fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend @@ -109,31 +109,31 @@ struct _Py_async_gen_state { struct _PyObjectStackChunk; -struct _Py_object_stack_state { +struct _Py_object_stack_freelist { struct _PyObjectStackChunk *free_list; Py_ssize_t numfree; }; -typedef struct _Py_freelist_state { - struct _Py_float_state floats; - struct _Py_tuple_state tuples; - struct _Py_list_state lists; +struct _Py_object_freelists { + struct _Py_float_freelist floats; + struct _Py_tuple_freelist tuples; + struct _Py_list_freelist lists; struct _Py_dict_freelist dicts; - struct _Py_slice_state slices; - struct _Py_context_state contexts; - struct _Py_async_gen_state async_gens; - struct _Py_object_stack_state object_stacks; -} _PyFreeListState; - -extern void _PyObject_ClearFreeLists(_PyFreeListState *state, int is_finalization); -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_ClearFreeList(_PyFreeListState *state, int is_finalization); -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 _PyObjectStackChunk_ClearFreeList(_PyFreeListState *state, int is_finalization); + struct _Py_slice_freelist slices; + struct _Py_context_freelist contexts; + struct _Py_async_gen_freelist async_gens; + struct _Py_object_stack_freelist object_stacks; +}; + +extern void _PyObject_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization); +extern void _PyTuple_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization); +extern void _PyFloat_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization); +extern void _PyList_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization); +extern void _PySlice_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization); +extern void _PyDict_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization); +extern void _PyAsyncGen_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization); +extern void _PyContext_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization); +extern void _PyObjectStackChunk_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization); #ifdef __cplusplus } diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index c244d89..c074471 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -20,7 +20,6 @@ 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 @@ -222,9 +221,6 @@ struct _is { // One bit is set for each non-NULL entry in code_watchers uint8_t active_code_watchers; -#if !defined(Py_GIL_DISABLED) - struct _Py_freelist_state freelist_state; -#endif struct _py_object_state object_state; struct _Py_unicode_state unicode; struct _Py_long_state long_state; diff --git a/Include/internal/pycore_object_state.h b/Include/internal/pycore_object_state.h index 9eac27b1..cd7c933 100644 --- a/Include/internal/pycore_object_state.h +++ b/Include/internal/pycore_object_state.h @@ -8,6 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_freelist.h" // _PyObject_freelists #include "pycore_hashtable.h" // _Py_hashtable_t struct _py_object_runtime_state { @@ -18,6 +19,9 @@ struct _py_object_runtime_state { }; struct _py_object_state { +#if !defined(Py_GIL_DISABLED) + struct _Py_object_freelists freelists; +#endif #ifdef Py_REF_DEBUG Py_ssize_t reftotal; #endif diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index 289ef28..6f9e6a3 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -268,7 +268,7 @@ PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); // See also PyInterpreterState_Get() and _PyInterpreterState_GET(). extern PyInterpreterState* _PyGILState_GetInterpreterStateUnsafe(void); -static inline _PyFreeListState* _PyFreeListState_GET(void) +static inline struct _Py_object_freelists* _Py_object_freelists_GET(void) { PyThreadState *tstate = _PyThreadState_GET(); #ifdef Py_DEBUG @@ -276,9 +276,9 @@ static inline _PyFreeListState* _PyFreeListState_GET(void) #endif #ifdef Py_GIL_DISABLED - return &((_PyThreadStateImpl*)tstate)->freelist_state; + return &((_PyThreadStateImpl*)tstate)->freelists; #else - return &tstate->interp->freelist_state; + return &tstate->interp->object_state.freelists; #endif } diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h index 3e8fcf5..97aa85a 100644 --- a/Include/internal/pycore_tstate.h +++ b/Include/internal/pycore_tstate.h @@ -29,7 +29,7 @@ typedef struct _PyThreadStateImpl { #ifdef Py_GIL_DISABLED struct _mimalloc_thread_state mimalloc; - struct _Py_freelist_state freelist_state; + struct _Py_object_freelists freelists; struct _brc_thread_state brc; #endif diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 9b1defa..11667b0 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -271,19 +271,19 @@ dict_setdefault_ref_lock_held(PyObject *d, PyObject *key, PyObject *default_valu #ifdef WITH_FREELISTS static struct _Py_dict_freelist * -get_dict_state(void) +get_dict_freelist(void) { - _PyFreeListState *state = _PyFreeListState_GET(); - return &state->dicts; + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + return &freelists->dicts; } #endif void -_PyDict_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) +_PyDict_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization) { #ifdef WITH_FREELISTS - struct _Py_dict_freelist *state = &freelist_state->dicts; + struct _Py_dict_freelist *state = &freelists->dicts; while (state->numfree > 0) { PyDictObject *op = state->free_list[--state->numfree]; assert(PyDict_CheckExact(op)); @@ -299,17 +299,6 @@ _PyDict_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) #endif } -void -_PyDict_Fini(PyInterpreterState *Py_UNUSED(interp)) -{ - // With Py_GIL_DISABLED: - // the freelists for the current thread state have already been cleared. -#ifndef Py_GIL_DISABLED - _PyFreeListState *state = _PyFreeListState_GET(); - _PyDict_ClearFreeList(state, 1); -#endif -} - static inline Py_hash_t unicode_get_hash(PyObject *o) { @@ -322,9 +311,9 @@ void _PyDict_DebugMallocStats(FILE *out) { #ifdef WITH_FREELISTS - struct _Py_dict_freelist *state = get_dict_state(); + struct _Py_dict_freelist *dict_freelist = get_dict_freelist(); _PyDebugAllocatorStats(out, "free PyDictObject", - state->numfree, sizeof(PyDictObject)); + dict_freelist->numfree, sizeof(PyDictObject)); #endif } @@ -674,9 +663,9 @@ new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode) } #ifdef WITH_FREELISTS - struct _Py_dict_freelist *state = get_dict_state(); - if (log2_size == PyDict_LOG_MINSIZE && unicode && state->keys_numfree > 0) { - dk = state->keys_free_list[--state->keys_numfree]; + struct _Py_dict_freelist *dict_freelist = get_dict_freelist(); + if (log2_size == PyDict_LOG_MINSIZE && unicode && dict_freelist->keys_numfree > 0) { + dk = dict_freelist->keys_free_list[--dict_freelist->keys_numfree]; OBJECT_STAT_INC(from_freelist); } else @@ -709,12 +698,12 @@ static void free_keys_object(PyDictKeysObject *keys) { #ifdef WITH_FREELISTS - struct _Py_dict_freelist *state = get_dict_state(); + struct _Py_dict_freelist *dict_freelist = get_dict_freelist(); if (DK_LOG_SIZE(keys) == PyDict_LOG_MINSIZE - && state->keys_numfree < PyDict_MAXFREELIST - && state->keys_numfree >= 0 + && dict_freelist->keys_numfree < PyDict_MAXFREELIST + && dict_freelist->keys_numfree >= 0 && DK_IS_UNICODE(keys)) { - state->keys_free_list[state->keys_numfree++] = keys; + dict_freelist->keys_free_list[dict_freelist->keys_numfree++] = keys; OBJECT_STAT_INC(to_freelist); return; } @@ -754,9 +743,9 @@ new_dict(PyInterpreterState *interp, PyDictObject *mp; assert(keys != NULL); #ifdef WITH_FREELISTS - struct _Py_dict_freelist *state = get_dict_state(); - if (state->numfree > 0) { - mp = state->free_list[--state->numfree]; + struct _Py_dict_freelist *dict_freelist = get_dict_freelist(); + if (dict_freelist->numfree > 0) { + mp = dict_freelist->free_list[--dict_freelist->numfree]; assert (mp != NULL); assert (Py_IS_TYPE(mp, &PyDict_Type)); OBJECT_STAT_INC(from_freelist); @@ -2604,10 +2593,10 @@ dict_dealloc(PyObject *self) dictkeys_decref(interp, keys); } #ifdef WITH_FREELISTS - struct _Py_dict_freelist *state = get_dict_state(); - if (state->numfree < PyDict_MAXFREELIST && state->numfree >=0 && + struct _Py_dict_freelist *dict_freelist = get_dict_freelist(); + if (dict_freelist->numfree < PyDict_MAXFREELIST && dict_freelist->numfree >=0 && Py_IS_TYPE(mp, &PyDict_Type)) { - state->free_list[state->numfree++] = mp; + dict_freelist->free_list[dict_freelist->numfree++] = mp; OBJECT_STAT_INC(to_freelist); } else diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 9b322c5..7dac829 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -8,7 +8,7 @@ #include "pycore_dtoa.h" // _Py_dg_dtoa() #include "pycore_floatobject.h" // _PyFloat_FormatAdvancedWriter() #include "pycore_initconfig.h" // _PyStatus_OK() -#include "pycore_interp.h" // _PyInterpreterState.float_state +#include "pycore_interp.h" // _Py_float_freelist #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_object.h" // _PyObject_Init(), _PyDebugAllocatorStats() @@ -27,12 +27,12 @@ class float "PyObject *" "&PyFloat_Type" #include "clinic/floatobject.c.h" #ifdef WITH_FREELISTS -static struct _Py_float_state * -get_float_state(void) +static struct _Py_float_freelist * +get_float_freelist(void) { - _PyFreeListState *state = _PyFreeListState_GET(); - assert(state != NULL); - return &state->floats; + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + assert(freelists != NULL); + return &freelists->floats; } #endif @@ -129,11 +129,11 @@ PyFloat_FromDouble(double fval) { PyFloatObject *op; #ifdef WITH_FREELISTS - struct _Py_float_state *state = get_float_state(); - op = state->free_list; + struct _Py_float_freelist *float_freelist = get_float_freelist(); + op = float_freelist->free_list; if (op != NULL) { - state->free_list = (PyFloatObject *) Py_TYPE(op); - state->numfree--; + float_freelist->free_list = (PyFloatObject *) Py_TYPE(op); + float_freelist->numfree--; OBJECT_STAT_INC(from_freelist); } else @@ -245,14 +245,14 @@ _PyFloat_ExactDealloc(PyObject *obj) assert(PyFloat_CheckExact(obj)); PyFloatObject *op = (PyFloatObject *)obj; #ifdef WITH_FREELISTS - struct _Py_float_state *state = get_float_state(); - if (state->numfree >= PyFloat_MAXFREELIST || state->numfree < 0) { + struct _Py_float_freelist *float_freelist = get_float_freelist(); + if (float_freelist->numfree >= PyFloat_MAXFREELIST || float_freelist->numfree < 0) { PyObject_Free(op); return; } - state->numfree++; - Py_SET_TYPE(op, (PyTypeObject *)state->free_list); - state->free_list = op; + float_freelist->numfree++; + Py_SET_TYPE(op, (PyTypeObject *)float_freelist->free_list); + float_freelist->free_list = op; OBJECT_STAT_INC(to_freelist); #else PyObject_Free(op); @@ -1990,10 +1990,10 @@ _PyFloat_InitTypes(PyInterpreterState *interp) } void -_PyFloat_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) +_PyFloat_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization) { #ifdef WITH_FREELISTS - struct _Py_float_state *state = &freelist_state->floats; + struct _Py_float_freelist *state = &freelists->floats; PyFloatObject *f = state->free_list; while (f != NULL) { PyFloatObject *next = (PyFloatObject*) Py_TYPE(f); @@ -2021,10 +2021,10 @@ void _PyFloat_DebugMallocStats(FILE *out) { #ifdef WITH_FREELISTS - struct _Py_float_state *state = get_float_state(); + struct _Py_float_freelist *float_freelist = get_float_freelist(); _PyDebugAllocatorStats(out, "free PyFloatObject", - state->numfree, sizeof(PyFloatObject)); + float_freelist->numfree, sizeof(PyFloatObject)); #endif } diff --git a/Objects/genobject.c b/Objects/genobject.c index 59ab7ab..a1b6db1 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -7,7 +7,7 @@ #include "pycore_ceval.h" // _PyEval_EvalFrame() #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_gc.h" // _PyGC_CLEAR_FINALIZED() -#include "pycore_genobject.h" // struct _Py_async_gen_state +#include "pycore_genobject.h" // struct _Py_async_gen_freelist #include "pycore_modsupport.h" // _PyArg_CheckPositional() #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_opcode_utils.h" // RESUME_AFTER_YIELD_FROM @@ -1629,11 +1629,11 @@ PyTypeObject PyAsyncGen_Type = { #ifdef WITH_FREELISTS -static struct _Py_async_gen_state * -get_async_gen_state(void) +static struct _Py_async_gen_freelist * +get_async_gen_freelist(void) { - _PyFreeListState *state = _PyFreeListState_GET(); - return &state->async_gens; + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + return &freelists->async_gens; } #endif @@ -1656,10 +1656,10 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname) void -_PyAsyncGen_ClearFreeLists(_PyFreeListState *freelist_state, int is_finalization) +_PyAsyncGen_ClearFreeLists(struct _Py_object_freelists *freelist_state, int is_finalization) { #ifdef WITH_FREELISTS - struct _Py_async_gen_state *state = &freelist_state->async_gens; + struct _Py_async_gen_freelist *state = &freelist_state->async_gens; while (state->value_numfree > 0) { _PyAsyncGenWrappedValue *o; @@ -1726,11 +1726,11 @@ async_gen_asend_dealloc(PyAsyncGenASend *o) Py_CLEAR(o->ags_gen); Py_CLEAR(o->ags_sendval); #ifdef WITH_FREELISTS - struct _Py_async_gen_state *state = get_async_gen_state(); - if (state->asend_numfree >= 0 && state->asend_numfree < _PyAsyncGen_MAXFREELIST) { + struct _Py_async_gen_freelist *async_gen_freelist = get_async_gen_freelist(); + if (async_gen_freelist->asend_numfree >= 0 && async_gen_freelist->asend_numfree < _PyAsyncGen_MAXFREELIST) { assert(PyAsyncGenASend_CheckExact(o)); _PyGC_CLEAR_FINALIZED((PyObject *)o); - state->asend_freelist[state->asend_numfree++] = o; + async_gen_freelist->asend_freelist[async_gen_freelist->asend_numfree++] = o; } else #endif @@ -1896,10 +1896,10 @@ async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval) { PyAsyncGenASend *o; #ifdef WITH_FREELISTS - struct _Py_async_gen_state *state = get_async_gen_state(); - if (state->asend_numfree > 0) { - state->asend_numfree--; - o = state->asend_freelist[state->asend_numfree]; + struct _Py_async_gen_freelist *async_gen_freelist = get_async_gen_freelist(); + if (async_gen_freelist->asend_numfree > 0) { + async_gen_freelist->asend_numfree--; + o = async_gen_freelist->asend_freelist[async_gen_freelist->asend_numfree]; _Py_NewReference((PyObject *)o); } else @@ -1931,10 +1931,10 @@ async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o) _PyObject_GC_UNTRACK((PyObject *)o); Py_CLEAR(o->agw_val); #ifdef WITH_FREELISTS - struct _Py_async_gen_state *state = get_async_gen_state(); - if (state->value_numfree >= 0 && state->value_numfree < _PyAsyncGen_MAXFREELIST) { + struct _Py_async_gen_freelist *async_gen_freelist = get_async_gen_freelist(); + if (async_gen_freelist->value_numfree >= 0 && async_gen_freelist->value_numfree < _PyAsyncGen_MAXFREELIST) { assert(_PyAsyncGenWrappedValue_CheckExact(o)); - state->value_freelist[state->value_numfree++] = o; + async_gen_freelist->value_freelist[async_gen_freelist->value_numfree++] = o; OBJECT_STAT_INC(to_freelist); } else @@ -2004,10 +2004,10 @@ _PyAsyncGenValueWrapperNew(PyThreadState *tstate, PyObject *val) assert(val); #ifdef WITH_FREELISTS - struct _Py_async_gen_state *state = get_async_gen_state(); - if (state->value_numfree > 0) { - state->value_numfree--; - o = state->value_freelist[state->value_numfree]; + struct _Py_async_gen_freelist *async_gen_freelist = get_async_gen_freelist(); + if (async_gen_freelist->value_numfree > 0) { + async_gen_freelist->value_numfree--; + o = async_gen_freelist->value_freelist[async_gen_freelist->value_numfree]; OBJECT_STAT_INC(from_freelist); assert(_PyAsyncGenWrappedValue_CheckExact(o)); _Py_NewReference((PyObject*)o); diff --git a/Objects/listobject.c b/Objects/listobject.c index 7fdb91e..93409a8 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -4,7 +4,7 @@ #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_interp.h" // PyInterpreterState.list -#include "pycore_list.h" // struct _Py_list_state, _PyListIterObject +#include "pycore_list.h" // struct _Py_list_freelist, _PyListIterObject #include "pycore_long.h" // _PyLong_DigitCount #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats() @@ -21,12 +21,12 @@ class list "PyListObject *" "&PyList_Type" _Py_DECLARE_STR(list_err, "list index out of range"); #ifdef WITH_FREELISTS -static struct _Py_list_state * -get_list_state(void) +static struct _Py_list_freelist * +get_list_freelist(void) { - _PyFreeListState *state = _PyFreeListState_GET(); - assert(state != NULL); - return &state->lists; + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + assert(freelists != NULL); + return &freelists->lists; } #endif @@ -120,10 +120,10 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size) } void -_PyList_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) +_PyList_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization) { #ifdef WITH_FREELISTS - struct _Py_list_state *state = &freelist_state->lists; + struct _Py_list_freelist *state = &freelists->lists; while (state->numfree > 0) { PyListObject *op = state->free_list[--state->numfree]; assert(PyList_CheckExact(op)); @@ -140,10 +140,10 @@ void _PyList_DebugMallocStats(FILE *out) { #ifdef WITH_FREELISTS - struct _Py_list_state *state = get_list_state(); + struct _Py_list_freelist *list_freelist = get_list_freelist(); _PyDebugAllocatorStats(out, "free PyListObject", - state->numfree, sizeof(PyListObject)); + list_freelist->numfree, sizeof(PyListObject)); #endif } @@ -158,10 +158,10 @@ PyList_New(Py_ssize_t size) } #ifdef WITH_FREELISTS - struct _Py_list_state *state = get_list_state(); - if (PyList_MAXFREELIST && state->numfree > 0) { - state->numfree--; - op = state->free_list[state->numfree]; + struct _Py_list_freelist *list_freelist = get_list_freelist(); + if (PyList_MAXFREELIST && list_freelist->numfree > 0) { + list_freelist->numfree--; + op = list_freelist->free_list[list_freelist->numfree]; OBJECT_STAT_INC(from_freelist); _Py_NewReference((PyObject *)op); } @@ -391,9 +391,9 @@ list_dealloc(PyObject *self) PyMem_Free(op->ob_item); } #ifdef WITH_FREELISTS - struct _Py_list_state *state = get_list_state(); - if (state->numfree < PyList_MAXFREELIST && state->numfree >= 0 && PyList_CheckExact(op)) { - state->free_list[state->numfree++] = op; + struct _Py_list_freelist *list_freelist = get_list_freelist(); + if (list_freelist->numfree < PyList_MAXFREELIST && list_freelist->numfree >= 0 && PyList_CheckExact(op)) { + list_freelist->free_list[list_freelist->numfree++] = op; OBJECT_STAT_INC(to_freelist); } else diff --git a/Objects/object.c b/Objects/object.c index 275aa671..23eab82 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -794,19 +794,19 @@ PyObject_Bytes(PyObject *v) } void -_PyObject_ClearFreeLists(_PyFreeListState *state, int is_finalization) +_PyObject_ClearFreeLists(struct _Py_object_freelists *freelists, int is_finalization) { // In the free-threaded build, freelists are per-PyThreadState and cleared in PyThreadState_Clear() // In the default build, freelists are per-interpreter and cleared in finalize_interp_types() - _PyFloat_ClearFreeList(state, is_finalization); - _PyTuple_ClearFreeList(state, is_finalization); - _PyList_ClearFreeList(state, is_finalization); - _PyDict_ClearFreeList(state, is_finalization); - _PyContext_ClearFreeList(state, is_finalization); - _PyAsyncGen_ClearFreeLists(state, is_finalization); + _PyFloat_ClearFreeList(freelists, is_finalization); + _PyTuple_ClearFreeList(freelists, is_finalization); + _PyList_ClearFreeList(freelists, is_finalization); + _PyDict_ClearFreeList(freelists, is_finalization); + _PyContext_ClearFreeList(freelists, is_finalization); + _PyAsyncGen_ClearFreeLists(freelists, is_finalization); // Only be cleared if is_finalization is true. - _PyObjectStackChunk_ClearFreeList(state, is_finalization); - _PySlice_ClearFreeList(state, is_finalization); + _PyObjectStackChunk_ClearFreeList(freelists, is_finalization); + _PySlice_ClearFreeList(freelists, is_finalization); } /* diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 9880c12..7333aea 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -103,15 +103,15 @@ PyObject _Py_EllipsisObject = _PyObject_HEAD_INIT(&PyEllipsis_Type); /* Slice object implementation */ -void _PySlice_ClearFreeList(_PyFreeListState *state, int is_finalization) +void _PySlice_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization) { if (!is_finalization) { return; } #ifdef WITH_FREELISTS - PySliceObject *obj = state->slices.slice_cache; + PySliceObject *obj = freelists->slices.slice_cache; if (obj != NULL) { - state->slices.slice_cache = NULL; + freelists->slices.slice_cache = NULL; PyObject_GC_Del(obj); } #endif @@ -127,10 +127,10 @@ _PyBuildSlice_Consume2(PyObject *start, PyObject *stop, PyObject *step) assert(start != NULL && stop != NULL && step != NULL); PySliceObject *obj; #ifdef WITH_FREELISTS - _PyFreeListState *state = _PyFreeListState_GET(); - if (state->slices.slice_cache != NULL) { - obj = state->slices.slice_cache; - state->slices.slice_cache = NULL; + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + if (freelists->slices.slice_cache != NULL) { + obj = freelists->slices.slice_cache; + freelists->slices.slice_cache = NULL; _Py_NewReference((PyObject *)obj); } else @@ -365,9 +365,9 @@ slice_dealloc(PySliceObject *r) Py_DECREF(r->start); Py_DECREF(r->stop); #ifdef WITH_FREELISTS - _PyFreeListState *state = _PyFreeListState_GET(); - if (state->slices.slice_cache == NULL) { - state->slices.slice_cache = r; + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + if (freelists->slices.slice_cache == NULL) { + freelists->slices.slice_cache = r; } else #endif diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 7d73c3f..1cdf79d 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -962,13 +962,13 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) } -static void maybe_freelist_clear(_PyFreeListState *, int); +static void maybe_freelist_clear(struct _Py_object_freelists *, int); void -_PyTuple_ClearFreeList(_PyFreeListState *state, int is_finalization) +_PyTuple_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization) { - maybe_freelist_clear(state, is_finalization); + maybe_freelist_clear(freelists, is_finalization); } /*********************** Tuple Iterator **************************/ @@ -1120,26 +1120,26 @@ tuple_iter(PyObject *seq) * freelists * *************/ -#define STATE (state->tuples) -#define FREELIST_FINALIZED (STATE.numfree[0] < 0) +#define TUPLE_FREELIST (freelists->tuples) +#define FREELIST_FINALIZED (TUPLE_FREELIST.numfree[0] < 0) static inline PyTupleObject * maybe_freelist_pop(Py_ssize_t size) { #ifdef WITH_FREELISTS - _PyFreeListState *state = _PyFreeListState_GET(); + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); if (size == 0) { return NULL; } assert(size > 0); if (size < PyTuple_MAXSAVESIZE) { Py_ssize_t index = size - 1; - PyTupleObject *op = STATE.free_list[index]; + PyTupleObject *op = TUPLE_FREELIST.free_list[index]; if (op != NULL) { /* op is the head of a linked list, with the first item pointing to the next node. Here we pop off the old head. */ - STATE.free_list[index] = (PyTupleObject *) op->ob_item[0]; - STATE.numfree[index]--; + TUPLE_FREELIST.free_list[index] = (PyTupleObject *) op->ob_item[0]; + TUPLE_FREELIST.numfree[index]--; /* Inlined _PyObject_InitVar() without _PyType_HasFeature() test */ #ifdef Py_TRACE_REFS /* maybe_freelist_push() ensures these were already set. */ @@ -1161,21 +1161,21 @@ static inline int maybe_freelist_push(PyTupleObject *op) { #ifdef WITH_FREELISTS - _PyFreeListState *state = _PyFreeListState_GET(); + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); if (Py_SIZE(op) == 0) { return 0; } Py_ssize_t index = Py_SIZE(op) - 1; if (index < PyTuple_NFREELISTS - && STATE.numfree[index] < PyTuple_MAXFREELIST - && STATE.numfree[index] >= 0 + && TUPLE_FREELIST.numfree[index] < PyTuple_MAXFREELIST + && TUPLE_FREELIST.numfree[index] >= 0 && Py_IS_TYPE(op, &PyTuple_Type)) { /* op is the head of a linked list, with the first item pointing to the next node. Here we set op as the new head. */ - op->ob_item[0] = (PyObject *) STATE.free_list[index]; - STATE.free_list[index] = op; - STATE.numfree[index]++; + op->ob_item[0] = (PyObject *) TUPLE_FREELIST.free_list[index]; + TUPLE_FREELIST.free_list[index] = op; + TUPLE_FREELIST.numfree[index]++; OBJECT_STAT_INC(to_freelist); return 1; } @@ -1184,13 +1184,13 @@ maybe_freelist_push(PyTupleObject *op) } static void -maybe_freelist_clear(_PyFreeListState *state, int fini) +maybe_freelist_clear(struct _Py_object_freelists *freelists, int fini) { #ifdef WITH_FREELISTS for (Py_ssize_t i = 0; i < PyTuple_NFREELISTS; i++) { - PyTupleObject *p = STATE.free_list[i]; - STATE.free_list[i] = NULL; - STATE.numfree[i] = fini ? -1 : 0; + PyTupleObject *p = TUPLE_FREELIST.free_list[i]; + TUPLE_FREELIST.free_list[i] = NULL; + TUPLE_FREELIST.numfree[i] = fini ? -1 : 0; while (p) { PyTupleObject *q = p; p = (PyTupleObject *)(p->ob_item[0]); @@ -1205,13 +1205,13 @@ void _PyTuple_DebugMallocStats(FILE *out) { #ifdef WITH_FREELISTS - _PyFreeListState *state = _PyFreeListState_GET(); + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); for (int i = 0; i < PyTuple_NFREELISTS; i++) { int len = i + 1; char buf[128]; PyOS_snprintf(buf, sizeof(buf), "free %d-sized PyTupleObject", len); - _PyDebugAllocatorStats(out, buf, STATE.numfree[i], + _PyDebugAllocatorStats(out, buf, TUPLE_FREELIST.numfree[i], _PyObject_VAR_SIZE(&PyTuple_Type, len)); } #endif diff --git a/Python/context.c b/Python/context.c index e44fef7..01a21b4 100644 --- a/Python/context.c +++ b/Python/context.c @@ -65,11 +65,11 @@ contextvar_del(PyContextVar *var); #ifdef WITH_FREELISTS -static struct _Py_context_state * -get_context_state(void) +static struct _Py_context_freelist * +get_context_freelist(void) { - _PyFreeListState *state = _PyFreeListState_GET(); - return &state->contexts; + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + return &freelists->contexts; } #endif @@ -341,11 +341,11 @@ _context_alloc(void) { PyContext *ctx; #ifdef WITH_FREELISTS - struct _Py_context_state *state = get_context_state(); - if (state->numfree > 0) { - state->numfree--; - ctx = state->freelist; - state->freelist = (PyContext *)ctx->ctx_weakreflist; + struct _Py_context_freelist *context_freelist = get_context_freelist(); + if (context_freelist->numfree > 0) { + context_freelist->numfree--; + ctx = context_freelist->freelist; + context_freelist->freelist = (PyContext *)ctx->ctx_weakreflist; OBJECT_STAT_INC(from_freelist); ctx->ctx_weakreflist = NULL; _Py_NewReference((PyObject *)ctx); @@ -468,11 +468,11 @@ context_tp_dealloc(PyContext *self) (void)context_tp_clear(self); #ifdef WITH_FREELISTS - struct _Py_context_state *state = get_context_state(); - if (state->numfree >= 0 && state->numfree < PyContext_MAXFREELIST) { - state->numfree++; - self->ctx_weakreflist = (PyObject *)state->freelist; - state->freelist = self; + struct _Py_context_freelist *context_freelist = get_context_freelist(); + if (context_freelist->numfree >= 0 && context_freelist->numfree < PyContext_MAXFREELIST) { + context_freelist->numfree++; + self->ctx_weakreflist = (PyObject *)context_freelist->freelist; + context_freelist->freelist = self; OBJECT_STAT_INC(to_freelist); } else @@ -1267,10 +1267,10 @@ get_token_missing(void) void -_PyContext_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization) +_PyContext_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization) { #ifdef WITH_FREELISTS - struct _Py_context_state *state = &freelist_state->contexts; + struct _Py_context_freelist *state = &freelists->contexts; for (; state->numfree > 0; state->numfree--) { PyContext *ctx = state->freelist; state->freelist = (PyContext *)ctx->ctx_weakreflist; diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index 93e1168..3dc1dc1 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -1721,7 +1721,7 @@ _PyGC_ClearAllFreeLists(PyInterpreterState *interp) HEAD_LOCK(&_PyRuntime); _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head; while (tstate != NULL) { - _PyObject_ClearFreeLists(&tstate->freelist_state, 0); + _PyObject_ClearFreeLists(&tstate->freelists, 0); tstate = (_PyThreadStateImpl *)tstate->base.next; } HEAD_UNLOCK(&_PyRuntime); diff --git a/Python/gc_gil.c b/Python/gc_gil.c index 5f1365f..48646c7 100644 --- a/Python/gc_gil.c +++ b/Python/gc_gil.c @@ -11,7 +11,7 @@ void _PyGC_ClearAllFreeLists(PyInterpreterState *interp) { - _PyObject_ClearFreeLists(&interp->freelist_state, 0); + _PyObject_ClearFreeLists(&interp->object_state.freelists, 0); } #endif diff --git a/Python/object_stack.c b/Python/object_stack.c index ced4460..ff2901c 100644 --- a/Python/object_stack.c +++ b/Python/object_stack.c @@ -8,22 +8,22 @@ extern _PyObjectStackChunk *_PyObjectStackChunk_New(void); extern void _PyObjectStackChunk_Free(_PyObjectStackChunk *); -static struct _Py_object_stack_state * -get_state(void) +static struct _Py_object_stack_freelist * +get_object_stack_freelist(void) { - _PyFreeListState *state = _PyFreeListState_GET(); - return &state->object_stacks; + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + return &freelists->object_stacks; } _PyObjectStackChunk * _PyObjectStackChunk_New(void) { _PyObjectStackChunk *buf; - struct _Py_object_stack_state *state = get_state(); - if (state->numfree > 0) { - buf = state->free_list; - state->free_list = buf->prev; - state->numfree--; + struct _Py_object_stack_freelist *obj_stack_freelist = get_object_stack_freelist(); + if (obj_stack_freelist->numfree > 0) { + buf = obj_stack_freelist->free_list; + obj_stack_freelist->free_list = buf->prev; + obj_stack_freelist->numfree--; } else { // NOTE: we use PyMem_RawMalloc() here because this is used by the GC @@ -43,13 +43,13 @@ void _PyObjectStackChunk_Free(_PyObjectStackChunk *buf) { assert(buf->n == 0); - struct _Py_object_stack_state *state = get_state(); - if (state->numfree >= 0 && - state->numfree < _PyObjectStackChunk_MAXFREELIST) + struct _Py_object_stack_freelist *obj_stack_freelist = get_object_stack_freelist(); + if (obj_stack_freelist->numfree >= 0 && + obj_stack_freelist->numfree < _PyObjectStackChunk_MAXFREELIST) { - buf->prev = state->free_list; - state->free_list = buf; - state->numfree++; + buf->prev = obj_stack_freelist->free_list; + obj_stack_freelist->free_list = buf; + obj_stack_freelist->numfree++; } else { PyMem_RawFree(buf); @@ -89,7 +89,7 @@ _PyObjectStack_Merge(_PyObjectStack *dst, _PyObjectStack *src) } void -_PyObjectStackChunk_ClearFreeList(_PyFreeListState *free_lists, int is_finalization) +_PyObjectStackChunk_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization) { if (!is_finalization) { // Ignore requests to clear the free list during GC. We use object @@ -97,7 +97,7 @@ _PyObjectStackChunk_ClearFreeList(_PyFreeListState *free_lists, int is_finalizat return; } - struct _Py_object_stack_state *state = &free_lists->object_stacks; + struct _Py_object_stack_freelist *state = &freelists->object_stacks; while (state->numfree > 0) { _PyObjectStackChunk *buf = state->free_list; state->free_list = buf->prev; diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 7e4c07b..5e5db98 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1795,8 +1795,8 @@ finalize_interp_types(PyInterpreterState *interp) #ifndef Py_GIL_DISABLED // With Py_GIL_DISABLED: // the freelists for the current thread state have already been cleared. - _PyFreeListState *state = _PyFreeListState_GET(); - _PyObject_ClearFreeLists(state, 1); + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + _PyObject_ClearFreeLists(freelists, 1); #endif #ifdef Py_DEBUG diff --git a/Python/pystate.c b/Python/pystate.c index 996f465..82c9558 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -1548,8 +1548,8 @@ PyThreadState_Clear(PyThreadState *tstate) } #ifdef Py_GIL_DISABLED // Each thread should clear own freelists in free-threading builds. - _PyFreeListState *freelist_state = _PyFreeListState_GET(); - _PyObject_ClearFreeLists(freelist_state, 1); + struct _Py_object_freelists *freelists = _Py_object_freelists_GET(); + _PyObject_ClearFreeLists(freelists, 1); // Remove ourself from the biased reference counting table of threads. _Py_brc_remove_thread(tstate); |