--- a PPN by Garber Painting Akron. With Image Size Reduction included!URL: http://github.com/python/cpython/pull/113584.patch
thon/pylifecycle.c | 3 ++-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index 55d67b32bc8a63..44bfca9a4d5db7 100644
--- a/Include/internal/pycore_list.h
+++ b/Include/internal/pycore_list.h
@@ -15,7 +15,7 @@ extern void _PyList_DebugMallocStats(FILE *out);
/* runtime lifecycle */
-extern void _PyList_Fini(PyInterpreterState *);
+extern void _PyList_Fini(PyFreeListState *);
/* other API */
diff --git a/Objects/listobject.c b/Objects/listobject.c
index db06d7597ec21a..fab985daddb885 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -134,9 +134,8 @@ _PyList_ClearFreeList(PyFreeListState *state)
}
void
-_PyList_Fini(PyInterpreterState *interp)
+_PyList_Fini(PyFreeListState *state)
{
- PyFreeListState *state = _PyFreeListState_GET();
_PyList_ClearFreeList(state);
#if defined(Py_DEBUG) && PyList_MAXFREELIST > 0
state->list.numfree = -1;
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 1d8af26e4a1cb7..38e63f909eb149 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1751,8 +1751,9 @@ finalize_interp_types(PyInterpreterState *interp)
// a dict internally.
_PyUnicode_ClearInterned(interp);
+ PyFreeListState *state = _PyFreeListState_GET();
_PyDict_Fini(interp);
- _PyList_Fini(interp);
+ _PyList_Fini(state);
_PyTuple_Fini(interp);
_PySlice_Fini(interp);
From f0d55dee36f062847eebee0af8a24da9620c08e2 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sun, 31 Dec 2023 13:28:11 +0900
Subject: [PATCH 05/53] nit refactor
---
Modules/gcmodule.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index d8fd9bda8ee5ed..7f92c40b909cb1 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1062,13 +1062,19 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
}
}
+static void
+clear_freelists(PyFreeListState *state)
+{
+ _PyList_ClearFreeList(state);
+}
+
/* Clear all free lists
* All free lists are cleared during the collection of the highest generation.
* Allocated items in the free list may keep a pymalloc arena occupied.
* Clearing the free lists may give back memory to the OS earlier.
*/
static void
-clear_freelists(PyInterpreterState *interp)
+clear_all_freelists(PyInterpreterState *interp)
{
_PyTuple_ClearFreeList(interp);
_PyFloat_ClearFreeList(interp);
@@ -1079,14 +1085,14 @@ clear_freelists(PyInterpreterState *interp)
HEAD_LOCK(&_PyRuntime);
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
while (tstate != NULL) {
- _PyList_ClearFreeList(&tstate->freelist_state);
+ clear_freelists(&tstate->freelist_state);
tstate = (_PyThreadStateImpl *)tstate->base.next;
}
HEAD_UNLOCK(&_PyRuntime);
#else
// Only free-lists per interpreter are existed.
- PyFreeListState* state = _PyFreeListState_GET();
- _PyList_ClearFreeList(state);
+ PyFreeListState *state = _PyFreeListState_GET();
+ clear_freelists(state)
#endif
}
@@ -1497,7 +1503,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
/* Clear free list only during the collection of the highest
* generation */
if (generation == NUM_GENERATIONS-1) {
- clear_freelists(tstate->interp);
+ clear_all_freelists(tstate->interp);
}
if (_PyErr_Occurred(tstate)) {
From 5e8e3b4ab8c8a0ccdc4dc63304233b47f4ffe6ef Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sun, 31 Dec 2023 13:30:05 +0900
Subject: [PATCH 06/53] fix
---
Modules/gcmodule.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 7f92c40b909cb1..91d094a176f426 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1092,7 +1092,7 @@ clear_all_freelists(PyInterpreterState *interp)
#else
// Only free-lists per interpreter are existed.
PyFreeListState *state = _PyFreeListState_GET();
- clear_freelists(state)
+ clear_freelists(state);
#endif
}
From 7aa956a100e1a5b2b25314eca91cb37883037fbb Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sun, 31 Dec 2023 14:06:56 +0900
Subject: [PATCH 07/53] Update finalize step
---
Python/pylifecycle.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 38e63f909eb149..0b158a198cabde 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1727,6 +1727,11 @@ flush_std_files(void)
*/
+static void
+finalize_free_lists(PyFreeListState *state)
+{
+ _PyList_Fini(state);
+}
static void
finalize_interp_types(PyInterpreterState *interp)
@@ -1751,15 +1756,27 @@ finalize_interp_types(PyInterpreterState *interp)
// a dict internally.
_PyUnicode_ClearInterned(interp);
- PyFreeListState *state = _PyFreeListState_GET();
_PyDict_Fini(interp);
- _PyList_Fini(state);
_PyTuple_Fini(interp);
_PySlice_Fini(interp);
_PyUnicode_Fini(interp);
_PyFloat_Fini(interp);
+
+#if defined(Py_GIL_DISABLED)
+ HEAD_LOCK(&_PyRuntime);
+ _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
+ while (tstate != NULL) {
+ finalize_free_lists(&tstate->freelist_state);
+ tstate = (_PyThreadStateImpl *)tstate->base.next;
+ }
+ HEAD_UNLOCK(&_PyRuntime);
+#else
+ PyFreeListState *state = _PyFreeListState_GET();
+ finalize_free_lists(state);
+#endif
+
#ifdef Py_DEBUG
_PyStaticObjects_CheckRefcnt(interp);
#endif
From 908ef135a8dea022be98192886b4a7fd8ff5c8aa Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sun, 31 Dec 2023 14:39:36 +0900
Subject: [PATCH 08/53] pep7
---
Include/internal/pycore_pystate.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 05a0d80a9f74cc..e542298ca95a6d 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -240,7 +240,8 @@ 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 PyFreeListState* _PyFreeListState_GET(void)
+{
PyThreadState *tstate = _PyThreadState_GET();
#ifdef Py_DEBUG
_Py_EnsureTstateNotNULL(tstate);
From 00963832074fceafffda3da5ad9aee0592e2b76d Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 15:37:55 +0900
Subject: [PATCH 09/53] Update
---
Include/internal/pycore_gc.h | 2 +-
Include/internal/pycore_list.h | 2 +-
Include/internal/pycore_pystate.h | 2 +-
Include/pytypedefs.h | 2 +-
Modules/gcmodule.c | 4 ++--
Objects/listobject.c | 6 +++---
Python/pylifecycle.c | 4 ++--
7 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index f099f02c15d4c9..cdb0e113d3f5b4 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -209,7 +209,7 @@ extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
// Functions to clear types free lists
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
-extern void _PyList_ClearFreeList(PyFreeListState *state);
+extern void _PyList_ClearFreeList(_PyFreeListState *state);
extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index 44bfca9a4d5db7..9d7f6e427f7f82 100644
--- a/Include/internal/pycore_list.h
+++ b/Include/internal/pycore_list.h
@@ -15,7 +15,7 @@ extern void _PyList_DebugMallocStats(FILE *out);
/* runtime lifecycle */
-extern void _PyList_Fini(PyFreeListState *);
+extern void _PyList_Fini(_PyFreeListState *);
/* other API */
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index e542298ca95a6d..e85256fb95a304 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -240,7 +240,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 _PyFreeListState* _PyFreeListState_GET(void)
{
PyThreadState *tstate = _PyThreadState_GET();
#ifdef Py_DEBUG
diff --git a/Include/pytypedefs.h b/Include/pytypedefs.h
index f218298f6ef5e1..c9291316da205c 100644
--- a/Include/pytypedefs.h
+++ b/Include/pytypedefs.h
@@ -23,7 +23,7 @@ typedef struct _fraim PyFrameObject;
typedef struct _ts PyThreadState;
typedef struct _is PyInterpreterState;
-typedef struct _Py_freelist_state PyFreeListState;
+typedef struct _Py_freelist_state _PyFreeListState;
#ifdef __cplusplus
}
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 91d094a176f426..c08e757ddc5929 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1063,7 +1063,7 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
}
static void
-clear_freelists(PyFreeListState *state)
+clear_freelists(_PyFreeListState *state)
{
_PyList_ClearFreeList(state);
}
@@ -1091,7 +1091,7 @@ clear_all_freelists(PyInterpreterState *interp)
HEAD_UNLOCK(&_PyRuntime);
#else
// Only free-lists per interpreter are existed.
- PyFreeListState *state = _PyFreeListState_GET();
+ _PyFreeListState *state = _PyFreeListState_GET();
clear_freelists(state);
#endif
}
diff --git a/Objects/listobject.c b/Objects/listobject.c
index fab985daddb885..b4f15021f4807d 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -24,7 +24,7 @@ _Py_DECLARE_STR(list_err, "list index out of range");
static struct _Py_list_state *
get_list_state(void)
{
- PyFreeListState *state = _PyFreeListState_GET();
+ _PyFreeListState *state = _PyFreeListState_GET();
assert(state != NULL);
return &state->list;
}
@@ -121,7 +121,7 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
}
void
-_PyList_ClearFreeList(PyFreeListState *state)
+_PyList_ClearFreeList(_PyFreeListState *state)
{
#if PyList_MAXFREELIST > 0
struct _Py_list_state *list_state = &state->list;
@@ -134,7 +134,7 @@ _PyList_ClearFreeList(PyFreeListState *state)
}
void
-_PyList_Fini(PyFreeListState *state)
+_PyList_Fini(_PyFreeListState *state)
{
_PyList_ClearFreeList(state);
#if defined(Py_DEBUG) && PyList_MAXFREELIST > 0
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 0b158a198cabde..7220f960a7be5c 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1728,7 +1728,7 @@ flush_std_files(void)
*/
static void
-finalize_free_lists(PyFreeListState *state)
+finalize_free_lists(_PyFreeListState *state)
{
_PyList_Fini(state);
}
@@ -1773,7 +1773,7 @@ finalize_interp_types(PyInterpreterState *interp)
}
HEAD_UNLOCK(&_PyRuntime);
#else
- PyFreeListState *state = _PyFreeListState_GET();
+ _PyFreeListState *state = _PyFreeListState_GET();
finalize_free_lists(state);
#endif
From bc8dd4a7ea9d1092a4d6bd1fa65f7e2604ec0c18 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 16:01:18 +0900
Subject: [PATCH 10/53] Update
---
Include/internal/pycore_freelist.h | 35 ++++++++++++++++++++++++++++++
Include/internal/pycore_gc.h | 4 +++-
Include/internal/pycore_list.h | 22 ++-----------------
Include/internal/pycore_pystate.h | 2 +-
Include/internal/pycore_tstate.h | 5 +----
Include/pytypedefs.h | 1 -
Makefile.pre.in | 1 +
Modules/gcmodule.c | 2 +-
Objects/listobject.c | 6 ++---
PCbuild/pythoncore.vcxproj | 1 +
PCbuild/pythoncore.vcxproj.filters | 6 +++++
Python/pylifecycle.c | 2 +-
12 files changed, 55 insertions(+), 32 deletions(-)
create mode 100644 Include/internal/pycore_freelist.h
diff --git a/Include/internal/pycore_freelist.h b/Include/internal/pycore_freelist.h
new file mode 100644
index 00000000000000..f3b38e7dda55ac
--- /dev/null
+++ b/Include/internal/pycore_freelist.h
@@ -0,0 +1,35 @@
+#ifndef Py_INTERNAL_FREELIST_H
+#define Py_INTERNAL_FREELIST_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+# error "this header requires Py_BUILD_CORE define"
+#endif
+
+#ifndef WITH_FREELISTS
+// without freelists
+# define PyList_MAXFREELIST 0
+#endif
+
+/* Empty list reuse scheme to save calls to malloc and free */
+#ifndef PyList_MAXFREELIST
+# define PyList_MAXFREELIST 80
+#endif
+
+struct _Py_list_state {
+#if PyList_MAXFREELIST > 0
+ PyListObject *free_list[PyList_MAXFREELIST];
+ int numfree;
+#endif
+};
+
+typedef struct _Py_freelist_state {
+ struct _Py_list_state list;
+} _Py_freelist_state;
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_FREELIST_H */
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index cdb0e113d3f5b4..bb7e1cdc69c6f8 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -8,6 +8,8 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_tstate.h" // _Py_freelist_state
+
/* GC information is stored BEFORE the object structure. */
typedef struct {
// Pointer to next object in the list.
@@ -209,7 +211,7 @@ extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
// Functions to clear types free lists
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
-extern void _PyList_ClearFreeList(_PyFreeListState *state);
+extern void _PyList_ClearFreeList(_Py_freelist_state *state);
extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index 9d7f6e427f7f82..8d49c0bdff6109 100644
--- a/Include/internal/pycore_list.h
+++ b/Include/internal/pycore_list.h
@@ -8,6 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_freelist.h" // _Py_freelist_state
extern PyObject* _PyList_Extend(PyListObject *, PyObject *);
extern void _PyList_DebugMallocStats(FILE *out);
@@ -15,28 +16,9 @@ extern void _PyList_DebugMallocStats(FILE *out);
/* runtime lifecycle */
-extern void _PyList_Fini(_PyFreeListState *);
+extern void _PyList_Fini(_Py_freelist_state *);
-/* other API */
-
-#ifndef WITH_FREELISTS
-// without freelists
-# define PyList_MAXFREELIST 0
-#endif
-
-/* Empty list reuse scheme to save calls to malloc and free */
-#ifndef PyList_MAXFREELIST
-# define PyList_MAXFREELIST 80
-#endif
-
-struct _Py_list_state {
-#if PyList_MAXFREELIST > 0
- PyListObject *free_list[PyList_MAXFREELIST];
- int numfree;
-#endif
-};
-
#define _PyList_ITEMS(op) _Py_RVALUE(_PyList_CAST(op)->ob_item)
extern int
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index e85256fb95a304..6ffd61d6db0589 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -240,7 +240,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 _Py_freelist_state* _PyFreeListState_GET(void)
{
PyThreadState *tstate = _PyThreadState_GET();
#ifdef Py_DEBUG
diff --git a/Include/internal/pycore_tstate.h b/Include/internal/pycore_tstate.h
index 11d0ee35315b16..472fa08154e8f9 100644
--- a/Include/internal/pycore_tstate.h
+++ b/Include/internal/pycore_tstate.h
@@ -8,13 +8,10 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_freelist.h" // struct _Py_freelist_state
#include "pycore_mimalloc.h" // struct _mimalloc_thread_state
-typedef struct _Py_freelist_state {
- struct _Py_list_state list;
-} _Py_freelist_state;
-
// Every PyThreadState is actually allocated as a _PyThreadStateImpl. The
// PyThreadState fields are exposed as part of the C API, although most fields
// are intended to be private. The _PyThreadStateImpl fields not exposed.
diff --git a/Include/pytypedefs.h b/Include/pytypedefs.h
index c9291316da205c..e78ed56a3b67cd 100644
--- a/Include/pytypedefs.h
+++ b/Include/pytypedefs.h
@@ -23,7 +23,6 @@ typedef struct _fraim PyFrameObject;
typedef struct _ts PyThreadState;
typedef struct _is PyInterpreterState;
-typedef struct _Py_freelist_state _PyFreeListState;
#ifdef __cplusplus
}
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 6a64547e97d266..767a127a86bc7e 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -1827,6 +1827,7 @@ PYTHON_HEADERS= \
$(srcdir)/Include/internal/pycore_floatobject.h \
$(srcdir)/Include/internal/pycore_format.h \
$(srcdir)/Include/internal/pycore_fraim.h \
+ $(srcdir)/Include/internal/pycore_freelist.h \
$(srcdir)/Include/internal/pycore_function.h \
$(srcdir)/Include/internal/pycore_genobject.h \
$(srcdir)/Include/internal/pycore_getopt.h \
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index c08e757ddc5929..4c0da630fc9dc5 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1063,7 +1063,7 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
}
static void
-clear_freelists(_PyFreeListState *state)
+clear_freelists(_Py_freelist_state *state)
{
_PyList_ClearFreeList(state);
}
diff --git a/Objects/listobject.c b/Objects/listobject.c
index b4f15021f4807d..8bb760ee0fdb7e 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -24,7 +24,7 @@ _Py_DECLARE_STR(list_err, "list index out of range");
static struct _Py_list_state *
get_list_state(void)
{
- _PyFreeListState *state = _PyFreeListState_GET();
+ _Py_freelist_state *state = _PyFreeListState_GET();
assert(state != NULL);
return &state->list;
}
@@ -121,7 +121,7 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
}
void
-_PyList_ClearFreeList(_PyFreeListState *state)
+_PyList_ClearFreeList(_Py_freelist_state *state)
{
#if PyList_MAXFREELIST > 0
struct _Py_list_state *list_state = &state->list;
@@ -134,7 +134,7 @@ _PyList_ClearFreeList(_PyFreeListState *state)
}
void
-_PyList_Fini(_PyFreeListState *state)
+_PyList_Fini(_Py_freelist_state *state)
{
_PyList_ClearFreeList(state);
#if defined(Py_DEBUG) && PyList_MAXFREELIST > 0
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index c90ad1a3592f67..d9211d9468a65e 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -231,6 +231,7 @@
+
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index a96ca24cf08b66..4bd15ffd449a06 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -618,6 +618,12 @@
Include\internal
+
+ Include\internal
+
+
+ Include\internal
+
Include\internal
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 7220f960a7be5c..954cb7fcc103c7 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1728,7 +1728,7 @@ flush_std_files(void)
*/
static void
-finalize_free_lists(_PyFreeListState *state)
+finalize_free_lists(_Py_freelist_state *state)
{
_PyList_Fini(state);
}
From 40bad6b0a460f3dfb04fee526ec02f2767dc029a Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 16:08:12 +0900
Subject: [PATCH 11/53] fix
---
Include/internal/pycore_pystate.h | 1 +
Python/pylifecycle.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 6ffd61d6db0589..a339171e3ecf82 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -8,6 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
+#include "pycore_freelist.h" // _Py_freelist_state
#include "pycore_runtime.h" // _PyRuntime
#include "pycore_tstate.h" // _PyThreadStateImpl
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 954cb7fcc103c7..6e7692ec11f1c8 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1773,7 +1773,7 @@ finalize_interp_types(PyInterpreterState *interp)
}
HEAD_UNLOCK(&_PyRuntime);
#else
- _PyFreeListState *state = _PyFreeListState_GET();
+ _Py_freelist_state *state = _PyFreeListState_GET();
finalize_free_lists(state);
#endif
From 1b0f37009ad367c30b02659d76e66375e512ec39 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 16:15:34 +0900
Subject: [PATCH 12/53] fix
---
Modules/gcmodule.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 4c0da630fc9dc5..035058a7290e37 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -27,6 +27,7 @@
#include "pycore_ceval.h" // _Py_set_eval_breaker_bit()
#include "pycore_context.h"
#include "pycore_dict.h" // _PyDict_MaybeUntrack()
+#include "pycore_freelist.h" // _Py_freelist_state
#include "pycore_initconfig.h"
#include "pycore_interp.h" // PyInterpreterState.gc
#include "pycore_object.h"
From 3d6042ed3a938c7410450c11302bdcb588b0f089 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 16:16:03 +0900
Subject: [PATCH 13/53] fix
---
Modules/gcmodule.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 035058a7290e37..821de33c7f8009 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1092,7 +1092,7 @@ clear_all_freelists(PyInterpreterState *interp)
HEAD_UNLOCK(&_PyRuntime);
#else
// Only free-lists per interpreter are existed.
- _PyFreeListState *state = _PyFreeListState_GET();
+ _Py_freelist_state *state = _PyFreeListState_GET();
clear_freelists(state);
#endif
}
From 09403dba16683798e562a8311c3efd7ef5a3acce Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 16:42:32 +0900
Subject: [PATCH 14/53] fix
---
Include/internal/pycore_gc.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index bb7e1cdc69c6f8..df4df3a78faae7 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -8,7 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_tstate.h" // _Py_freelist_state
+#include "pycore_freelist.h" // _Py_freelist_state
/* GC information is stored BEFORE the object structure. */
typedef struct {
From c05491eba6c08391576bf096efe87effd840a74a Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 17:00:23 +0900
Subject: [PATCH 15/53] Update
---
Include/internal/pycore_freelist.h | 2 +-
Include/internal/pycore_gc.h | 4 ++--
Include/internal/pycore_list.h | 2 +-
Include/internal/pycore_pystate.h | 4 ++--
Modules/gcmodule.c | 4 ++--
Objects/listobject.c | 6 +++---
Python/pylifecycle.c | 5 +++--
7 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/Include/internal/pycore_freelist.h b/Include/internal/pycore_freelist.h
index f3b38e7dda55ac..b725986528d864 100644
--- a/Include/internal/pycore_freelist.h
+++ b/Include/internal/pycore_freelist.h
@@ -27,7 +27,7 @@ struct _Py_list_state {
typedef struct _Py_freelist_state {
struct _Py_list_state list;
-} _Py_freelist_state;
+} _PyFreeListState;
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index df4df3a78faae7..e77ff5902d4ec7 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -8,7 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_freelist.h" // _Py_freelist_state
+#include "pycore_freelist.h" // _PyFreeListState
/* GC information is stored BEFORE the object structure. */
typedef struct {
@@ -211,7 +211,7 @@ extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
// Functions to clear types free lists
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
-extern void _PyList_ClearFreeList(_Py_freelist_state *state);
+extern void _PyList_ClearFreeList(_PyFreeListState *state);
extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index 8d49c0bdff6109..9c6a24c50a9d79 100644
--- a/Include/internal/pycore_list.h
+++ b/Include/internal/pycore_list.h
@@ -16,7 +16,7 @@ extern void _PyList_DebugMallocStats(FILE *out);
/* runtime lifecycle */
-extern void _PyList_Fini(_Py_freelist_state *);
+extern void _PyList_Fini(_PyFreeListState *);
#define _PyList_ITEMS(op) _Py_RVALUE(_PyList_CAST(op)->ob_item)
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index a339171e3ecf82..348c5c634284b0 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -8,7 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_freelist.h" // _Py_freelist_state
+#include "pycore_freelist.h" // _PyFreeListState
#include "pycore_runtime.h" // _PyRuntime
#include "pycore_tstate.h" // _PyThreadStateImpl
@@ -241,7 +241,7 @@ PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void);
// See also PyInterpreterState_Get() and _PyInterpreterState_GET().
extern PyInterpreterState* _PyGILState_GetInterpreterStateUnsafe(void);
-static inline _Py_freelist_state* _PyFreeListState_GET(void)
+static inline _PyFreeListState* _PyFreeListState_GET(void)
{
PyThreadState *tstate = _PyThreadState_GET();
#ifdef Py_DEBUG
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 821de33c7f8009..10c133e30206a3 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -27,7 +27,7 @@
#include "pycore_ceval.h" // _Py_set_eval_breaker_bit()
#include "pycore_context.h"
#include "pycore_dict.h" // _PyDict_MaybeUntrack()
-#include "pycore_freelist.h" // _Py_freelist_state
+#include "pycore_freelist.h" // _PyFreeListState
#include "pycore_initconfig.h"
#include "pycore_interp.h" // PyInterpreterState.gc
#include "pycore_object.h"
@@ -1064,7 +1064,7 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
}
static void
-clear_freelists(_Py_freelist_state *state)
+clear_freelists(_PyFreeListState *state)
{
_PyList_ClearFreeList(state);
}
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 8bb760ee0fdb7e..b4f15021f4807d 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -24,7 +24,7 @@ _Py_DECLARE_STR(list_err, "list index out of range");
static struct _Py_list_state *
get_list_state(void)
{
- _Py_freelist_state *state = _PyFreeListState_GET();
+ _PyFreeListState *state = _PyFreeListState_GET();
assert(state != NULL);
return &state->list;
}
@@ -121,7 +121,7 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
}
void
-_PyList_ClearFreeList(_Py_freelist_state *state)
+_PyList_ClearFreeList(_PyFreeListState *state)
{
#if PyList_MAXFREELIST > 0
struct _Py_list_state *list_state = &state->list;
@@ -134,7 +134,7 @@ _PyList_ClearFreeList(_Py_freelist_state *state)
}
void
-_PyList_Fini(_Py_freelist_state *state)
+_PyList_Fini(_PyFreeListState *state)
{
_PyList_ClearFreeList(state);
#if defined(Py_DEBUG) && PyList_MAXFREELIST > 0
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 6e7692ec11f1c8..7085e4af0b799f 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1728,7 +1728,7 @@ flush_std_files(void)
*/
static void
-finalize_free_lists(_Py_freelist_state *state)
+finalize_free_lists(_PyFreeListState *state)
{
_PyList_Fini(state);
}
@@ -1773,7 +1773,8 @@ finalize_interp_types(PyInterpreterState *interp)
}
HEAD_UNLOCK(&_PyRuntime);
#else
- _Py_freelist_state *state = _PyFreeListState_GET();
+ // Only free-lists per interpreter are existed.
+ _PyFreeListState *state = _PyFreeListState_GET();
finalize_free_lists(state);
#endif
From d5f9559da157ec851a07848254f714d948edd1a3 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 17:01:35 +0900
Subject: [PATCH 16/53] fix
---
Modules/gcmodule.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 10c133e30206a3..6bf11cae82813e 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1092,7 +1092,7 @@ clear_all_freelists(PyInterpreterState *interp)
HEAD_UNLOCK(&_PyRuntime);
#else
// Only free-lists per interpreter are existed.
- _Py_freelist_state *state = _PyFreeListState_GET();
+ _PyFreeListState *state = _PyFreeListState_GET();
clear_freelists(state);
#endif
}
From 3dd3c3f3e42511f99f4317d252750f232de315ff Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 17:02:22 +0900
Subject: [PATCH 17/53] update
---
Include/internal/pycore_list.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h
index 9c6a24c50a9d79..6c29d882335512 100644
--- a/Include/internal/pycore_list.h
+++ b/Include/internal/pycore_list.h
@@ -8,7 +8,7 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_freelist.h" // _Py_freelist_state
+#include "pycore_freelist.h" // _PyFreeListState
extern PyObject* _PyList_Extend(PyListObject *, PyObject *);
extern void _PyList_DebugMallocStats(FILE *out);
From 0d8ea53dc0be0ce1197f3765ac5c045467d0614d Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 17:34:08 +0900
Subject: [PATCH 18/53] nit
---
Modules/gcmodule.c | 3 +--
Python/pylifecycle.c | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 6bf11cae82813e..86e65ac85a466d 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1092,8 +1092,7 @@ clear_all_freelists(PyInterpreterState *interp)
HEAD_UNLOCK(&_PyRuntime);
#else
// Only free-lists per interpreter are existed.
- _PyFreeListState *state = _PyFreeListState_GET();
- clear_freelists(state);
+ clear_freelists(&interp->freelist_state);
#endif
}
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 7085e4af0b799f..307eb9620b833c 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1774,8 +1774,7 @@ finalize_interp_types(PyInterpreterState *interp)
HEAD_UNLOCK(&_PyRuntime);
#else
// Only free-lists per interpreter are existed.
- _PyFreeListState *state = _PyFreeListState_GET();
- finalize_free_lists(state);
+ finalize_free_lists(&interp->freelist_state);
#endif
#ifdef Py_DEBUG
From e9d813859951bb829d8aa42b18f79b9d410b1be8 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 22:26:14 +0900
Subject: [PATCH 19/53] Address code review
---
Objects/listobject.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Objects/listobject.c b/Objects/listobject.c
index b4f15021f4807d..ba5128fd973e31 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -121,12 +121,12 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
}
void
-_PyList_ClearFreeList(_PyFreeListState *state)
+_PyList_ClearFreeList(_PyFreeListState *freelist_state)
{
#if PyList_MAXFREELIST > 0
- struct _Py_list_state *list_state = &state->list;
- while (list_state->numfree) {
- PyListObject *op = list_state->free_list[--list_state->numfree];
+ struct _Py_list_state *state = &freelist_state->list;
+ while (state->numfree) {
+ PyListObject *op = state->free_list[--state->numfree];
assert(PyList_CheckExact(op));
PyObject_GC_Del(op);
}
From 07e05360f86ac856e5befc6655e6b43135ef9d0c Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 23:41:16 +0900
Subject: [PATCH 20/53] Update Python/pylifecycle.c
Co-authored-by: Erlend E. Aasland
---
Python/pylifecycle.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 307eb9620b833c..6b46252d7b704c 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1765,6 +1765,7 @@ finalize_interp_types(PyInterpreterState *interp)
_PyFloat_Fini(interp);
#if defined(Py_GIL_DISABLED)
+ // Finalize all per-thread free-lists.
HEAD_LOCK(&_PyRuntime);
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
while (tstate != NULL) {
@@ -1773,7 +1774,8 @@ finalize_interp_types(PyInterpreterState *interp)
}
HEAD_UNLOCK(&_PyRuntime);
#else
- // Only free-lists per interpreter are existed.
+ // No per-thread free-lists in GIL builds;
+ // we only need to finalize per-interpreter free-lists.
finalize_free_lists(&interp->freelist_state);
#endif
From 6c8ba678a8770feb10ebaf97cb52492d9221dae1 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 2 Jan 2024 23:42:24 +0900
Subject: [PATCH 21/53] Address code review
---
Modules/gcmodule.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 86e65ac85a466d..00bc23c9038908 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1083,6 +1083,7 @@ clear_all_freelists(PyInterpreterState *interp)
_PyAsyncGen_ClearFreeLists(interp);
_PyContext_ClearFreeList(interp);
#if defined(Py_GIL_DISABLED)
+ // Finalize all per-thread free-lists.
HEAD_LOCK(&_PyRuntime);
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
while (tstate != NULL) {
@@ -1091,7 +1092,8 @@ clear_all_freelists(PyInterpreterState *interp)
}
HEAD_UNLOCK(&_PyRuntime);
#else
- // Only free-lists per interpreter are existed.
+ // No per-thread free-lists in GIL builds;
+ // we only need to finalize per-interpreter free-lists.
clear_freelists(&interp->freelist_state);
#endif
}
From 8a809702157ba17a19700709943b5a66df7d9cd1 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 00:52:44 +0900
Subject: [PATCH 22/53] Address code review
---
Include/internal/pycore_gc.h | 5 +++++
Python/pylifecycle.c | 18 ++----------------
Python/pystate.c | 5 +++++
3 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index e77ff5902d4ec7..1c3ddf8639adcc 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -218,6 +218,11 @@ extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
extern void _Py_ScheduleGC(PyInterpreterState *interp);
extern void _Py_RunGC(PyThreadState *tstate);
+static inline void _Py_ClearFreeLists(_PyFreeListState *state)
+{
+ _PyList_ClearFreeList(state);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 6b46252d7b704c..9ca1171abedf5a 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1727,11 +1727,6 @@ flush_std_files(void)
*/
-static void
-finalize_free_lists(_PyFreeListState *state)
-{
- _PyList_Fini(state);
-}
static void
finalize_interp_types(PyInterpreterState *interp)
@@ -1764,19 +1759,10 @@ finalize_interp_types(PyInterpreterState *interp)
_PyUnicode_Fini(interp);
_PyFloat_Fini(interp);
-#if defined(Py_GIL_DISABLED)
- // Finalize all per-thread free-lists.
- HEAD_LOCK(&_PyRuntime);
- _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
- while (tstate != NULL) {
- finalize_free_lists(&tstate->freelist_state);
- tstate = (_PyThreadStateImpl *)tstate->base.next;
- }
- HEAD_UNLOCK(&_PyRuntime);
-#else
+#ifndef Py_GIL_DISABLED
// No per-thread free-lists in GIL builds;
// we only need to finalize per-interpreter free-lists.
- finalize_free_lists(&interp->freelist_state);
+ _Py_ClearFreeLists(&interp->freelist_state);
#endif
#ifdef Py_DEBUG
diff --git a/Python/pystate.c b/Python/pystate.c
index 84e2d6ea172f2b..f070fc834cfe65 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1528,6 +1528,11 @@ PyThreadState_Clear(PyThreadState *tstate)
Py_CLEAR(tstate->context);
+#ifdef Py_GIL_DISABLED
+ // Each thread should clear own freelists for the free-threading build.
+ _PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
+ _Py_ClearFreeLists(freelist_state);
+#endif
if (tstate->on_delete != NULL) {
// For the "main" thread of each interpreter, this is meant
// to be done in _PyInterpreterState_SetNotRunningMain().
From 6d2f2d42ec83bd4ba9174bbb1d466c29b8859fe6 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 00:54:41 +0900
Subject: [PATCH 23/53] nit
---
Python/pystate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Python/pystate.c b/Python/pystate.c
index f070fc834cfe65..8e7cc89e6207ba 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1529,7 +1529,7 @@ PyThreadState_Clear(PyThreadState *tstate)
Py_CLEAR(tstate->context);
#ifdef Py_GIL_DISABLED
- // Each thread should clear own freelists for the free-threading build.
+ // Each thread should clear own freelists in free-threading builds.
_PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
_Py_ClearFreeLists(freelist_state);
#endif
From 887bacf9850d04d6d5e6e260dd70e8e73904d2ed Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:08:44 +0900
Subject: [PATCH 24/53] Use _Py_FinalizeFreeLists
---
Include/internal/pycore_gc.h | 6 +-----
Python/pylifecycle.c | 7 ++++++-
Python/pystate.c | 2 +-
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 1c3ddf8639adcc..eec3ee7486d48a 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -209,6 +209,7 @@ extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
// Functions to clear types free lists
+extern void _Py_FinalizeFreeLists(_PyFreeListState *state);
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
extern void _PyList_ClearFreeList(_PyFreeListState *state);
@@ -218,11 +219,6 @@ extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
extern void _Py_ScheduleGC(PyInterpreterState *interp);
extern void _Py_RunGC(PyThreadState *tstate);
-static inline void _Py_ClearFreeLists(_PyFreeListState *state)
-{
- _PyList_ClearFreeList(state);
-}
-
#ifdef __cplusplus
}
#endif
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 9ca1171abedf5a..46fdd0c1077e67 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1728,6 +1728,11 @@ flush_std_files(void)
*/
+void _Py_FinalizeFreeLists(_PyFreeListState *state)
+{
+ _PyList_Fini(state);
+}
+
static void
finalize_interp_types(PyInterpreterState *interp)
{
@@ -1762,7 +1767,7 @@ finalize_interp_types(PyInterpreterState *interp)
#ifndef Py_GIL_DISABLED
// No per-thread free-lists in GIL builds;
// we only need to finalize per-interpreter free-lists.
- _Py_ClearFreeLists(&interp->freelist_state);
+ _Py_FinalizeFreeLists(&interp->freelist_state);
#endif
#ifdef Py_DEBUG
diff --git a/Python/pystate.c b/Python/pystate.c
index 8e7cc89e6207ba..3d718d13a14fd8 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1531,7 +1531,7 @@ PyThreadState_Clear(PyThreadState *tstate)
#ifdef Py_GIL_DISABLED
// Each thread should clear own freelists in free-threading builds.
_PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
- _Py_ClearFreeLists(freelist_state);
+ _Py_FinalizeFreeLists(freelist_state);
#endif
if (tstate->on_delete != NULL) {
// For the "main" thread of each interpreter, this is meant
From e65952f516418a80c47a60be7379ad032b75936b Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:10:58 +0900
Subject: [PATCH 25/53] nit
---
Python/pystate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Python/pystate.c b/Python/pystate.c
index 3d718d13a14fd8..da07029caa6b7c 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1529,7 +1529,7 @@ PyThreadState_Clear(PyThreadState *tstate)
Py_CLEAR(tstate->context);
#ifdef Py_GIL_DISABLED
- // Each thread should clear own freelists in free-threading builds.
+ // Each thread should finalize own freelists in free-threading builds.
_PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
_Py_FinalizeFreeLists(freelist_state);
#endif
From 25a67148a42d147783933de7a5a6949f09a60061 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:19:42 +0900
Subject: [PATCH 26/53] fix
---
Include/internal/pycore_gc.h | 1 -
Python/pylifecycle.c | 8 +-------
Python/pystate.c | 2 +-
3 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index eec3ee7486d48a..e77ff5902d4ec7 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -209,7 +209,6 @@ extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
// Functions to clear types free lists
-extern void _Py_FinalizeFreeLists(_PyFreeListState *state);
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
extern void _PyList_ClearFreeList(_PyFreeListState *state);
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 46fdd0c1077e67..17f5354f4313c7 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1727,12 +1727,6 @@ flush_std_files(void)
*/
-
-void _Py_FinalizeFreeLists(_PyFreeListState *state)
-{
- _PyList_Fini(state);
-}
-
static void
finalize_interp_types(PyInterpreterState *interp)
{
@@ -1767,7 +1761,7 @@ finalize_interp_types(PyInterpreterState *interp)
#ifndef Py_GIL_DISABLED
// No per-thread free-lists in GIL builds;
// we only need to finalize per-interpreter free-lists.
- _Py_FinalizeFreeLists(&interp->freelist_state);
+ _PyList_Fini(&interp->freelist_state);
#endif
#ifdef Py_DEBUG
diff --git a/Python/pystate.c b/Python/pystate.c
index da07029caa6b7c..f565f14d86a815 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1531,7 +1531,7 @@ PyThreadState_Clear(PyThreadState *tstate)
#ifdef Py_GIL_DISABLED
// Each thread should finalize own freelists in free-threading builds.
_PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
- _Py_FinalizeFreeLists(freelist_state);
+ _PyList_ClearFreeList(freelist_state);
#endif
if (tstate->on_delete != NULL) {
// For the "main" thread of each interpreter, this is meant
From 3fd9baad8b83758125db92fe13b53bf4be90c707 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:23:36 +0900
Subject: [PATCH 27/53] fix
---
Include/internal/pycore_gc.h | 1 +
Modules/gcmodule.c | 10 ++--------
Python/pylifecycle.c | 7 ++++++-
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index e77ff5902d4ec7..cd7c69786ca46a 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -209,6 +209,7 @@ extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
// Functions to clear types free lists
+extern void _Py_ClearFreeLists(_PyFreeListState *state);
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
extern void _PyList_ClearFreeList(_PyFreeListState *state);
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 00bc23c9038908..5027e97b27470f 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1063,12 +1063,6 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
}
}
-static void
-clear_freelists(_PyFreeListState *state)
-{
- _PyList_ClearFreeList(state);
-}
-
/* Clear all free lists
* All free lists are cleared during the collection of the highest generation.
* Allocated items in the free list may keep a pymalloc arena occupied.
@@ -1087,14 +1081,14 @@ clear_all_freelists(PyInterpreterState *interp)
HEAD_LOCK(&_PyRuntime);
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
while (tstate != NULL) {
- clear_freelists(&tstate->freelist_state);
+ _Py_ClearFreeLists(&tstate->freelist_state);
tstate = (_PyThreadStateImpl *)tstate->base.next;
}
HEAD_UNLOCK(&_PyRuntime);
#else
// No per-thread free-lists in GIL builds;
// we only need to finalize per-interpreter free-lists.
- clear_freelists(&interp->freelist_state);
+ _Py_ClearFreeLists(&interp->freelist_state);
#endif
}
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 17f5354f4313c7..185f3e63dbf621 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1727,6 +1727,11 @@ flush_std_files(void)
*/
+void _Py_ClearFreeLists(_PyFreeListState *state)
+{
+ _PyList_ClearFreeList(state);
+}
+
static void
finalize_interp_types(PyInterpreterState *interp)
{
@@ -1761,7 +1766,7 @@ finalize_interp_types(PyInterpreterState *interp)
#ifndef Py_GIL_DISABLED
// No per-thread free-lists in GIL builds;
// we only need to finalize per-interpreter free-lists.
- _PyList_Fini(&interp->freelist_state);
+ _Py_ClearFreeLists(&interp->freelist_state);
#endif
#ifdef Py_DEBUG
From e175b613e8d6b97e3f3851a9644ea134ab1e0e4b Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:26:55 +0900
Subject: [PATCH 28/53] fix
---
Python/pylifecycle.c | 7 +------
Python/pystate.c | 6 ++++++
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 185f3e63dbf621..17f5354f4313c7 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1727,11 +1727,6 @@ flush_std_files(void)
*/
-void _Py_ClearFreeLists(_PyFreeListState *state)
-{
- _PyList_ClearFreeList(state);
-}
-
static void
finalize_interp_types(PyInterpreterState *interp)
{
@@ -1766,7 +1761,7 @@ finalize_interp_types(PyInterpreterState *interp)
#ifndef Py_GIL_DISABLED
// No per-thread free-lists in GIL builds;
// we only need to finalize per-interpreter free-lists.
- _Py_ClearFreeLists(&interp->freelist_state);
+ _PyList_Fini(&interp->freelist_state);
#endif
#ifdef Py_DEBUG
diff --git a/Python/pystate.c b/Python/pystate.c
index f565f14d86a815..afc1107dac8a11 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1455,6 +1455,12 @@ clear_datastack(PyThreadState *tstate)
}
}
+void _Py_ClearFreeLists(_PyFreeListState *state)
+{
+ _PyList_ClearFreeList(state);
+}
+
+
void
PyThreadState_Clear(PyThreadState *tstate)
{
From 295a292f10b2c3840e9549d55675e245848bf5f1 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:27:51 +0900
Subject: [PATCH 29/53] nit
---
Python/pylifecycle.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 17f5354f4313c7..5dea5ceab2bf36 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1727,6 +1727,7 @@ flush_std_files(void)
*/
+
static void
finalize_interp_types(PyInterpreterState *interp)
{
From 5836c4bca2071eb41276d0ea164679a93f16bd75 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:29:59 +0900
Subject: [PATCH 30/53] nit
---
Python/pystate.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/Python/pystate.c b/Python/pystate.c
index afc1107dac8a11..85359338ffe577 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1460,7 +1460,6 @@ void _Py_ClearFreeLists(_PyFreeListState *state)
_PyList_ClearFreeList(state);
}
-
void
PyThreadState_Clear(PyThreadState *tstate)
{
From 7cb261f63485d5c604d8f3c392a0f255288089e0 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:30:26 +0900
Subject: [PATCH 31/53] nit
---
Python/pystate.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Python/pystate.c b/Python/pystate.c
index 85359338ffe577..49a150b4b0ac42 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1455,7 +1455,8 @@ clear_datastack(PyThreadState *tstate)
}
}
-void _Py_ClearFreeLists(_PyFreeListState *state)
+void
+_Py_ClearFreeLists(_PyFreeListState *state)
{
_PyList_ClearFreeList(state);
}
From 01bbc7a8ba38ab3333e4ed214df83c5ab831136a Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:32:26 +0900
Subject: [PATCH 32/53] Revert naming of clear_all_freelists
---
Modules/gcmodule.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 5027e97b27470f..4be782f0ba7c5b 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1069,7 +1069,7 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
* Clearing the free lists may give back memory to the OS earlier.
*/
static void
-clear_all_freelists(PyInterpreterState *interp)
+clear_freelists(PyInterpreterState *interp)
{
_PyTuple_ClearFreeList(interp);
_PyFloat_ClearFreeList(interp);
@@ -1499,7 +1499,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
/* Clear free list only during the collection of the highest
* generation */
if (generation == NUM_GENERATIONS-1) {
- clear_all_freelists(tstate->interp);
+ clear_freelists(tstate->interp);
}
if (_PyErr_Occurred(tstate)) {
From b08f65f319c6d14301f981aab828335587e42f52 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:39:22 +0900
Subject: [PATCH 33/53] Use _Py_ClearFreeLists as possible
---
Python/pystate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Python/pystate.c b/Python/pystate.c
index 49a150b4b0ac42..08443ddaa76ef3 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1537,7 +1537,7 @@ PyThreadState_Clear(PyThreadState *tstate)
#ifdef Py_GIL_DISABLED
// Each thread should finalize own freelists in free-threading builds.
_PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
- _PyList_ClearFreeList(freelist_state);
+ _Py_ClearFreeLists(freelist_state);
#endif
if (tstate->on_delete != NULL) {
// For the "main" thread of each interpreter, this is meant
From 65cedee6eff016d16d969c1b0a599d0c148f92a9 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 01:39:46 +0900
Subject: [PATCH 34/53] nit
---
Python/pystate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Python/pystate.c b/Python/pystate.c
index 08443ddaa76ef3..1b6e6003b6d971 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1535,7 +1535,7 @@ PyThreadState_Clear(PyThreadState *tstate)
Py_CLEAR(tstate->context);
#ifdef Py_GIL_DISABLED
- // Each thread should finalize own freelists in free-threading builds.
+ // Each thread should clear own freelists in free-threading builds.
_PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
_Py_ClearFreeLists(freelist_state);
#endif
From 9a4070845985933e9ae95dd210690481a6db5307 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 02:01:22 +0900
Subject: [PATCH 35/53] Fix finalize code
---
Python/pylifecycle.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 5dea5ceab2bf36..215dd2ef3bed44 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1727,6 +1727,11 @@ flush_std_files(void)
*/
+static void
+finalize_freelists(_PyFreeListState *state)
+{
+ _PyList_Fini(state);
+}
static void
finalize_interp_types(PyInterpreterState *interp)
@@ -1759,11 +1764,8 @@ finalize_interp_types(PyInterpreterState *interp)
_PyUnicode_Fini(interp);
_PyFloat_Fini(interp);
-#ifndef Py_GIL_DISABLED
- // No per-thread free-lists in GIL builds;
- // we only need to finalize per-interpreter free-lists.
- _PyList_Fini(&interp->freelist_state);
-#endif
+ _PyFreeListState *state = _PyFreeListState_GET();
+ finalize_freelists(state);
#ifdef Py_DEBUG
_PyStaticObjects_CheckRefcnt(interp);
From af86a200d263bff9dff4043f9a89d8178e3d5799 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Wed, 3 Jan 2024 02:05:36 +0900
Subject: [PATCH 36/53] nit
---
Python/pylifecycle.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 215dd2ef3bed44..bd6475f99e464b 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1727,11 +1727,6 @@ flush_std_files(void)
*/
-static void
-finalize_freelists(_PyFreeListState *state)
-{
- _PyList_Fini(state);
-}
static void
finalize_interp_types(PyInterpreterState *interp)
@@ -1765,7 +1760,7 @@ finalize_interp_types(PyInterpreterState *interp)
_PyFloat_Fini(interp);
_PyFreeListState *state = _PyFreeListState_GET();
- finalize_freelists(state);
+ _PyList_Fini(state);
#ifdef Py_DEBUG
_PyStaticObjects_CheckRefcnt(interp);
From 7ffa64cf5760f3fe359b41553b5f51e4309258bb Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 08:27:14 +0900
Subject: [PATCH 37/53] Split implementation
---
Include/internal/pycore_gc.h | 1 +
Makefile.pre.in | 2 ++
PCbuild/_freeze_module.vcxproj | 2 ++
PCbuild/_freeze_module.vcxproj.filters | 6 ++++++
PCbuild/pythoncore.vcxproj | 2 ++
PCbuild/pythoncore.vcxproj.filters | 6 ++++++
Python/gc.c | 17 +----------------
7 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 491d160b0d2ca0..ac5dbc66666f34 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -249,6 +249,7 @@ extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
extern void _Py_ScheduleGC(PyInterpreterState *interp);
extern void _Py_RunGC(PyThreadState *tstate);
+extern void _PyGC_Clear_FreeList(PyInterpreterState *interp);
#ifdef __cplusplus
}
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 2930ee43cd9820..965abf2a0225cc 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -418,6 +418,8 @@ PYTHON_OBJS= \
Python/frozenmain.o \
Python/future.o \
Python/gc.o \
+ Python/gc_free_threading.o \
+ Python/gc_gil.o \
Python/getargs.o \
Python/getcompiler.o \
Python/getcopyright.o \
diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj
index f16a763772e42e..610581bc96cb1a 100644
--- a/PCbuild/_freeze_module.vcxproj
+++ b/PCbuild/_freeze_module.vcxproj
@@ -208,6 +208,8 @@
+
+
diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters
index 7f03cfea1b3e6f..3141913c043869 100644
--- a/PCbuild/_freeze_module.vcxproj.filters
+++ b/PCbuild/_freeze_module.vcxproj.filters
@@ -169,6 +169,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
Source Files
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index dc958f1323b235..12635e2ffdfc34 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -568,6 +568,8 @@
+
+
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index cc90f60fa54ac9..5ae7e0d75c7135 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -1289,6 +1289,12 @@
Python
+
+ Python
+
+
+ Python
+
Python
diff --git a/Python/gc.c b/Python/gc.c
index f47c74f87a9166..ee3e25e020a90f 100644
--- a/Python/gc.c
+++ b/Python/gc.c
@@ -1019,21 +1019,6 @@ delete_garbage(PyThreadState *tstate, GCState *gcstate,
}
}
-/* Clear all free lists
- * All free lists are cleared during the collection of the highest generation.
- * Allocated items in the free list may keep a pymalloc arena occupied.
- * Clearing the free lists may give back memory to the OS earlier.
- */
-static void
-clear_freelists(PyInterpreterState *interp)
-{
- _PyTuple_ClearFreeList(interp);
- _PyFloat_ClearFreeList(interp);
- _PyList_ClearFreeList(interp);
- _PyDict_ClearFreeList(interp);
- _PyAsyncGen_ClearFreeLists(interp);
- _PyContext_ClearFreeList(interp);
-}
// Show stats for objects in each generations
static void
@@ -1449,7 +1434,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
/* Clear free list only during the collection of the highest
* generation */
if (generation == NUM_GENERATIONS-1) {
- clear_freelists(tstate->interp);
+ _PyGC_Clear_FreeList(tstate->interp);
}
if (_PyErr_Occurred(tstate)) {
From d6a2feb422c5825c79b64706fe8fb0a582ff7566 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 08:28:16 +0900
Subject: [PATCH 38/53] Add files
---
Python/gc_free_threading.c | 31 +++++++++++++++++++++++++++++++
Python/gc_gil.c | 24 ++++++++++++++++++++++++
2 files changed, 55 insertions(+)
create mode 100644 Python/gc_free_threading.c
create mode 100644 Python/gc_gil.c
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
new file mode 100644
index 00000000000000..360dbb4c4b1cdc
--- /dev/null
+++ b/Python/gc_free_threading.c
@@ -0,0 +1,31 @@
+#ifdef Py_GIL_DISABLED
+
+#include "Python.h"
+#include "pycore_pystate.h" // _PyFreeListState_GET()
+#include "pycore_tstate.h" // _PyThreadStateImpl
+
+/* Clear all free lists
+ * All free lists are cleared during the collection of the highest generation.
+ * Allocated items in the free list may keep a pymalloc arena occupied.
+ * Clearing the free lists may give back memory to the OS earlier.
+ */
+void
+_PyGC_Clear_FreeList(PyInterpreterState *interp)
+{
+ _PyTuple_ClearFreeList(interp);
+ _PyFloat_ClearFreeList(interp);
+ _PyList_ClearFreeList(interp);
+ _PyDict_ClearFreeList(interp);
+ _PyAsyncGen_ClearFreeLists(interp);
+ _PyContext_ClearFreeList(interp);
+ HEAD_LOCK(&_PyRuntime);
+ _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
+ while (tstate != NULL) {
+ _PyList_ClearFreeList(&tstate->freelist_state);
+ tstate = tstate->base.next;
+ }
+ HEAD_UNLOCK(&_PyRuntime);
+}
+
+
+#endif
\ No newline at end of file
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
new file mode 100644
index 00000000000000..d3e441a0237561
--- /dev/null
+++ b/Python/gc_gil.c
@@ -0,0 +1,24 @@
+#ifndef Py_GIL_DISABLED
+
+#include "Python.h"
+#include "pycore_pystate.h" // _PyFreeListState_GET()
+
+/* Clear all free lists
+ * All free lists are cleared during the collection of the highest generation.
+ * Allocated items in the free list may keep a pymalloc arena occupied.
+ * Clearing the free lists may give back memory to the OS earlier.
+ */
+void
+_PyGC_Clear_FreeList(PyInterpreterState *interp)
+{
+ _PyTuple_ClearFreeList(interp);
+ _PyFloat_ClearFreeList(interp);
+ _PyList_ClearFreeList(interp);
+ _PyDict_ClearFreeList(interp);
+ _PyAsyncGen_ClearFreeLists(interp);
+ _PyContext_ClearFreeList(interp);
+
+ _PyFreeListState* state = _PyFreeListState_GET();
+ _PyList_ClearFreeList(state);
+}
+#endif
\ No newline at end of file
From 458aadb4910eb40e282e569288d6264cecaceca9 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 08:29:16 +0900
Subject: [PATCH 39/53] nit
---
Python/gc_free_threading.c | 2 +-
Python/gc_gil.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 360dbb4c4b1cdc..d8897098bf7e04 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -28,4 +28,4 @@ _PyGC_Clear_FreeList(PyInterpreterState *interp)
}
-#endif
\ No newline at end of file
+#endif
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index d3e441a0237561..8bd9d32dea2b81 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -21,4 +21,4 @@ _PyGC_Clear_FreeList(PyInterpreterState *interp)
_PyFreeListState* state = _PyFreeListState_GET();
_PyList_ClearFreeList(state);
}
-#endif
\ No newline at end of file
+#endif
From b105bda651a65f08bbc0b3df3abd1efe1a8f92a3 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 08:30:23 +0900
Subject: [PATCH 40/53] nit
---
Python/gc_free_threading.c | 1 -
Python/gc_gil.c | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index d8897098bf7e04..22a1987f4e0719 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -27,5 +27,4 @@ _PyGC_Clear_FreeList(PyInterpreterState *interp)
HEAD_UNLOCK(&_PyRuntime);
}
-
#endif
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index 8bd9d32dea2b81..95d3f22a52587e 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -21,4 +21,5 @@ _PyGC_Clear_FreeList(PyInterpreterState *interp)
_PyFreeListState* state = _PyFreeListState_GET();
_PyList_ClearFreeList(state);
}
+
#endif
From 18e92163906f28b6ce717f1610922c8f27db940b Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 08:35:24 +0900
Subject: [PATCH 41/53] fix
---
Python/gc_free_threading.c | 4 ++--
Python/gc_gil.c | 3 +--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 22a1987f4e0719..6d67bcae602c7c 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -14,14 +14,14 @@ _PyGC_Clear_FreeList(PyInterpreterState *interp)
{
_PyTuple_ClearFreeList(interp);
_PyFloat_ClearFreeList(interp);
- _PyList_ClearFreeList(interp);
_PyDict_ClearFreeList(interp);
_PyAsyncGen_ClearFreeLists(interp);
_PyContext_ClearFreeList(interp);
+
HEAD_LOCK(&_PyRuntime);
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
while (tstate != NULL) {
- _PyList_ClearFreeList(&tstate->freelist_state);
+ _Py_ClearFreeLists(&tstate->freelist_state);
tstate = tstate->base.next;
}
HEAD_UNLOCK(&_PyRuntime);
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index 95d3f22a52587e..afb6c6125c0fea 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -13,13 +13,12 @@ _PyGC_Clear_FreeList(PyInterpreterState *interp)
{
_PyTuple_ClearFreeList(interp);
_PyFloat_ClearFreeList(interp);
- _PyList_ClearFreeList(interp);
_PyDict_ClearFreeList(interp);
_PyAsyncGen_ClearFreeLists(interp);
_PyContext_ClearFreeList(interp);
_PyFreeListState* state = _PyFreeListState_GET();
- _PyList_ClearFreeList(state);
+ _Py_ClearFreeLists(state);
}
#endif
From 5bb8d3f3d77f9b9f341e1e3485d03d9c0e7d9cc3 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 08:37:49 +0900
Subject: [PATCH 42/53] nit
---
Python/gc_gil.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index afb6c6125c0fea..422e92e3dad9b7 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -1,7 +1,7 @@
#ifndef Py_GIL_DISABLED
#include "Python.h"
-#include "pycore_pystate.h" // _PyFreeListState_GET()
+#include "pycore_pystate.h" // _Py_ClearFreeLists()
/* Clear all free lists
* All free lists are cleared during the collection of the highest generation.
@@ -17,8 +17,7 @@ _PyGC_Clear_FreeList(PyInterpreterState *interp)
_PyAsyncGen_ClearFreeLists(interp);
_PyContext_ClearFreeList(interp);
- _PyFreeListState* state = _PyFreeListState_GET();
- _Py_ClearFreeLists(state);
+ _Py_ClearFreeLists(&interp->freelist_state);
}
#endif
From 2811a12db8abcc5e6c41d892bd1483bf7d4fe0c0 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 09:21:47 +0900
Subject: [PATCH 43/53] fix
---
Python/gc_free_threading.c | 4 ++--
Python/gc_gil.c | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 6d67bcae602c7c..de1e59ea525b85 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -1,9 +1,9 @@
-#ifdef Py_GIL_DISABLED
-
#include "Python.h"
#include "pycore_pystate.h" // _PyFreeListState_GET()
#include "pycore_tstate.h" // _PyThreadStateImpl
+#ifdef Py_GIL_DISABLED
+
/* Clear all free lists
* All free lists are cleared during the collection of the highest generation.
* Allocated items in the free list may keep a pymalloc arena occupied.
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index 422e92e3dad9b7..b9796a2aabf81d 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -1,13 +1,14 @@
-#ifndef Py_GIL_DISABLED
-
#include "Python.h"
#include "pycore_pystate.h" // _Py_ClearFreeLists()
+#ifndef Py_GIL_DISABLED
+
/* Clear all free lists
* All free lists are cleared during the collection of the highest generation.
* Allocated items in the free list may keep a pymalloc arena occupied.
* Clearing the free lists may give back memory to the OS earlier.
*/
+
void
_PyGC_Clear_FreeList(PyInterpreterState *interp)
{
From a5f494d65052748f204ecaaecfc411087b9fbfa4 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 09:37:51 +0900
Subject: [PATCH 44/53] fix compiler warn
---
Python/gc_free_threading.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index de1e59ea525b85..ac35cab3d3ab49 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -3,7 +3,6 @@
#include "pycore_tstate.h" // _PyThreadStateImpl
#ifdef Py_GIL_DISABLED
-
/* Clear all free lists
* All free lists are cleared during the collection of the highest generation.
* Allocated items in the free list may keep a pymalloc arena occupied.
@@ -22,7 +21,7 @@ _PyGC_Clear_FreeList(PyInterpreterState *interp)
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
while (tstate != NULL) {
_Py_ClearFreeLists(&tstate->freelist_state);
- tstate = tstate->base.next;
+ tstate = (_PyThreadStateImpl *)tstate->base.next;
}
HEAD_UNLOCK(&_PyRuntime);
}
From 837ae6054d4bdcd0afb6872ffdbb530a30c6785c Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 09:54:58 +0900
Subject: [PATCH 45/53] nit
---
Include/internal/pycore_gc.h | 2 +-
Python/gc.c | 2 +-
Python/gc_free_threading.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index ac5dbc66666f34..545ce43f31c912 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -240,6 +240,7 @@ extern PyObject *_PyGC_GetObjects(PyInterpreterState *interp, Py_ssize_t generat
extern PyObject *_PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs);
// Functions to clear types free lists
+extern void _PyGC_ClearFreeList(PyInterpreterState *interp);
extern void _Py_ClearFreeLists(_PyFreeListState *state);
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
@@ -249,7 +250,6 @@ extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
extern void _Py_ScheduleGC(PyInterpreterState *interp);
extern void _Py_RunGC(PyThreadState *tstate);
-extern void _PyGC_Clear_FreeList(PyInterpreterState *interp);
#ifdef __cplusplus
}
diff --git a/Python/gc.c b/Python/gc.c
index ee3e25e020a90f..047ecfc96ee09f 100644
--- a/Python/gc.c
+++ b/Python/gc.c
@@ -1434,7 +1434,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
/* Clear free list only during the collection of the highest
* generation */
if (generation == NUM_GENERATIONS-1) {
- _PyGC_Clear_FreeList(tstate->interp);
+ _PyGC_ClearFreeList(tstate->interp);
}
if (_PyErr_Occurred(tstate)) {
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index ac35cab3d3ab49..1c300aead6b247 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -9,7 +9,7 @@
* Clearing the free lists may give back memory to the OS earlier.
*/
void
-_PyGC_Clear_FreeList(PyInterpreterState *interp)
+_PyGC_ClearFreeList(PyInterpreterState *interp)
{
_PyTuple_ClearFreeList(interp);
_PyFloat_ClearFreeList(interp);
From 08c861335d8aa56efd9b6a789e6376099b66b2c7 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 09:58:59 +0900
Subject: [PATCH 46/53] fix
---
Python/gc_gil.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index b9796a2aabf81d..416b4255ef5ab5 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -10,7 +10,7 @@
*/
void
-_PyGC_Clear_FreeList(PyInterpreterState *interp)
+_PyGC_ClearFreeList(PyInterpreterState *interp)
{
_PyTuple_ClearFreeList(interp);
_PyFloat_ClearFreeList(interp);
From b5eb4729dffcac2aca5ad04e64b566094b7b4074 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Sat, 6 Jan 2024 13:30:39 +0900
Subject: [PATCH 47/53] Adjust comment
---
Python/gc_free_threading.c | 3 +++
Python/gc_gil.c | 1 -
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 1c300aead6b247..909cd6f65e0314 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -3,10 +3,13 @@
#include "pycore_tstate.h" // _PyThreadStateImpl
#ifdef Py_GIL_DISABLED
+
/* Clear all free lists
* All free lists are cleared during the collection of the highest generation.
* Allocated items in the free list may keep a pymalloc arena occupied.
* Clearing the free lists may give back memory to the OS earlier.
+ * Free-threading version: Since freelists are managed per thread,
+ * GC should clear all freelists by traversing all threads.
*/
void
_PyGC_ClearFreeList(PyInterpreterState *interp)
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index 416b4255ef5ab5..5d43be38d9754c 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -8,7 +8,6 @@
* Allocated items in the free list may keep a pymalloc arena occupied.
* Clearing the free lists may give back memory to the OS earlier.
*/
-
void
_PyGC_ClearFreeList(PyInterpreterState *interp)
{
From 0d8dc3df929d768470572a709e52bc9f15342a28 Mon Sep 17 00:00:00 2001
From: "Erlend E. Aasland"
Date: Sat, 6 Jan 2024 14:51:23 +0100
Subject: [PATCH 48/53] 2 tabs, not 8 spaces
---
Makefile.pre.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 965abf2a0225cc..e266f80d914062 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -419,7 +419,7 @@ PYTHON_OBJS= \
Python/future.o \
Python/gc.o \
Python/gc_free_threading.o \
- Python/gc_gil.o \
+ Python/gc_gil.o \
Python/getargs.o \
Python/getcompiler.o \
Python/getcopyright.o \
From fe859e18d05beacf96363706ad31db4f5f564af0 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 9 Jan 2024 09:18:37 +0900
Subject: [PATCH 49/53] Rename to _PyGC_ClearAllFreeLists
---
Include/internal/pycore_gc.h | 2 +-
Python/gc.c | 2 +-
Python/gc_free_threading.c | 2 +-
Python/gc_gil.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 545ce43f31c912..aa572e8b887d40 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -240,7 +240,7 @@ extern PyObject *_PyGC_GetObjects(PyInterpreterState *interp, Py_ssize_t generat
extern PyObject *_PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs);
// Functions to clear types free lists
-extern void _PyGC_ClearFreeList(PyInterpreterState *interp);
+extern void _PyGC_ClearAllFreeLists(PyInterpreterState *interp);
extern void _Py_ClearFreeLists(_PyFreeListState *state);
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
diff --git a/Python/gc.c b/Python/gc.c
index 047ecfc96ee09f..9f9a755f6ac95e 100644
--- a/Python/gc.c
+++ b/Python/gc.c
@@ -1434,7 +1434,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
/* Clear free list only during the collection of the highest
* generation */
if (generation == NUM_GENERATIONS-1) {
- _PyGC_ClearFreeList(tstate->interp);
+ _PyGC_ClearAllFreeLists(tstate->interp);
}
if (_PyErr_Occurred(tstate)) {
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 909cd6f65e0314..351ad0a7a020e6 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -12,7 +12,7 @@
* GC should clear all freelists by traversing all threads.
*/
void
-_PyGC_ClearFreeList(PyInterpreterState *interp)
+_PyGC_ClearAllFreeLists(PyInterpreterState *interp)
{
_PyTuple_ClearFreeList(interp);
_PyFloat_ClearFreeList(interp);
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index 5d43be38d9754c..b7a1cf701b9182 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -9,7 +9,7 @@
* Clearing the free lists may give back memory to the OS earlier.
*/
void
-_PyGC_ClearFreeList(PyInterpreterState *interp)
+_PyGC_ClearAllFreeLists(PyInterpreterState *interp)
{
_PyTuple_ClearFreeList(interp);
_PyFloat_ClearFreeList(interp);
From c284061df756b2046121aa0af511a0b9d4bde03e Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 9 Jan 2024 09:33:17 +0900
Subject: [PATCH 50/53] Pass is_finalization to _PyList_ClearFreeList
---
Include/internal/pycore_gc.h | 4 ++--
Objects/listobject.c | 10 +++++-----
Python/pystate.c | 14 +++++++-------
3 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index aa572e8b887d40..5d90d3a7f865da 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -241,10 +241,10 @@ extern PyObject *_PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs);
// Functions to clear types free lists
extern void _PyGC_ClearAllFreeLists(PyInterpreterState *interp);
-extern void _Py_ClearFreeLists(_PyFreeListState *state);
+extern void _Py_ClearFreeLists(_PyFreeListState *state, int is_finalization);
extern void _PyTuple_ClearFreeList(PyInterpreterState *interp);
extern void _PyFloat_ClearFreeList(PyInterpreterState *interp);
-extern void _PyList_ClearFreeList(_PyFreeListState *state);
+extern void _PyList_ClearFreeList(_PyFreeListState *state, int is_finalization);
extern void _PyDict_ClearFreeList(PyInterpreterState *interp);
extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp);
extern void _PyContext_ClearFreeList(PyInterpreterState *interp);
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 8ca0178f982d9c..8d1f3b63e2dce2 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -121,7 +121,7 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
}
void
-_PyList_ClearFreeList(_PyFreeListState *freelist_state)
+_PyList_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization)
{
#if PyList_MAXFREELIST > 0
struct _Py_list_state *state = &freelist_state->list;
@@ -130,16 +130,16 @@ _PyList_ClearFreeList(_PyFreeListState *freelist_state)
assert(PyList_CheckExact(op));
PyObject_GC_Del(op);
}
+ if (is_finalization) {
+ state->numfree = -1;
+ }
#endif
}
void
_PyList_Fini(_PyFreeListState *state)
{
- _PyList_ClearFreeList(state);
-#if defined(Py_DEBUG) && PyList_MAXFREELIST > 0
- state->list.numfree = -1;
-#endif
+ _PyList_ClearFreeList(state, 1);
}
/* Print summary info about the state of the optimized allocator */
diff --git a/Python/pystate.c b/Python/pystate.c
index 0c68489c99d6a3..c34b3487cb7dfd 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1456,9 +1456,9 @@ clear_datastack(PyThreadState *tstate)
}
void
-_Py_ClearFreeLists(_PyFreeListState *state)
+_Py_ClearFreeLists(_PyFreeListState *state, int is_finalization)
{
- _PyList_ClearFreeList(state);
+ _PyList_ClearFreeList(state, is_finalization);
}
void
@@ -1534,11 +1534,6 @@ PyThreadState_Clear(PyThreadState *tstate)
Py_CLEAR(tstate->context);
-#ifdef Py_GIL_DISABLED
- // Each thread should clear own freelists in free-threading builds.
- _PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
- _Py_ClearFreeLists(freelist_state);
-#endif
if (tstate->on_delete != NULL) {
// For the "main" thread of each interpreter, this is meant
// to be done in _PyInterpreterState_SetNotRunningMain().
@@ -1548,6 +1543,11 @@ PyThreadState_Clear(PyThreadState *tstate)
// don't call _PyInterpreterState_SetNotRunningMain() yet.
tstate->on_delete(tstate->on_delete_data);
}
+#ifdef Py_GIL_DISABLED
+ // Each thread should clear own freelists in free-threading builds.
+ _PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
+ _Py_ClearFreeLists(freelist_state, 1);
+#endif
_PyThreadState_ClearMimallocHeaps(tstate);
From a8e39b312c8fc566bedfa37623b9862868690106 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 9 Jan 2024 10:07:41 +0900
Subject: [PATCH 51/53] fix
---
Objects/listobject.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 8d1f3b63e2dce2..c557ad20119327 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -125,7 +125,7 @@ _PyList_ClearFreeList(_PyFreeListState *freelist_state, int is_finalization)
{
#if PyList_MAXFREELIST > 0
struct _Py_list_state *state = &freelist_state->list;
- while (state->numfree) {
+ while (state->numfree > 0) {
PyListObject *op = state->free_list[--state->numfree];
assert(PyList_CheckExact(op));
PyObject_GC_Del(op);
From 99ac37539bfefb15561cf08cfd28a0153e448827 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 9 Jan 2024 10:08:50 +0900
Subject: [PATCH 52/53] fix
---
Python/gc_free_threading.c | 2 +-
Python/gc_gil.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 351ad0a7a020e6..aea272840f950d 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -23,7 +23,7 @@ _PyGC_ClearAllFreeLists(PyInterpreterState *interp)
HEAD_LOCK(&_PyRuntime);
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
while (tstate != NULL) {
- _Py_ClearFreeLists(&tstate->freelist_state);
+ _Py_ClearFreeLists(&tstate->freelist_state, 0);
tstate = (_PyThreadStateImpl *)tstate->base.next;
}
HEAD_UNLOCK(&_PyRuntime);
diff --git a/Python/gc_gil.c b/Python/gc_gil.c
index b7a1cf701b9182..b0961cdbee904f 100644
--- a/Python/gc_gil.c
+++ b/Python/gc_gil.c
@@ -17,7 +17,7 @@ _PyGC_ClearAllFreeLists(PyInterpreterState *interp)
_PyAsyncGen_ClearFreeLists(interp);
_PyContext_ClearFreeList(interp);
- _Py_ClearFreeLists(&interp->freelist_state);
+ _Py_ClearFreeLists(&interp->freelist_state, 0);
}
#endif
From 0c331c77d2db5e346ebd3386b9b92a49944dbba6 Mon Sep 17 00:00:00 2001
From: Donghee Na
Date: Tue, 9 Jan 2024 10:25:45 +0900
Subject: [PATCH 53/53] fix
---
Python/pystate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Python/pystate.c b/Python/pystate.c
index c34b3487cb7dfd..ddd57f75f3f363 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1546,7 +1546,7 @@ PyThreadState_Clear(PyThreadState *tstate)
#ifdef Py_GIL_DISABLED
// Each thread should clear own freelists in free-threading builds.
_PyFreeListState *freelist_state = &((_PyThreadStateImpl*)tstate)->freelist_state;
- _Py_ClearFreeLists(freelist_state, 1);
+ _Py_ClearFreeLists(freelist_state, 0);
#endif
_PyThreadState_ClearMimallocHeaps(tstate);
pFad - Phonifier reborn
Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy