From 82212b36ad95b48792f22de6785a92c96920d454 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Mon, 16 Feb 2026 19:13:23 +0100 Subject: [PATCH 1/9] Improve performance in specialize_dict_access_hint() via adding specialization for PY_GIL_DISABLED --- Python/specialize.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Python/specialize.c b/Python/specialize.c index 5ba016f83ea077..4407cb39a12910 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -644,7 +644,12 @@ specialize_dict_access_hint( SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_SPLIT_DICT); return 0; } +#ifdef Py_GIL_DISABLED + PyObject *value; + Py_ssize_t index = _PyDict_LookupIndexAndValue((PyDictObject *)globals, name, &value); +#else Py_ssize_t index = _PyDict_LookupIndex(dict, name); +#endif if (index != (uint16_t)index) { SPECIALIZATION_FAIL(base_op, index == DKIX_EMPTY ? @@ -652,6 +657,9 @@ specialize_dict_access_hint( SPEC_FAIL_OUT_OF_RANGE); return 0; } +#ifdef Py_GIL_DISABLED + maybe_enable_deferred_ref_count(value); +#endif cache->index = (uint16_t)index; write_u32(cache->version, tp_version); specialize(instr, hint_op); From 613135ac9a1e88f1cfa8bfa28c93415da9e7a109 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 16 Feb 2026 18:23:15 +0000 Subject: [PATCH 2/9] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-02-16-18-23-13.gh-issue-132657.SeGcFx.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-18-23-13.gh-issue-132657.SeGcFx.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-18-23-13.gh-issue-132657.SeGcFx.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-18-23-13.gh-issue-132657.SeGcFx.rst new file mode 100644 index 00000000000000..e2107f599b4cf1 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-16-18-23-13.gh-issue-132657.SeGcFx.rst @@ -0,0 +1,2 @@ +In the free-threaded build, dictionary access hint specializations now attempt to enable deferred reference counting for resolved values owned by a different thread, reducing cross-thread reference count traffic and improving multi-threaded scalability. +Patch by Benedikt Johannes. From f79e41a221edf87a4ea5b8c2c810f7ff0d722998 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Mon, 16 Feb 2026 19:24:44 +0100 Subject: [PATCH 3/9] Update specialize.c --- Python/specialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/specialize.c b/Python/specialize.c index 4407cb39a12910..b0fe32d3100a86 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -646,7 +646,7 @@ specialize_dict_access_hint( } #ifdef Py_GIL_DISABLED PyObject *value; - Py_ssize_t index = _PyDict_LookupIndexAndValue((PyDictObject *)globals, name, &value); + Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value); #else Py_ssize_t index = _PyDict_LookupIndex(dict, name); #endif From 0c1e7e11ea1af572b73bf86d43aa3d7b3b09d7c6 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Mon, 16 Feb 2026 19:56:16 +0100 Subject: [PATCH 4/9] Update specialize.c --- Python/specialize.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Python/specialize.c b/Python/specialize.c index b0fe32d3100a86..1d4aa55499b26d 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -644,12 +644,12 @@ specialize_dict_access_hint( SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_SPLIT_DICT); return 0; } -#ifdef Py_GIL_DISABLED PyObject *value; Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value); -#else - Py_ssize_t index = _PyDict_LookupIndex(dict, name); -#endif + if (value != NULL && PyLazyImport_CheckExact(value)) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); + return -1; + } if (index != (uint16_t)index) { SPECIALIZATION_FAIL(base_op, index == DKIX_EMPTY ? From af7160b5d3537e46572a95f016e0ceb4579b9857 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Mon, 16 Feb 2026 20:23:27 +0100 Subject: [PATCH 5/9] Update specialize.c --- Python/specialize.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/specialize.c b/Python/specialize.c index 1d4aa55499b26d..5d0bdb9fb83f2f 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -647,8 +647,8 @@ specialize_dict_access_hint( PyObject *value; Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value); if (value != NULL && PyLazyImport_CheckExact(value)) { - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); - return -1; + SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); + return 0; } if (index != (uint16_t)index) { SPECIALIZATION_FAIL(base_op, From f408c6736a53055a66d5e07e6217cee686642813 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Thu, 19 Feb 2026 12:02:21 +0100 Subject: [PATCH 6/9] Update specialize.c --- Python/specialize.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Python/specialize.c b/Python/specialize.c index 5d0bdb9fb83f2f..f730b386f9f816 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -383,12 +383,16 @@ specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, P SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_STRING); return -1; } +#ifdef Py_GIL_DISABLED PyObject *value; Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value); if (value != NULL && PyLazyImport_CheckExact(value)) { SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); return -1; } +#else + Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name); +#endif assert(index != DKIX_ERROR); if (index != (uint16_t)index) { SPECIALIZATION_FAIL(LOAD_ATTR, From 143dd0f2aff4237dde7dd399c2895b3c462076b7 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Thu, 19 Feb 2026 12:05:22 +0100 Subject: [PATCH 7/9] Update specialize.c --- Python/specialize.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Python/specialize.c b/Python/specialize.c index f730b386f9f816..5d0bdb9fb83f2f 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -383,16 +383,12 @@ specialize_module_load_attr_lock_held(PyDictObject *dict, _Py_CODEUNIT *instr, P SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_STRING); return -1; } -#ifdef Py_GIL_DISABLED PyObject *value; Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value); if (value != NULL && PyLazyImport_CheckExact(value)) { SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); return -1; } -#else - Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name); -#endif assert(index != DKIX_ERROR); if (index != (uint16_t)index) { SPECIALIZATION_FAIL(LOAD_ATTR, From a12c0e1cf2c4900ecf9951ff6463ee1ab2247d35 Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Thu, 19 Feb 2026 12:07:13 +0100 Subject: [PATCH 8/9] Update specialize.c --- Python/specialize.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Python/specialize.c b/Python/specialize.c index 5d0bdb9fb83f2f..33a600c0c25c2a 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -644,12 +644,16 @@ specialize_dict_access_hint( SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_SPLIT_DICT); return 0; } +#ifdef PY_GIL_DISABLED PyObject *value; Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value); if (value != NULL && PyLazyImport_CheckExact(value)) { SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE); return 0; } +#else + Py_ssize_t index = _PyDict_LookupIndex(dict, name); +#endif if (index != (uint16_t)index) { SPECIALIZATION_FAIL(base_op, index == DKIX_EMPTY ? From a4030a90c4eb503c2c28f40953e0a77fab4aeced Mon Sep 17 00:00:00 2001 From: Benedikt Johannes Date: Thu, 19 Feb 2026 12:44:29 +0100 Subject: [PATCH 9/9] Update specialize.c --- Python/specialize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/specialize.c b/Python/specialize.c index 33a600c0c25c2a..38f9239f558628 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -644,7 +644,7 @@ specialize_dict_access_hint( SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_SPLIT_DICT); return 0; } -#ifdef PY_GIL_DISABLED +#ifdef Py_GIL_DISABLED PyObject *value; Py_ssize_t index = _PyDict_LookupIndexAndValue(dict, name, &value); if (value != NULL && PyLazyImport_CheckExact(value)) {