Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

PEP 590: A new calling convention for CPython#960

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged

Conversation

@markshannon
Copy link
Member

No description provided.

Copy link
Member

@brettcannonbrettcannon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

There's some reST-related change that should probably be made before this gets committed.

pep-0590.rst Outdated
Abstract
========

This PEP introduces a new calling convention [1] for use by CPython and other software and tools in the CPython ecosystem.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
This PEP introduces a new calling convention [1] for use by CPython and other software and tools in the CPython ecosystem.
This PEP introduces a new calling convention [1]_ for use by CPython and other software and tools in the CPython ecosystem.

pep-0590.rst Outdated
The choice of a calling convention impacts the performance and flexibility of code on either side of the call.
Often there is tension between performance and flexibility.

The current ``tp_call`` [2] calling convention is sufficiently flexible to cover all cases, but its performance is poor.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
The current ``tp_call`` [2] calling convention is sufficiently flexible to cover all cases, but its performance is poor.
The current ``tp_call`` [2]_ calling convention is sufficiently flexible to cover all cases, but its performance is poor.

pep-0590.rst Outdated

The current ``tp_call`` [2] calling convention is sufficiently flexible to cover all cases, but its performance is poor.
The poor performance is largely a result of having to create intermediate tuples, and possibly intermediate dicts, during the call.
This is mitigated in CPython by including special case code to speed up calls to Python and builtin functions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
This is mitigated in CPython by including specialcase code to speed up calls to Python and builtin functions.
This is mitigated in CPython by including special-case code to speed up calls to Python and builtin functions.

pep-0590.rst Outdated
-------------------------

Calls are made through a function pointer taking the following parameters:
* ``PyObject *callable`` The called object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

You could make this adefinition list. Otherwise I would suggest a colon to help visibly separate the definition from the explanation, e.g.:

Suggested change
* ``PyObject *callable`` The called object
* ``PyObject *callable``: The called object

pep-0590.rst Outdated
Additional flags
----------------

Currently only one flags is specified.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
Currently only oneflags is specified.
Currently only oneflag is specified: ``PY_METHOD_DESCRIPTOR``.

pep-0590.rst Outdated
Calls ``args[0]`` with the remaining arguments.
Note that ``nargs`` is the number of positional arguments, including the callable; no offsetting is allowed.

Both functions raise an exception if `obj` is not callable.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
Both functions raise an exception if `obj` is not callable.
Both functions raise an exception if ``obj`` is not callable.

pep-0590.rst Outdated
These functions are ``PyObject *``PyCall_MakeVectorCall(PyObject *obj, PyObject *tuple, PyObject **dict);`` and
``PyObject *PyCall_MakeTpCall(PyObject *obj, PyObject **args, Py_ssize_t nargs, PyTupleObject *kwnames);``, respectively.

Both functions raise an exception if `obj` does not support the relevant protocol.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
Both functions raise an exception if `obj` does not support the relevant protocol.
Both functions raise an exception if ``obj`` does not support the relevant protocol.

pep-0590.rst Outdated

Both functions raise an exception if `obj` does not support the relevant protocol.

METH_FASTCALL and METH_VECTORCALL flags
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
METH_FASTCALL and METH_VECTORCALL flags
``METH_FASTCALL`` and``METH_VECTORCALL`` flags

pep-0590.rst Outdated
The `MethodDef` protocol and Argument Clinic
============================================

Argument Clinic [4] automatically generates wrapper functions around lower-level callables, providing safe unboxing of primitive types and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
Argument Clinic [4] automatically generates wrapper functions around lower-level callables, providing safe unboxing of primitive types and
Argument Clinic [4]_ automatically generates wrapper functions around lower-level callables, providing safe unboxing of primitive types and

@jdemeyer
Copy link
Contributor

The statementPEP 580 is specifically targetted at function-like objects, and doesn't support other callables like classes, partial functions, or proxies is factually false. The motivation for PEP 580 is certainly function/method-like objects but it's a general protocol that every class can implement. For certain classes, it may not be easy or desirable to do that but it's always possible.

@jdemeyer
Copy link
Contributor

Given thatPY_METHOD_DESCRIPTOR is a flag fortp_flags, shouldn't it be calledPy_TPFLAGS_METHOD_DESCRIPTOR or something?

Copy link
Member

@brettcannonbrettcannon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

From a PEP editor POV, this LGTM. I will let Mark handle the merge himself.

-------------------------

A longer, 6 argument, form combining both the vector and optional tuple and dictionary arguments was considered.
However, it was found that the code to convert between it and the old `tp_call` form was overly cumbersome and inefficient.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
However, it was found that the code to convert between it and the old `tp_call` form was overly cumbersome and inefficient.
However, it was found that the code to convert between it and the old ``tp_call`` form was overly cumbersome and inefficient.

However, it was found that the code to convert between it and the old `tp_call` form was overly cumbersome and inefficient.
Also, since only 4 arguments are passed in registers on x64 Windows, the two extra arguments would have non-neglible costs.

Removing any special cases and making all calls use the `tp_call` form was also considered.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
Removing any special cases and making all calls use the `tp_call` form was also considered.
Removing any special cases and making all calls use the ``tp_call`` form was also considered.

@jdemeyer
Copy link
Contributor

I don't really see the point ofPyCall_MakeTpCall: it seems to do exactly the same thing asPyObject_VectorCallWithCallable. I don't think that the caller should care which protocol is used:PyObject_VectorCallWithCallable should use the vectorcall protocol if available and fall back totp_call otherwise.

@jdemeyer
Copy link
Contributor

I still find the explanation ofPY_VECTORCALL_ARGUMENTS_OFFSET a bit unclear. Maybe a better way to explain it would be:

If the flagPY_VECTORCALL_ARGUMENTS_OFFSET is used, then the callee is free to write toargs[-1]. This is used for example by bound methods to make their onward calls cheaply. Whenever they can do so cheaply (without allocation), callers are encouraged to offset the arguments.

``METH_FASTCALL`` and ``METH_VECTORCALL`` flags
-----------------------------------------------

A new ``METH_VECTORCALL`` flag is added for specifying ``MethodDef`` structs. It is equivalent to the currently undocumented ``METH_FASTCALL | METH_KEYWORD`` flag.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Typo:MethodDef ->PyMethodDef

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
A new ``METH_VECTORCALL`` flag is added for specifying ``MethodDef`` structs. It is equivalent to the currently undocumented ``METH_FASTCALL | METH_KEYWORD`` flag.
A new ``METH_VECTORCALL`` flag is added for specifying ``PyMethodDef`` structs. It is equivalent to the currently undocumented ``METH_FASTCALL | METH_KEYWORD`` flag.

-------------------------------

The a new slot called ``tp_vectorcall_offset`` is added. It has the type ``uint32_t``.
A new flag is added, ``Py_TPFLAGS_HAVE_VECTOR_CALL``, which is set for any new PyTypeObjects that include the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Py_TPFLAGS_HAVE_VECTOR_CALL ->Py_TPFLAGS_HAVE_VECTORCALL to be consistent withtp_vectorcall_offset and other uses of "vectorcall" (not "vector call")

@jdemeyer
Copy link
Contributor

You write about using the vectorcall protocol in classes, as if that's a trivial thing to do. I'm not saying that it's impossible, but extending the vectorcall protocol (or the PEP 580 C call protocol) totype requires some more thought. Personally, I would rather leave that for a follow-up PEP.

Any class the sets ``tp_vectorcall`` to non-zero should also implement the ``tp_call`` function and make sure its behaviour is consistent with the ``vectorcall`` function.
Setting ``tp_call`` to ``PyCall_MakeVectorCall`` will suffice.

The `MethodDef` protocol and Argument Clinic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

MethodDef ->PyMethodDef

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
The `MethodDef` protocol and Argument Clinic
The ``PyMethodDef`` protocol and Argument Clinic

@encukou
Copy link
Member

Mark, I assume you'll be OK with me doing typo/syntax fixes. I'll get to do them and merge this later today, so we have something concrete to talk about.

Jeroen, thank you for the reviews! But please save discussion for the mailing lists – this particular PR is for publishing the initial version of the PEP.

@jdemeyer
Copy link
Contributor

And please also remove the last part about PEP 580 (see#960 (comment)). I don't think it's fair to write that in a PEP.

@encukou
Copy link
Member

And please also remove the last part about PEP 580 (see#960 (comment)). I don't think it's fair to write that in a PEP.

It's not, and it definitely won't go in an accepted PEP, but I'm not doing that kind of editing here.
Please take it as a misunderstanding which Mark didn't yet have time to clear up.

``METH_FASTCALL`` and ``METH_VECTORCALL`` flags
-----------------------------------------------

A new ``METH_VECTORCALL`` flag is added for specifying ``MethodDef`` structs. It is equivalent to the currently undocumented ``METH_FASTCALL | METH_KEYWORD`` flag.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
A new ``METH_VECTORCALL`` flag is added for specifying ``MethodDef`` structs. It is equivalent to the currently undocumented ``METH_FASTCALL | METH_KEYWORD`` flag.
A new ``METH_VECTORCALL`` flag is added for specifying ``PyMethodDef`` structs. It is equivalent to the currently undocumented ``METH_FASTCALL | METH_KEYWORD`` flag.

Any class the sets ``tp_vectorcall`` to non-zero should also implement the ``tp_call`` function and make sure its behaviour is consistent with the ``vectorcall`` function.
Setting ``tp_call`` to ``PyCall_MakeVectorCall`` will suffice.

The `MethodDef` protocol and Argument Clinic
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
The `MethodDef` protocol and Argument Clinic
The ``PyMethodDef`` protocol and Argument Clinic


To enable call performance on a par with Python functions and built-in functions, third-party callables should include a ``vectorcall`` function pointer
and set ``tp_vectorcall`` to the correct value.
Any class the sets ``tp_vectorcall`` to non-zero should also implement the ``tp_call`` function and make sure its behaviour is consistent with the ``vectorcall`` function.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
Any classthe sets ``tp_vectorcall`` to non-zero should also implement the ``tp_call`` function and make sure its behaviour is consistent with the ``vectorcall`` function.
Any classthat sets ``tp_vectorcall`` to non-zero should also implement the ``tp_call`` function and make sure its behaviour is consistent with the ``vectorcall`` function.

The underlying calling convention is similar. Because PEP 576 only allows a fixed offset for the function pointer,
it would not allow the improvements to any objects with constraints on their layout.

PEP 580 proposes a major change to the `MethodDef` protocol used to define builtin functions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
PEP 580 proposes a major change to the `MethodDef` protocol used to define builtin functions.
PEP 580 proposes a major change to the ``MethodDef`` protocol used to define builtin functions.


PEP 580 proposes a major change to the `MethodDef` protocol used to define builtin functions.
This PEP provides a more general and simpler mechanism in the form of a new calling convention.
This PEP also extends the `MethodDef` protocol, but merely to formalise existing conventions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
This PEP also extends the `MethodDef` protocol, but merely to formalise existing conventions.
This PEP also extends the ``MethodDef`` protocol, but merely to formalise existing conventions.

@encukou
Copy link
Member

Ah, my bad. I won't be merging this, as I'm not a PEP Editor.

@gvanrossum
Copy link
Member

gvanrossum commentedApr 2, 2019 via email

Is it ready to merge? Because I am a pep editor and I can merge it for you.Just give the word.
On Tue, Apr 2, 2019 at 5:00 AM Petr Viktorin ***@***.***> wrote: Ah, my bad. I won't be merging this, as I'm not a PEP Editor. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#960 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/ACwrMgiCDTGeS2mrPP2Kxkgc2958f6oUks5vc0ZDgaJpZM4cSk65> .
-- --Guido (mobile)

@encukou
Copy link
Member

encukou commentedApr 3, 2019
edited
Loading

Is it ready to merge? Because I am a pep editor and I can merge it for you.

Thank you! It is ready for initial discussion, but it needs some editing – committing the syntax fix suggestions, then checking if the build is clean, and merging them.
If you want to do that, it would be great.

@markshannon, ifyou could commit the suggestions, it would be even better :)

@jdemeyer
Copy link
Contributor

One detail which would be good to mention: whenever thevectorcall pointer (at offsettp_vectorcall_offset in the structure) isNULL in a particular instance, then the vectorcall protocol is not used in that instance. This makes it easy for classes to implement the new protocol only for certain instances.

This contrasts with PEP 580: the C call protocol is all-or-nothing. If a class supports the C call protocol, every instance must use it.

A new flag is added, ``Py_TPFLAGS_HAVE_VECTOR_CALL``, which is set for any new PyTypeObjects that include the
``tp_vectorcall_offset`` member.

If ``Py_TPFLAGS_HAS_VECTORCALL`` is set then ``tp_vectorcall_offset`` is the offset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Py_TPFLAGS_HAS_VECTORCALL ->Py_TPFLAGS_HAVE_VECTORCALL

--------

The call takes the form ``((vectorcall)(((char *)o)+offset))(o, n, args, kwnames)`` where
``offset`` is ``TYPE(o)->tp_vectorcall``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

tp_vectorcall ->tp_vectorcall_offset

------------------------------------------------------------------

To enable call performance on a par with Python functions and built-in functions, third-party callables should include a ``vectorcall`` function pointer
and set ``tp_vectorcall`` to the correct value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

tp_vectorcall ->tp_vectorcall_offset

@gvanrossumgvanrossum merged commit7a4c496 intopython:masterApr 3, 2019
@gvanrossum
Copy link
Member

Thank you! It is ready for initial discussion, but it needs some editing – committing the syntax fix suggestions, then checking if the build is clean, and merging them.
If you want to do that, it would be great.

I didn't have time to make any edits, but I merged this, so it's public now.

@markshannon, if you could commit the suggestions, it would be even better :)

Please make a new PR for that. (@jdemeyer or you could send a PR and once Mark approves it can be merged -- IIRC Mark can merge peps PRs too.)

@jdemeyer
Copy link
Contributor

Great, thanks!

I'll make a PR with the various edits.

@markshannonmarkshannon deleted the new-calling-convention branchMarch 23, 2022 11:41
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@encukouencukouencukou left review comments

@jdemeyerjdemeyerjdemeyer left review comments

@brettcannonbrettcannonbrettcannon approved these changes

Assignees

No one assigned

Labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

6 participants

@markshannon@jdemeyer@encukou@gvanrossum@brettcannon@the-knights-who-say-ni

[8]ページ先頭

©2009-2025 Movatter.jp