mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	bpo-40428: Remove PyTuple_ClearFreeList() function (GH-19769)
Remove the following function from the C API: * PyAsyncGen_ClearFreeLists() * PyContext_ClearFreeList() * PyDict_ClearFreeList() * PyFloat_ClearFreeList() * PyFrame_ClearFreeList() * PyList_ClearFreeList() * PySet_ClearFreeList() * PyTuple_ClearFreeList() Make these functions private, move them to the internal C API and change their return type to void. Call explicitly PyGC_Collect() to free all free lists. Note: PySet_ClearFreeList() did nothing.
This commit is contained in:
		
							parent
							
								
									cc0dc7e484
								
							
						
					
					
						commit
						ae00a5a885
					
				
					 21 changed files with 71 additions and 86 deletions
				
			
		|  | @ -672,6 +672,19 @@ Build and C API Changes | ||||||
|   the garbage collector respectively. (Contributed by Pablo Galindo in |   the garbage collector respectively. (Contributed by Pablo Galindo in | ||||||
|   :issue:`40241`.) |   :issue:`40241`.) | ||||||
| 
 | 
 | ||||||
|  | * Remove the following functions from the C API. Call :c:func:`PyGC_Collect` | ||||||
|  |   explicitly to free all free lists. | ||||||
|  |   (Contributed by Victor Stinner in :issue:`40428`.) | ||||||
|  | 
 | ||||||
|  |   * ``PyAsyncGen_ClearFreeLists()`` | ||||||
|  |   * ``PyContext_ClearFreeList()`` | ||||||
|  |   * ``PyDict_ClearFreeList()`` | ||||||
|  |   * ``PyFloat_ClearFreeList()`` | ||||||
|  |   * ``PyFrame_ClearFreeList()`` | ||||||
|  |   * ``PyList_ClearFreeList()`` | ||||||
|  |   * ``PySet_ClearFreeList()`` | ||||||
|  |   * ``PyTuple_ClearFreeList()`` | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| Deprecated | Deprecated | ||||||
| ========== | ========== | ||||||
|  |  | ||||||
|  | @ -73,9 +73,6 @@ PyAPI_FUNC(int) PyContextVar_Reset(PyObject *var, PyObject *token); | ||||||
| PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void); | PyAPI_FUNC(PyObject *) _PyContext_NewHamtForTests(void); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(int) PyContext_ClearFreeList(void); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| #endif /* !Py_LIMITED_API */ | #endif /* !Py_LIMITED_API */ | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  |  | ||||||
|  | @ -62,8 +62,6 @@ PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *); | ||||||
| PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); | PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); | ||||||
| #define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) | #define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(int) PyDict_ClearFreeList(void); |  | ||||||
| 
 |  | ||||||
| /* Like PyDict_Merge, but override can be 0, 1 or 2.  If override is 0,
 | /* Like PyDict_Merge, but override can be 0, 1 or 2.  If override is 0,
 | ||||||
|    the first occurrence of a key wins, if override is 1, the last occurrence |    the first occurrence of a key wins, if override is 1, the last occurrence | ||||||
|    of a key wins, if override is 2, a KeyError with conflicting key as |    of a key wins, if override is 2, a KeyError with conflicting key as | ||||||
|  |  | ||||||
|  | @ -75,8 +75,6 @@ PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); | ||||||
| PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); | PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f); | ||||||
| PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); | PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(int) PyFrame_ClearFreeList(void); |  | ||||||
| 
 |  | ||||||
| PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); | PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
|  |  | ||||||
|  | @ -26,7 +26,6 @@ typedef struct { | ||||||
| } PyListObject; | } PyListObject; | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); | PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); | ||||||
| PyAPI_FUNC(int) PyList_ClearFreeList(void); |  | ||||||
| PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); | PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); | ||||||
| 
 | 
 | ||||||
| /* Macro, trading safety for speed */ | /* Macro, trading safety for speed */ | ||||||
|  |  | ||||||
|  | @ -100,9 +100,6 @@ PyAPI_FUNC(double) _PyFloat_Unpack2(const unsigned char *p, int le); | ||||||
| PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); | PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); | ||||||
| PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); | PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); | ||||||
| 
 | 
 | ||||||
| /* free list api */ |  | ||||||
| PyAPI_FUNC(int) PyFloat_ClearFreeList(void); |  | ||||||
| 
 |  | ||||||
| PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); | PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); | ||||||
| 
 | 
 | ||||||
| /* Format the object based on the format_spec, as defined in PEP 3101
 | /* Format the object based on the format_spec, as defined in PEP 3101
 | ||||||
|  |  | ||||||
|  | @ -91,8 +91,6 @@ PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *, | ||||||
| 
 | 
 | ||||||
| PyObject *_PyAsyncGenValueWrapperNew(PyObject *); | PyObject *_PyAsyncGenValueWrapperNew(PyObject *); | ||||||
| 
 | 
 | ||||||
| int PyAsyncGen_ClearFreeLists(void); |  | ||||||
| 
 |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #undef _PyGenObject_HEAD | #undef _PyGenObject_HEAD | ||||||
|  |  | ||||||
|  | @ -163,6 +163,16 @@ struct _gc_runtime_state { | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); | PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | // Functions to clear types free lists
 | ||||||
|  | extern void _PyFrame_ClearFreeList(void); | ||||||
|  | extern void _PyTuple_ClearFreeList(void); | ||||||
|  | extern void _PyFloat_ClearFreeList(void); | ||||||
|  | extern void _PyList_ClearFreeList(void); | ||||||
|  | extern void _PyDict_ClearFreeList(void); | ||||||
|  | extern void _PyAsyncGen_ClearFreeLists(void); | ||||||
|  | extern void _PyContext_ClearFreeList(void); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -70,7 +70,6 @@ PyAPI_DATA(PyObject *) _PySet_Dummy; | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); | PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); | ||||||
| PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); | PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); | ||||||
| PyAPI_FUNC(int) PySet_ClearFreeList(void); |  | ||||||
| 
 | 
 | ||||||
| #endif /* Section excluded by Py_LIMITED_API */ | #endif /* Section excluded by Py_LIMITED_API */ | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -34,8 +34,6 @@ PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); | ||||||
| PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); | PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); | ||||||
| PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); | PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(int) PyTuple_ClearFreeList(void); |  | ||||||
| 
 |  | ||||||
| #ifndef Py_LIMITED_API | #ifndef Py_LIMITED_API | ||||||
| #  define Py_CPYTHON_TUPLEOBJECT_H | #  define Py_CPYTHON_TUPLEOBJECT_H | ||||||
| #  include  "cpython/tupleobject.h" | #  include  "cpython/tupleobject.h" | ||||||
|  |  | ||||||
|  | @ -0,0 +1,11 @@ | ||||||
|  | Remove the following functions from the C API. Call :c:func:`PyGC_Collect` | ||||||
|  | explicitly to free all free lists. | ||||||
|  | 
 | ||||||
|  | * ``PyAsyncGen_ClearFreeLists()`` | ||||||
|  | * ``PyContext_ClearFreeList()`` | ||||||
|  | * ``PyDict_ClearFreeList()`` | ||||||
|  | * ``PyFloat_ClearFreeList()`` | ||||||
|  | * ``PyFrame_ClearFreeList()`` | ||||||
|  | * ``PyList_ClearFreeList()`` | ||||||
|  | * ``PySet_ClearFreeList()`` | ||||||
|  | * ``PyTuple_ClearFreeList()`` | ||||||
|  | @ -30,7 +30,6 @@ | ||||||
| #include "pycore_object.h" | #include "pycore_object.h" | ||||||
| #include "pycore_pyerrors.h" | #include "pycore_pyerrors.h" | ||||||
| #include "pycore_pystate.h"     // _PyThreadState_GET() | #include "pycore_pystate.h"     // _PyThreadState_GET() | ||||||
| #include "frameobject.h"        // PyFrame_ClearFreeList |  | ||||||
| #include "pydtrace.h" | #include "pydtrace.h" | ||||||
| #include "pytime.h"             // _PyTime_GetMonotonicClock() | #include "pytime.h"             // _PyTime_GetMonotonicClock() | ||||||
| 
 | 
 | ||||||
|  | @ -1026,14 +1025,13 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate, | ||||||
| static void | static void | ||||||
| clear_freelists(void) | clear_freelists(void) | ||||||
| { | { | ||||||
|     (void)PyFrame_ClearFreeList(); |     _PyFrame_ClearFreeList(); | ||||||
|     (void)PyTuple_ClearFreeList(); |     _PyTuple_ClearFreeList(); | ||||||
|     (void)PyFloat_ClearFreeList(); |     _PyFloat_ClearFreeList(); | ||||||
|     (void)PyList_ClearFreeList(); |     _PyList_ClearFreeList(); | ||||||
|     (void)PyDict_ClearFreeList(); |     _PyDict_ClearFreeList(); | ||||||
|     (void)PySet_ClearFreeList(); |     _PyAsyncGen_ClearFreeLists(); | ||||||
|     (void)PyAsyncGen_ClearFreeLists(); |     _PyContext_ClearFreeList(); | ||||||
|     (void)PyContext_ClearFreeList(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Show stats for objects in each generations
 | // Show stats for objects in each generations
 | ||||||
|  |  | ||||||
|  | @ -257,20 +257,17 @@ static int numfreekeys = 0; | ||||||
| 
 | 
 | ||||||
| #include "clinic/dictobject.c.h" | #include "clinic/dictobject.c.h" | ||||||
| 
 | 
 | ||||||
| int | void | ||||||
| PyDict_ClearFreeList(void) | _PyDict_ClearFreeList(void) | ||||||
| { | { | ||||||
|     PyDictObject *op; |  | ||||||
|     int ret = numfree + numfreekeys; |  | ||||||
|     while (numfree) { |     while (numfree) { | ||||||
|         op = free_list[--numfree]; |         PyDictObject *op = free_list[--numfree]; | ||||||
|         assert(PyDict_CheckExact(op)); |         assert(PyDict_CheckExact(op)); | ||||||
|         PyObject_GC_Del(op); |         PyObject_GC_Del(op); | ||||||
|     } |     } | ||||||
|     while (numfreekeys) { |     while (numfreekeys) { | ||||||
|         PyObject_FREE(keys_free_list[--numfreekeys]); |         PyObject_FREE(keys_free_list[--numfreekeys]); | ||||||
|     } |     } | ||||||
|     return ret; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Print summary info about the state of the optimized allocator */ | /* Print summary info about the state of the optimized allocator */ | ||||||
|  | @ -285,7 +282,7 @@ _PyDict_DebugMallocStats(FILE *out) | ||||||
| void | void | ||||||
| _PyDict_Fini(void) | _PyDict_Fini(void) | ||||||
| { | { | ||||||
|     PyDict_ClearFreeList(); |     _PyDict_ClearFreeList(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #define DK_SIZE(dk) ((dk)->dk_size) | #define DK_SIZE(dk) ((dk)->dk_size) | ||||||
|  |  | ||||||
|  | @ -1998,25 +1998,22 @@ _PyFloat_Init(void) | ||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | void | ||||||
| PyFloat_ClearFreeList(void) | _PyFloat_ClearFreeList(void) | ||||||
| { | { | ||||||
|     PyFloatObject *f = free_list, *next; |     PyFloatObject *f = free_list, *next; | ||||||
|     int i = numfree; |     for (; f; f = next) { | ||||||
|     while (f) { |  | ||||||
|         next = (PyFloatObject*) Py_TYPE(f); |         next = (PyFloatObject*) Py_TYPE(f); | ||||||
|         PyObject_FREE(f); |         PyObject_FREE(f); | ||||||
|         f = next; |  | ||||||
|     } |     } | ||||||
|     free_list = NULL; |     free_list = NULL; | ||||||
|     numfree = 0; |     numfree = 0; | ||||||
|     return i; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| _PyFloat_Fini(void) | _PyFloat_Fini(void) | ||||||
| { | { | ||||||
|     (void)PyFloat_ClearFreeList(); |     _PyFloat_ClearFreeList(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Print summary info about the state of the optimized allocator */ | /* Print summary info about the state of the optimized allocator */ | ||||||
|  |  | ||||||
|  | @ -1200,11 +1200,9 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Clear out the free list */ | /* Clear out the free list */ | ||||||
| int | void | ||||||
| PyFrame_ClearFreeList(void) | _PyFrame_ClearFreeList(void) | ||||||
| { | { | ||||||
|     int freelist_size = numfree; |  | ||||||
| 
 |  | ||||||
|     while (free_list != NULL) { |     while (free_list != NULL) { | ||||||
|         PyFrameObject *f = free_list; |         PyFrameObject *f = free_list; | ||||||
|         free_list = free_list->f_back; |         free_list = free_list->f_back; | ||||||
|  | @ -1212,13 +1210,12 @@ PyFrame_ClearFreeList(void) | ||||||
|         --numfree; |         --numfree; | ||||||
|     } |     } | ||||||
|     assert(numfree == 0); |     assert(numfree == 0); | ||||||
|     return freelist_size; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| _PyFrame_Fini(void) | _PyFrame_Fini(void) | ||||||
| { | { | ||||||
|     (void)PyFrame_ClearFreeList(); |     _PyFrame_ClearFreeList(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Print summary info about the state of the optimized allocator */ | /* Print summary info about the state of the optimized allocator */ | ||||||
|  |  | ||||||
|  | @ -1429,11 +1429,9 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| int | void | ||||||
| PyAsyncGen_ClearFreeLists(void) | _PyAsyncGen_ClearFreeLists(void) | ||||||
| { | { | ||||||
|     int ret = ag_value_freelist_free + ag_asend_freelist_free; |  | ||||||
| 
 |  | ||||||
|     while (ag_value_freelist_free) { |     while (ag_value_freelist_free) { | ||||||
|         _PyAsyncGenWrappedValue *o; |         _PyAsyncGenWrappedValue *o; | ||||||
|         o = ag_value_freelist[--ag_value_freelist_free]; |         o = ag_value_freelist[--ag_value_freelist_free]; | ||||||
|  | @ -1447,14 +1445,12 @@ PyAsyncGen_ClearFreeLists(void) | ||||||
|         assert(Py_IS_TYPE(o, &_PyAsyncGenASend_Type)); |         assert(Py_IS_TYPE(o, &_PyAsyncGenASend_Type)); | ||||||
|         PyObject_GC_Del(o); |         PyObject_GC_Del(o); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     return ret; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| _PyAsyncGen_Fini(void) | _PyAsyncGen_Fini(void) | ||||||
| { | { | ||||||
|     PyAsyncGen_ClearFreeLists(); |     _PyAsyncGen_ClearFreeLists(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -103,23 +103,20 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size) | ||||||
| static PyListObject *free_list[PyList_MAXFREELIST]; | static PyListObject *free_list[PyList_MAXFREELIST]; | ||||||
| static int numfree = 0; | static int numfree = 0; | ||||||
| 
 | 
 | ||||||
| int | void | ||||||
| PyList_ClearFreeList(void) | _PyList_ClearFreeList(void) | ||||||
| { | { | ||||||
|     PyListObject *op; |  | ||||||
|     int ret = numfree; |  | ||||||
|     while (numfree) { |     while (numfree) { | ||||||
|         op = free_list[--numfree]; |         PyListObject *op = free_list[--numfree]; | ||||||
|         assert(PyList_CheckExact(op)); |         assert(PyList_CheckExact(op)); | ||||||
|         PyObject_GC_Del(op); |         PyObject_GC_Del(op); | ||||||
|     } |     } | ||||||
|     return ret; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| _PyList_Fini(void) | _PyList_Fini(void) | ||||||
| { | { | ||||||
|     PyList_ClearFreeList(); |     _PyList_ClearFreeList(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Print summary info about the state of the optimized allocator */ | /* Print summary info about the state of the optimized allocator */ | ||||||
|  |  | ||||||
|  | @ -2384,12 +2384,6 @@ PySet_Add(PyObject *anyset, PyObject *key) | ||||||
|     return set_add_key((PySetObject *)anyset, key); |     return set_add_key((PySetObject *)anyset, key); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int |  | ||||||
| PySet_ClearFreeList(void) |  | ||||||
| { |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void | void | ||||||
| _PySet_Fini(void) | _PySet_Fini(void) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -955,26 +955,22 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int | void | ||||||
| PyTuple_ClearFreeList(void) | _PyTuple_ClearFreeList(void) | ||||||
| { | { | ||||||
|     int freelist_size = 0; |  | ||||||
| #if PyTuple_MAXSAVESIZE > 0 | #if PyTuple_MAXSAVESIZE > 0 | ||||||
|     int i; |     for (Py_ssize_t i = 1; i < PyTuple_MAXSAVESIZE; i++) { | ||||||
|     for (i = 1; i < PyTuple_MAXSAVESIZE; i++) { |         PyTupleObject *p = free_list[i]; | ||||||
|         PyTupleObject *p, *q; |  | ||||||
|         p = free_list[i]; |  | ||||||
|         freelist_size += numfree[i]; |  | ||||||
|         free_list[i] = NULL; |         free_list[i] = NULL; | ||||||
|         numfree[i] = 0; |         numfree[i] = 0; | ||||||
|         while (p) { |         while (p) { | ||||||
|             q = p; |             PyTupleObject *q = p; | ||||||
|             p = (PyTupleObject *)(p->ob_item[0]); |             p = (PyTupleObject *)(p->ob_item[0]); | ||||||
|             PyObject_GC_Del(q); |             PyObject_GC_Del(q); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |     // the empty tuple singleton is only cleared by _PyTuple_Fini()
 | ||||||
| #endif | #endif | ||||||
|     return freelist_size; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
|  | @ -985,7 +981,7 @@ _PyTuple_Fini(void) | ||||||
|      * rely on the fact that an empty tuple is a singleton. */ |      * rely on the fact that an empty tuple is a singleton. */ | ||||||
|     Py_CLEAR(free_list[0]); |     Py_CLEAR(free_list[0]); | ||||||
| 
 | 
 | ||||||
|     (void)PyTuple_ClearFreeList(); |     _PyTuple_ClearFreeList(); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -35,7 +35,6 @@ EXPORTS | ||||||
|   PyBytes_Size=python39.PyBytes_Size |   PyBytes_Size=python39.PyBytes_Size | ||||||
|   PyBytes_Type=python39.PyBytes_Type DATA |   PyBytes_Type=python39.PyBytes_Type DATA | ||||||
|   PyCFunction_Call=python39.PyCFunction_Call |   PyCFunction_Call=python39.PyCFunction_Call | ||||||
|   PyCFunction_ClearFreeList=python39.PyCFunction_ClearFreeList |  | ||||||
|   PyCFunction_GetFlags=python39.PyCFunction_GetFlags |   PyCFunction_GetFlags=python39.PyCFunction_GetFlags | ||||||
|   PyCFunction_GetFunction=python39.PyCFunction_GetFunction |   PyCFunction_GetFunction=python39.PyCFunction_GetFunction | ||||||
|   PyCFunction_GetSelf=python39.PyCFunction_GetSelf |   PyCFunction_GetSelf=python39.PyCFunction_GetSelf | ||||||
|  | @ -584,7 +583,6 @@ EXPORTS | ||||||
|   PyTraceBack_Print=python39.PyTraceBack_Print |   PyTraceBack_Print=python39.PyTraceBack_Print | ||||||
|   PyTraceBack_Type=python39.PyTraceBack_Type DATA |   PyTraceBack_Type=python39.PyTraceBack_Type DATA | ||||||
|   PyTupleIter_Type=python39.PyTupleIter_Type DATA |   PyTupleIter_Type=python39.PyTupleIter_Type DATA | ||||||
|   PyTuple_ClearFreeList=python39.PyTuple_ClearFreeList |  | ||||||
|   PyTuple_GetItem=python39.PyTuple_GetItem |   PyTuple_GetItem=python39.PyTuple_GetItem | ||||||
|   PyTuple_GetSlice=python39.PyTuple_GetSlice |   PyTuple_GetSlice=python39.PyTuple_GetSlice | ||||||
|   PyTuple_New=python39.PyTuple_New |   PyTuple_New=python39.PyTuple_New | ||||||
|  |  | ||||||
|  | @ -1270,18 +1270,15 @@ get_token_missing(void) | ||||||
| ///////////////////////////
 | ///////////////////////////
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| int | void | ||||||
| PyContext_ClearFreeList(void) | _PyContext_ClearFreeList(void) | ||||||
| { | { | ||||||
|     int size = ctx_freelist_len; |     for (; ctx_freelist_len; ctx_freelist_len--) { | ||||||
|     while (ctx_freelist_len) { |  | ||||||
|         PyContext *ctx = ctx_freelist; |         PyContext *ctx = ctx_freelist; | ||||||
|         ctx_freelist = (PyContext *)ctx->ctx_weakreflist; |         ctx_freelist = (PyContext *)ctx->ctx_weakreflist; | ||||||
|         ctx->ctx_weakreflist = NULL; |         ctx->ctx_weakreflist = NULL; | ||||||
|         PyObject_GC_Del(ctx); |         PyObject_GC_Del(ctx); | ||||||
|         ctx_freelist_len--; |  | ||||||
|     } |     } | ||||||
|     return size; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -1289,8 +1286,8 @@ void | ||||||
| _PyContext_Fini(void) | _PyContext_Fini(void) | ||||||
| { | { | ||||||
|     Py_CLEAR(_token_missing); |     Py_CLEAR(_token_missing); | ||||||
|     (void)PyContext_ClearFreeList(); |     _PyContext_ClearFreeList(); | ||||||
|     (void)_PyHamt_Fini(); |     _PyHamt_Fini(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner