diff options
Diffstat (limited to 'contrib/tools/cython/Cython/Compiler/Code.py')
| -rw-r--r-- | contrib/tools/cython/Cython/Compiler/Code.py | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/contrib/tools/cython/Cython/Compiler/Code.py b/contrib/tools/cython/Cython/Compiler/Code.py index 630683bf166..ed783164ff8 100644 --- a/contrib/tools/cython/Cython/Compiler/Code.py +++ b/contrib/tools/cython/Cython/Compiler/Code.py @@ -2429,19 +2429,26 @@ class GlobalState: writer.putln("{") writer.putln(f"PyObject **table = {array_cname};") writer.putln(f"for (Py_ssize_t i=0; i<{constant_count}; ++i) {{") - writer.putln("#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING") + writer.putln("#if PY_VERSION_HEX >= 0x030F0000") + writer.putln("PyUnstable_SetImmortal(table[i]);") + writer.putln("#elif CYTHON_COMPILING_IN_CPYTHON_FREETHREADING") # We don't want to set the refcount on shared constants (e.g. cached integers) # because setting the refcount isn't thread-safe. The chances are that most of the constants # that this applies to are already immortal though so that isn't a great loss. + # Overflow, e.g. on 32 bit systems. + writer.putln("if ((PY_SSIZE_T_MAX <= _Py_IMMORTAL_REFCNT_LOCAL)) break;") writer.putln("#if PY_VERSION_HEX < 0x030E0000") writer.putln("if (_Py_IsOwnedByCurrentThread(table[i]) && Py_REFCNT(table[i]) == 1)") writer.putln("#else") writer.putln("if (PyUnstable_Object_IsUniquelyReferenced(table[i]))") writer.putln("#endif") writer.putln("{") - writer.putln("Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL);") + # Go one higher than we think we need to because of a bug in SET_REFCNT check in CPython + writer.putln("Py_SET_REFCNT(table[i], ((Py_ssize_t)_Py_IMMORTAL_REFCNT_LOCAL + 1));") writer.putln("}") writer.putln("#else") + # Overflow, e.g. on 32 bit systems. + writer.putln("if ((PY_SSIZE_T_MAX < _Py_IMMORTAL_INITIAL_REFCNT)) break;") writer.putln("Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT);") writer.putln("#endif") writer.putln("}") # for() |
