Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cpython-unix/build-cpython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,11 @@ if [ "${PYTHON_MAJMIN_VERSION}" = 3.14 ]; then
patch -p1 -i "${ROOT}/patch-python-3.14-asyncio-static.patch"
fi

# Backport a gc incremental collection fix to 3.14.
if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" && -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_14}" ]]; then
patch -p1 -i "${ROOT}/patch-gc-collect-increment-3.14.patch"
fi

# Ensure the new build-details.json file reports relocatable paths.
# There is not yet a flag in ./configure for this, sadly.
if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then
Expand Down
25 changes: 25 additions & 0 deletions cpython-unix/patch-gc-collect-increment-3.14.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
diff --git a/Python/gc.c b/Python/gc.c
index 91d77237620..53643ce5c5d 100644
--- a/Python/gc.c
+++ b/Python/gc.c
@@ -1616,17 +1616,16 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
GC_STAT_ADD(1, collections, 1);
GCState *gcstate = &tstate->interp->gc;
gcstate->work_to_do += assess_work_to_do(gcstate);
- if (gcstate->work_to_do < 0) {
- return;
- }
untrack_tuples(&gcstate->young.head);
if (gcstate->phase == GC_PHASE_MARK) {
+ /* Start a new scavenge and immediately continue into the collect phase.
+ * Otherwise, sparse cycles created continuously can wait for another
+ * threshold crossing before the collector reclaims them.
+ */
Py_ssize_t objects_marked = mark_at_start(tstate);
GC_STAT_ADD(1, objects_transitively_reachable, objects_marked);
- gcstate->work_to_do -= objects_marked;
validate_spaces(gcstate);
- return;
}
PyGC_Head *not_visited = &gcstate->old[gcstate->visited_space^1].head;
PyGC_Head *visited = &gcstate->old[gcstate->visited_space].head;
Loading