mirror of https://github.com/python/cpython
gh-111968: Rename freelist related struct names to Eric's suggestion (gh-115329)
This commit is contained in:
parent
518af37eb5
commit
f15795c9a0
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
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(_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);
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
void
|
||||
_PyGC_ClearAllFreeLists(PyInterpreterState *interp)
|
||||
{
|
||||
_PyObject_ClearFreeLists(&interp->freelist_state, 0);
|
||||
_PyObject_ClearFreeLists(&interp->object_state.freelists, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue