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. diff --git a/Python/specialize.c b/Python/specialize.c index 5ba016f83ea077..38f9239f558628 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -644,7 +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 ? @@ -652,6 +661,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);