On Thu, Dec 16, 2021 at 3:08 AM Petr Viktorin <encukou@gmail.com> wrote:
On 16. 12. 21 11:52, Victor Stinner wrote:
> On Thu, Dec 16, 2021 at 2:29 AM Nathaniel Smith <njs@pobox.com> wrote:
>> On Wed, Dec 15, 2021 at 3:07 AM Victor Stinner <vstinner@python.org> wrote:
>>> I wrote https://bugs.python.org/issue39511 and
>>> https://github.com/python/cpython/pull/18301 to have per-interpreter
>>> None, True and False singletons. My change is backward compatible on
>>> the C API: you can still use "Py_None" in your C code. The code gets
>>> the singleton object from the current interpreter with a function
>>> call:
>>>
>>>      #define Py_None Py_GetNone()
>>>
>>> Py_GetNone() is implemented as: "return _PyInterpreterState_GET()->none;"
>>
>> It's backward compatible for the C API, but not for the stable C ABI
>> -- that exports Py_None directly as a symbol.
>
> You're right. But we can add a macro like Py_SUBINTERPRETER_API which
> would change the implementation:
>
> * By default, "Py_None" would continue returning "&_Py_NoneStruct".
> * If Py_SUBINTERPRETER_API macro is defined, Py_None would call Py_GetNone().
>
> => no impact on the stable ABI (if used, the stable ABI is not supported)

The stable ABI could be orthogonal here -- you could compile for the
stable ABI even with Py_SUBINTERPRETER_API.

This would require (_PyInterpreterState_GET()->none == Py_None) in the
"main" interpreter, and extrensions without Py_SUBINTERPRETER_API only
loadable in the "main" interpreter.

That would slow things down a bit -- even if the pointer to the interpreter state was already in a register, getting None would require loading the pointer to Py_None from memory by indexing relative to that register. Compared to a plain global, the latter would be a "load constant" instruction, and Eric's other proposal (move the Py_None struct itself into the interpreter state) would be just adding a constant to the register (possibly the fastest solution, since that constant would be much smaller than the full address of the global). Alas, that last version is not compatible with the stable ABI. So I'm still in favor of trying harder to make immortable objects a reality.

--
--Guido van Rossum (python.org/~guido)