From ea2c0016502472aa8baa3149050ada776d17a009 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Sat, 22 Apr 2023 15:39:37 -0400 Subject: 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. --- Modules/gcmodule.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'Modules/gcmodule.c') diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index 4eaa5490b6..1d00fc3e71 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; } } -- cgit v1.2.1