Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-37483: add _PyObject_CallOneArg() function #14558

Merged
merged 1 commit into from
Jul 4, 2019

Conversation

jdemeyer
Copy link
Contributor

@jdemeyer jdemeyer commented Jul 2, 2019

Copy link
Contributor

@aeros aeros left a comment

Choose a reason for hiding this comment

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

@jdemeyer On lines 145 and 146 of abstract.h:
return _PyObject_Vectorcall(func, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);

What is the purpose of using the constant PY_VECTORCALL_ARGUMENTS_OFFSET in a function that is made specifically for single arguments? Unless I am misunderstanding something, return _PyObject_Vectorcall(func, args, 1, NULL); would effectively have the same functionality. Is there any circumstance where this function is used and 1 | PY_VECTORCALL_ARGUMENTS_OFFSET does not result in 1?

@jdemeyer
Copy link
Contributor Author

jdemeyer commented Jul 3, 2019

What is the purpose of using the constant PY_VECTORCALL_ARGUMENTS_OFFSET in a function that is made specifically for single arguments?

It's meant for optimizing calls to bound methods. If you're calling a bound method with 1 argument, you're effectively calling a function with 2 arguments when you add self. So args[-1] is meant to store self. See https://www.python.org/dev/peps/pep-0590/#py-vectorcall-arguments-offset

Modules/_testbuffer.c Outdated Show resolved Hide resolved
Modules/_xxsubinterpretersmodule.c Outdated Show resolved Hide resolved
Modules/_decimal/_decimal.c Outdated Show resolved Hide resolved
@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@aeros
Copy link
Contributor

aeros commented Jul 4, 2019

@jdemeyer Wouldn't 1 | PY_VECTORCALL_ARGUMENTS_OFFSET always resolve to the same value in the case of this function though? The primary use for it seems to be calculating the offset when the number of args is unknown:
nargs | PY_VECTORCALL_ARGUMENTS_OFFSET

or for the example provided in PEP 590:
nargs & PY_VECTORCALL_ARGUMENTS_OFFSET

What is the purpose of using PY_VECTORCALL_ARGUMENTS_OFFSET when the the number of arguments for the function is static? As far as I can tell, the result of 1 | PY_VECTORCALL_ARGUMENTS_OFFSET will always be 1 any time _PyObject_CallOneArg() is utilized. Is this incorrect?

Also, apologies for the questions if these answers are fairly obvious. I have some understanding of C fundamentals, but I'm significantly more experienced with Python. I'm just trying to get a solid understanding of both so that I can be more useful as a contributor.

@jdemeyer
Copy link
Contributor Author

jdemeyer commented Jul 4, 2019

I have made the requested changes; please review again

@bedevere-bot
Copy link

Thanks for making the requested changes!

@skrah, @methane: please review the changes made to this pull request.

@jdemeyer
Copy link
Contributor Author

jdemeyer commented Jul 4, 2019

Wouldn't 1 | PY_VECTORCALL_ARGUMENTS_OFFSET always resolve to the same value in the case of this function though?

PY_VECTORCALL_ARGUMENTS_OFFSET is a constant flag, so of course 1 | PY_VECTORCALL_ARGUMENTS_OFFSET is a constant value. But that's not the point.

The PY_VECTORCALL_ARGUMENTS_OFFSET flag is meant for the called function. It indicates that the value args[-1] may temporarily be changed as scratch space. That's the reason for the array _args of length two in this PR: _args[0] is the same as args[-1] which can be used as scratch space by the called function.

@aeros
Copy link
Contributor

aeros commented Jul 4, 2019

@jdemeyer Oh that makes sense, I see. I hadn't realized the purpose of it within this function was solely to be an indicating flag, in general I'm far more used to working on much smaller scale projects and codebases where almost everything has a specific functional purpose. Seeing the two constant values being used for the nargs argument of PyObject_Vectorcall had seemed redundant to me initially, but now I understand the reasoning.

Thank you for taking the time to fully explain it, I certainly appreciate it.

@skrah
Copy link
Contributor

skrah commented Jul 4, 2019

Thanks for the changes, the "approval" was a GitHub thing, I'm actually -0 on such large replacement PRs.

@jdemeyer
Copy link
Contributor Author

jdemeyer commented Jul 4, 2019

It's not doing replacement for the sake of replacement. As I explained on bpo-37483, it gives a nice performance gain (in terms of runtime and stack usage).

@methane methane merged commit 196a530 into python:master Jul 4, 2019
@bedevere-bot
Copy link

@methane: Please replace # with GH- in the commit message next time. Thanks!

@skrah
Copy link
Contributor

skrah commented Jul 4, 2019

I mean large replacement. Note that I did not protest against the changes in memoryobject.c.

@jdemeyer jdemeyer deleted the call_one_arg branch July 4, 2019 10:47
lisroach pushed a commit to lisroach/cpython that referenced this pull request Sep 10, 2019
DinoV pushed a commit to DinoV/cpython that referenced this pull request Jan 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants