Skip to content

Commit 2a08194

Browse files
committed
Add test
1 parent b1e2a33 commit 2a08194

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

Include/refcount.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ having all the lower 32 bits set, which will avoid the reference count to go
4141
beyond the refcount limit. Immortality checks for reference count decreases will
4242
be done by checking the bit sign flag in the lower 32 bits.
4343
44+
To ensure that once an object becomes immortal, it remains immortal, the threshold
45+
for omitting increfs is much higher than for omitting decrefs. Consequently, once
46+
the refcount for an object exceeds _Py_IMMORTAL_MINIMUM_REFCNT it will gradually
47+
increase over time until it reaches _Py_IMMORTAL_INITIAL_REFCNT.
4448
*/
4549
#define _Py_IMMORTAL_INITIAL_REFCNT (3UL << 30)
4650
#define _Py_STATIC_FLAG_BITS ((Py_ssize_t)(_Py_STATICALLY_ALLOCATED_FLAG | _Py_IMMORTAL_FLAGS))
@@ -287,7 +291,7 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
287291
}
288292
#elif SIZEOF_VOID_P > 4
289293
PY_UINT32_T cur_refcnt = op->ob_refcnt;
290-
if (cur_refcnt >= _Py_IMMORTAL_INITIAL_REFCNT) < 0) {
294+
if (cur_refcnt >= _Py_IMMORTAL_INITIAL_REFCNT) {
291295
// the object is immortal
292296
_Py_INCREF_IMMORTAL_STAT_INC();
293297
return;

Lib/test/test_bigmem.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"""
1010

1111
from test import support
12-
from test.support import bigmemtest, _1G, _2G, _4G
12+
from test.support import bigmemtest, _1G, _2G, _4G, import_helper
13+
_testcapi = import_helper.import_module('_testcapi')
1314

1415
import unittest
1516
import operator
@@ -1257,6 +1258,24 @@ def test_dict(self, size):
12571258
d[size] = 1
12581259

12591260

1261+
class ImmortalityTest(unittest.TestCase):
1262+
1263+
@bigmemtest(size=_2G, memuse=pointer_size * 9/8)
1264+
def test_stickiness(self, size):
1265+
"""Check that immortality is "sticky", so that
1266+
once an object is immortal it remains so."""
1267+
o1 = o2 = o3 = o4 = o5 = o6 = o7 = o8 = object()
1268+
l = [o1] * (size-20)
1269+
self.assertFalse(_testcapi.is_immortal(o1))
1270+
for _ in range(30):
1271+
l.append(l[0])
1272+
self.assertTrue(_testcapi.is_immortal(o1))
1273+
del o2, o3, o4, o5, o6, o7, o8
1274+
self.assertTrue(_testcapi.is_immortal(o1))
1275+
del l
1276+
self.assertTrue(_testcapi.is_immortal(o1))
1277+
1278+
12601279
if __name__ == '__main__':
12611280
if len(sys.argv) > 1:
12621281
support.set_memlimit(sys.argv[1])

0 commit comments

Comments
 (0)