diff options
| author | Peter Bierma <zintensitydev@gmail.com> | 2024-11-15 13:46:00 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-15 13:46:00 (GMT) |
| commit | ecda3ae2a51cdec65996005690391172bc25ca4b (patch) | |
| tree | 91f9cd11e26af427b4e7723dff81454ab947ba45 /Python | |
| parent | 3227680d2de57a4617a10e6371ec00e62ad9f386 (diff) | |
| download | cpython-ecda3ae2a51cdec65996005690391172bc25ca4b.zip cpython-ecda3ae2a51cdec65996005690391172bc25ca4b.tar.gz cpython-ecda3ae2a51cdec65996005690391172bc25ca4b.tar.bz2 | |
[3.13] gh-126312: Don't traverse frozen objects on the free-threaded build (GH-126338) (#126866)
* Fix merge conflicts.
* [3.13] gh-126312: Don't traverse frozen objects on the free-threaded build (GH-126338)
Also, _PyGC_Freeze() no longer freezes unreachable objects.
(cherry picked from commit d4c72fed8cba8e15ab7bb6c30a92bc9f2c8f0a2c)
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
---------
Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com>
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/gc_free_threading.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index bf3cd01..ff86c75 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -111,6 +111,12 @@ worklist_remove(struct worklist_iter *iter) } static inline int +gc_is_frozen(PyObject *op) +{ + return (op->ob_gc_bits & _PyGC_BITS_FROZEN) != 0; +} + +static inline int gc_is_unreachable(PyObject *op) { return (op->ob_gc_bits & _PyGC_BITS_UNREACHABLE) != 0; @@ -229,7 +235,7 @@ op_from_block(void *block, void *arg, bool include_frozen) if (!_PyObject_GC_IS_TRACKED(op)) { return NULL; } - if (!include_frozen && (op->ob_gc_bits & _PyGC_BITS_FROZEN) != 0) { + if (!include_frozen && gc_is_frozen(op)) { return NULL; } return op; @@ -364,7 +370,10 @@ process_delayed_frees(PyInterpreterState *interp) static int visit_decref(PyObject *op, void *arg) { - if (_PyObject_GC_IS_TRACKED(op) && !_Py_IsImmortal(op)) { + if (_PyObject_GC_IS_TRACKED(op) + && !_Py_IsImmortal(op) + && !gc_is_frozen(op)) + { // If update_refs hasn't reached this object yet, mark it // as (tentatively) unreachable and initialize ob_tid to zero. gc_maybe_init_refs(op); @@ -1419,7 +1428,7 @@ visit_freeze(const mi_heap_t *heap, const mi_heap_area_t *area, void *block, size_t block_size, void *args) { PyObject *op = op_from_block(block, args, true); - if (op != NULL) { + if (op != NULL && !gc_is_unreachable(op)) { op->ob_gc_bits |= _PyGC_BITS_FROZEN; } return true; @@ -1464,7 +1473,7 @@ visit_count_frozen(const mi_heap_t *heap, const mi_heap_area_t *area, void *block, size_t block_size, void *args) { PyObject *op = op_from_block(block, args, true); - if (op != NULL && (op->ob_gc_bits & _PyGC_BITS_FROZEN) != 0) { + if (op != NULL && gc_is_frozen(op)) { struct count_frozen_args *arg = (struct count_frozen_args *)args; arg->count++; } |
