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

gh-98831: Modernize CALL and family#101508

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
gvanrossum merged 42 commits intopython:mainfromgvanrossum:call-family
Feb 8, 2023

Conversation

gvanrossum
Copy link
Member

@gvanrossumgvanrossum commentedFeb 1, 2023
edited
Loading

Note that we have a few opcodes starting withCALL_ that aren't specializations ofCALL.

@gvanrossum
Copy link
MemberAuthor

There are a few things about this family that make it unpleasant to convert.

First, the initial call stack can be either

[method, self, arg1, arg2, ...]

or

[NULL, callable, arg1, arg2, ...]

(This situation arises because theLOAD_ATTR instruction dynamically decides whether to produce one or the other.)

In the latter case we then introspectcallable and if it is a bound method, we extract theim_func andim_self fields and convert to the former format -- but if the callable is not a bound method, we leave theNULL in place.

There is a macrois_method(stack_pointer, oparg) that, despite its lofty name, really just checks whether there's aNULL at the indicated position (usingPEEK(oparg+1), it doesn't even use thestack_pointer argument). In the converted instructions I am modeling this as an input stack effect of the formthing1, thing2, args[oparg], and I replace theis_method() macro withthing1 != NULL. Everything else then gets a little awkward, because the thing we need to call in the end is eitherthing1 orthing2, and the number of arguments is eitheroparg oroparg+1. It also means that the first argument is not the start of theargs array -- it is either that or one less.

Second, most specializations don't just call the function and produce a result. Because of Python function call inlining, most end up withDISPATCH_INLINE(), and because of that we can't leave the popping of the stack to the generated code (it would just beSTACK_SHRINK(oparg+1)) -- we have to manually do this, and while we're at it we also eitherDECREF the arguments (includingself, if present), or copy them into a new frame, depending on what we're calling.

All this leaves me with the feeling that the generator isn't a good match for the complexity of this instruction family, or I am missing a trick.

Maybe I should model the input stack effect asmethod, callable, args[oparg] and do something like

if (method != NULL) {    callable = method;    args -= 1;    oparg += 1;}

so that we can always callcallable withoparg arguments starting atargs. But we still need to recall whether we did this, so we know where to push the result.

@iritkatriel
Copy link
Member

Note that you linked this with the wrong issue.

gvanrossum reacted with thumbs up emoji

@gvanrossumgvanrossum changed the titlegh-98331: Modernize CALL and familygh-98831: Modernize CALL and familyFeb 2, 2023
@gvanrossum
Copy link
MemberAuthor

gvanrossum commentedFeb 2, 2023
edited
Loading

@brandtbucher,@markshannon, any suggestions? (This is not all, I just would like some feedback on how to proceed with the remaining 12-odd specializations ofCALL.)

@markshannon
Copy link
Member

Why not declare the interface as(null_or_func, func_or_self, arguments[oparg] -- result) and leave it at that?

We don't need the code generator to understand very bit of C code. We aren't implementing a C compiler.

TBH, I'm a little concerned that the code generator has become an end in itself, rather than being a means to an end.

@gvanrossum
Copy link
MemberAuthor

TBH, I'm a little concerned that the code generator has become an end in itself, rather than being a means to an end.

Yeah, I agree. I'm not sure what we'll get out of it. Generating a tier 2 interpreter and supporting micro-ops does still seem like a worthy cause though. We should talk a bit about this on Monday.

@gvanrossum
Copy link
MemberAuthor

gvanrossum commentedFeb 3, 2023
edited
Loading

Another thing where the code generator is getting in the way:CHECK_EVAL_BREAKER(). This may end up withgoto handle_eval_breaker and at that pointstack_pointer andnext_instr should be updated. I guess the solution is to special-case this, and when found, move the call to just beforeDISPATCH(). We do the same thing withPREDICT(). (EDIT: Yeah, I should definitely do this, it makes things much simpler for mostCALL* opcodes.)

@gvanrossum
Copy link
MemberAuthor

I have made the requested changes; please review again.

I didn't literally do what you or Mark suggested; instead, I converted everything to the format (already used by many of these)(method, callable, args[oparg] -- res) with this little idiom:

int is_meth = method != NULL;int total_args = oparg;if (is_meth) {    callable = method;    args--;    total_args++;}

(Slight variations in a few cases.) I also removed most manual stack manipulation except when exiting viaDISPATCH_INLINE(). I merged the latest main, so we now have (tadaaa)NO LEGACY INSTRUCTION DEFINITIONS LEFT.

brandtbucher reacted with hooray emoji

@bedevere-bot
Copy link

Thanks for making the requested changes!

@brandtbucher: please review the changes made to this pull request.

Copy link
Member

@brandtbucherbrandtbucher left a comment

Choose a reason for hiding this comment

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

Looks good!

Has it been benchmarked for regressions? Not a huge deal if not, but itdoes change quite a bit of critical code in subtle ways. Your call.

total_args = oparg + is_meth;
function = PEEK(total_args + 1);
if (!is_meth && Py_TYPE(callable) == &PyMethod_Type) {
is_meth = 1; // For consistenct; it's dead, though
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
is_meth=1;// Forconsistenct; it's dead, though
is_meth=1;// Forconsistency; it's dead, though

@brandtbucher
Copy link
Member

Ah, I see you already ran the benchmarks in an earlier comment. Never mind!

@gvanrossumgvanrossum merged commit616aec1 intopython:mainFeb 8, 2023
@gvanrossumgvanrossum deleted the call-family branchFebruary 8, 2023 19:40
@gvanrossumgvanrossum restored the call-family branchFebruary 8, 2023 19:41
@gvanrossumgvanrossum deleted the call-family branchFebruary 8, 2023 23:02
carljm added a commit to carljm/cpython that referenced this pull requestFeb 9, 2023
* main: (82 commits)pythongh-101670: typo fix in PyImport_ExtendInittab() (python#101723)pythonGH-99293: Document that `Py_TPFLAGS_VALID_VERSION_TAG` shouldn't be used. (#pythonGH-101736)  no-issue: Add Dong-hee Na as the cjkcodecs codeowner (pythongh-101731)pythongh-101678: Merge math_1_to_whatever() and math_1() (python#101730)pythongh-101678: refactor the math module to use special functions from c11 (pythonGH-101679)pythongh-85984: Remove legacy Lib/pty.py code. (python#92365)pythongh-98831: Use opcode metadata for stack_effect() (python#101704)pythongh-101283: Version was just released, so should be changed in 3.11.3 (pythonGH-101719)pythongh-101283: Fix use of unbound variable (pythonGH-101712)pythongh-101283: Improved fallback logic for subprocess with shell=True on Windows (pythonGH-101286)pythongh-101277: Port more itertools static types to heap types (python#101304)pythongh-98831: Modernize CALL and family (python#101508)pythonGH-101696: invalidate type version tag in `_PyStaticType_Dealloc` (python#101697)pythongh-100221: Fix creating dirs in `make sharedinstall` (pythonGH-100329)pythongh-101670: typo fix in PyImport_AppendInittab() (pythonGH-101672)pythongh-101196: Make isdir/isfile/exists faster on Windows (pythonGH-101324)pythongh-101614: Don't treat python3_d.dll as a Python DLL when checking extension modules for incompatibility (pythonGH-101615)pythongh-100933: Improve `check_element` helper in `test_xml_etree` (python#100934)pythonGH-101578: Normalize the current exception (pythonGH-101607)pythongh-47937: Note that Popen attributes are read-only (python#93070)  ...
@pythonpython deleted a commentFeb 25, 2023
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@brandtbucherbrandtbucherbrandtbucher approved these changes

@iritkatrieliritkatrielAwaiting requested review from iritkatriel

@markshannonmarkshannonAwaiting requested review from markshannonmarkshannon is a code owner

Assignees
No one assigned
Labels
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

5 participants
@gvanrossum@iritkatriel@markshannon@bedevere-bot@brandtbucher

[8]ページ先頭

©2009-2025 Movatter.jp