From 19d64f005c46b67716424546ffb9dee21c08eeea Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Thu, 21 Nov 2024 20:20:46 +0100 Subject: [PATCH 01/10] Remove check on small ints in long_dealloc --- Objects/longobject.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 4aa35685b509f2..c2de34d09e6af3 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3614,20 +3614,10 @@ long_richcompare(PyObject *self, PyObject *other, int op) static void long_dealloc(PyObject *self) { - /* This should never get called, but we also don't want to SEGV if - * we accidentally decref small Ints out of existence. Instead, - * since small Ints are immortal, re-set the reference count. - */ PyLongObject *pylong = (PyLongObject*)self; - if (pylong && _PyLong_IsCompact(pylong)) { - stwodigits ival = medium_value(pylong); - if (IS_SMALL_INT(ival)) { - PyLongObject *small_pylong = (PyLongObject *)get_small_int((sdigit)ival); - if (pylong == small_pylong) { - _Py_SetImmortal(self); - return; - } - } + if (_PyLong_IsCompact(pylong)) { + // assert the small ints are not deallocated + assert (!(PyLong_CheckExact(self) && IS_SMALL_INT(medium_value(pylong)))); } Py_TYPE(self)->tp_free(self); } From 4117c549dc250a1ea23408145f5190b08856e6ac Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 22 Nov 2024 08:56:04 +0100 Subject: [PATCH 02/10] rewrite assert --- Objects/longobject.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index c2de34d09e6af3..9f8024fe95e45d 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3611,14 +3611,26 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } +static int _is_python_smallint(PyObject *op) +{ + PyLongObject *pylong = (PyLongObject*)op; + if (pylong && _PyLong_IsCompact(pylong)) { + stwodigits ival = medium_value(pylong); + if (IS_SMALL_INT(ival)) { + PyLongObject *small_pylong = (PyLongObject *)get_small_int((sdigit)ival); + if (pylong == small_pylong) { + return 1; + } + } + } + return 0; +} + static void long_dealloc(PyObject *self) { - PyLongObject *pylong = (PyLongObject*)self; - if (_PyLong_IsCompact(pylong)) { - // assert the small ints are not deallocated - assert (!(PyLong_CheckExact(self) && IS_SMALL_INT(medium_value(pylong)))); - } + // assert the small ints are not deallocated + assert(!_is_python_smallint(self)); Py_TYPE(self)->tp_free(self); } From 38862e3c1639ad4179efa94e39e4c27c3f806303 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 22 Nov 2024 07:58:05 +0000 Subject: [PATCH 03/10] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst new file mode 100644 index 00000000000000..45bcb0ac6fe7c6 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst @@ -0,0 +1 @@ +Remove redundant check on small ints in ``long_dealloc`` From d8c318d9251cf3f0f277df3b3af2fb49ec699c84 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 22 Nov 2024 16:03:58 +0100 Subject: [PATCH 04/10] avoid warnings in release builds by using Py_DEBUG --- Objects/longobject.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Objects/longobject.c b/Objects/longobject.c index 9f8024fe95e45d..1eae6324ce9d6b 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3611,6 +3611,8 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } + +#ifdef Py_DEBUG static int _is_python_smallint(PyObject *op) { PyLongObject *pylong = (PyLongObject*)op; @@ -3625,6 +3627,7 @@ static int _is_python_smallint(PyObject *op) } return 0; } +#endif static void long_dealloc(PyObject *self) From 0cd1eba8255f2a7d369358c027001b4987d3b96d Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 22 Nov 2024 16:04:27 +0100 Subject: [PATCH 05/10] Update Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst Co-authored-by: Peter Bierma --- .../2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst index 45bcb0ac6fe7c6..68b8b1d37cffc1 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-22-07-58-00.gh-issue-127119.p9Yv4U.rst @@ -1 +1 @@ -Remove redundant check on small ints in ``long_dealloc`` +Slightly optimize the :class:`int` deallocator by removing a redundant check. From 2c23541dc33e9177373543212b43c40780581ecc Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 22 Nov 2024 16:51:17 +0100 Subject: [PATCH 06/10] use NDEBUG --- Objects/longobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 1eae6324ce9d6b..88af6613d5c371 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3612,7 +3612,7 @@ long_richcompare(PyObject *self, PyObject *other, int op) } -#ifdef Py_DEBUG +#ifndef NDEBUG static int _is_python_smallint(PyObject *op) { PyLongObject *pylong = (PyLongObject*)op; From ea17aee7abcdd2c6996a5fad42a1493c3b43af74 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 22 Nov 2024 16:53:25 +0100 Subject: [PATCH 07/10] whitespace --- Objects/longobject.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 88af6613d5c371..369d580b5ff581 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3611,7 +3611,6 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } - #ifndef NDEBUG static int _is_python_smallint(PyObject *op) { From 08376995b468ecaa8c85965cef0af11c9f82828b Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sun, 24 Nov 2024 21:10:33 +0100 Subject: [PATCH 08/10] keep check in stable ABI build --- Objects/longobject.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 369d580b5ff581..54680a39d3ede0 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3611,28 +3611,29 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } -#ifndef NDEBUG -static int _is_python_smallint(PyObject *op) +long_dealloc(PyObject *self) { - PyLongObject *pylong = (PyLongObject*)op; +#ifdef Py_LIMITED_API +#ifndef Py_GIL_DISABLED + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref small Ints out of existence. Instead, + * since small Ints are immortal, re-set the reference count. + * + * See PEP 683, section Accidental De-Immortalizing for details + */ + PyLongObject *pylong = (PyLongObject*)self; if (pylong && _PyLong_IsCompact(pylong)) { stwodigits ival = medium_value(pylong); if (IS_SMALL_INT(ival)) { PyLongObject *small_pylong = (PyLongObject *)get_small_int((sdigit)ival); if (pylong == small_pylong) { - return 1; + _Py_SetImmortal(self); + return; } } } - return 0; -} #endif - -static void -long_dealloc(PyObject *self) -{ - // assert the small ints are not deallocated - assert(!_is_python_smallint(self)); +#endif Py_TYPE(self)->tp_free(self); } From 076424198edf06dacc4e8eb68a23f2da500f1a78 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sun, 24 Nov 2024 21:13:50 +0100 Subject: [PATCH 09/10] typo --- Objects/longobject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Objects/longobject.c b/Objects/longobject.c index 54680a39d3ede0..ce1b25c5d434b4 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3611,6 +3611,7 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } +static void long_dealloc(PyObject *self) { #ifdef Py_LIMITED_API From 56f41330dda8283d53b9de9fa04c68371eac2071 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Mon, 25 Nov 2024 11:53:25 +0100 Subject: [PATCH 10/10] review comments --- Objects/longobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index ce1b25c5d434b4..469937a3cfb2ce 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3614,7 +3614,7 @@ long_richcompare(PyObject *self, PyObject *other, int op) static void long_dealloc(PyObject *self) { -#ifdef Py_LIMITED_API +#if SIZEOF_VOID_P <= 4 /* same condition as in refcount.h */ #ifndef Py_GIL_DISABLED /* This should never get called, but we also don't want to SEGV if * we accidentally decref small Ints out of existence. Instead,