summaryrefslogtreecommitdiffstats
path: root/Modules/gcmodule.c
diff options
context:
space:
mode:
authorEddie Elizondo <eduardo.elizondorueda@gmail.com>2023-04-22 19:39:37 (GMT)
committerGitHub <noreply@github.com>2023-04-22 19:39:37 (GMT)
commitea2c0016502472aa8baa3149050ada776d17a009 (patch)
treee9e3935a9b71a1f88ac18c24fe512d199880ff90 /Modules/gcmodule.c
parent916de04fd1838530096336aadb3b94b774ed6c90 (diff)
downloadcpython-ea2c0016502472aa8baa3149050ada776d17a009.zip
cpython-ea2c0016502472aa8baa3149050ada776d17a009.tar.gz
cpython-ea2c0016502472aa8baa3149050ada776d17a009.tar.bz2
gh-84436: Implement Immortal Objects (gh-19474)
This is the implementation of PEP683 Motivation: The PR introduces the ability to immortalize instances in CPython which bypasses reference counting. Tagging objects as immortal allows up to skip certain operations when we know that the object will be around for the entire execution of the runtime. Note that this by itself will bring a performance regression to the runtime due to the extra reference count checks. However, this brings the ability of having truly immutable objects that are useful in other contexts such as immutable data sharing between sub-interpreters.
Diffstat (limited to 'Modules/gcmodule.c')
-rw-r--r--Modules/gcmodule.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 4eaa549..1d00fc3 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -418,8 +418,20 @@ validate_list(PyGC_Head *head, enum flagstates flags)
static void
update_refs(PyGC_Head *containers)
{
+ PyGC_Head *next;
PyGC_Head *gc = GC_NEXT(containers);
- for (; gc != containers; gc = GC_NEXT(gc)) {
+
+ while (gc != containers) {
+ next = GC_NEXT(gc);
+ /* Move any object that might have become immortal to the
+ * permanent generation as the reference count is not accurately
+ * reflecting the actual number of live references to this object
+ */
+ if (_Py_IsImmortal(FROM_GC(gc))) {
+ gc_list_move(gc, &get_gc_state()->permanent_generation.head);
+ gc = next;
+ continue;
+ }
gc_reset_refs(gc, Py_REFCNT(FROM_GC(gc)));
/* Python's cyclic gc should never see an incoming refcount
* of 0: if something decref'ed to 0, it should have been
@@ -440,6 +452,7 @@ update_refs(PyGC_Head *containers)
* check instead of an assert?
*/
_PyObject_ASSERT(FROM_GC(gc), gc_get_refs(gc) != 0);
+ gc = next;
}
}