beyond the refcount limit. Immortality checks for reference count decreases will
be done by checking the bit sign flag in the lower 32 bits.
+To ensure that once an object becomes immortal, it remains immortal, the threshold
+for omitting increfs is much higher than for omitting decrefs. Consequently, once
+the refcount for an object exceeds _Py_IMMORTAL_MINIMUM_REFCNT it will gradually
+increase over time until it reaches _Py_IMMORTAL_INITIAL_REFCNT.
*/
#define _Py_IMMORTAL_INITIAL_REFCNT (3ULL << 30)
#define _Py_IMMORTAL_MINIMUM_REFCNT (1ULL << 31)
}
#elif SIZEOF_VOID_P > 4
PY_UINT32_T cur_refcnt = op->ob_refcnt;
- if (((int32_t)cur_refcnt) < 0) {
+ if (cur_refcnt >= _Py_IMMORTAL_INITIAL_REFCNT) {
// the object is immortal
_Py_INCREF_IMMORTAL_STAT_INC();
return;
"""
from test import support
-from test.support import bigmemtest, _1G, _2G, _4G
+from test.support import bigmemtest, _1G, _2G, _4G, import_helper
+_testcapi = import_helper.import_module('_testcapi')
import unittest
import operator
d[size] = 1
+class ImmortalityTest(unittest.TestCase):
+
+ @bigmemtest(size=_2G, memuse=pointer_size * 9/8)
+ def test_stickiness(self, size):
+ """Check that immortality is "sticky", so that
+ once an object is immortal it remains so."""
+ if size < _2G:
+ # Not enough memory to cause immortality on overflow
+ return
+ o1 = o2 = o3 = o4 = o5 = o6 = o7 = o8 = object()
+ l = [o1] * (size-20)
+ self.assertFalse(_testcapi.is_immortal(o1))
+ for _ in range(30):
+ l.append(l[0])
+ self.assertTrue(_testcapi.is_immortal(o1))
+ del o2, o3, o4, o5, o6, o7, o8
+ self.assertTrue(_testcapi.is_immortal(o1))
+ del l
+ self.assertTrue(_testcapi.is_immortal(o1))
+
+
if __name__ == '__main__':
if len(sys.argv) > 1:
support.set_memlimit(sys.argv[1])