GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-98831: Modernize CALL and family by gvanrossum · Pull Request #101508 · python/cpython

Conversation

@gvanrossum

@gvanrossum gvanrossum commented Feb 1, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Note that we have a few opcodes starting with CALL_ that aren't specializations of CALL.

  • Issue: Generate the interpreter #98831

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@gvanrossum gvanrossum added the skip news label Feb 1, 2023
@bedevere-bot bedevere-bot added the awaiting core review label Feb 1, 2023
@bedevere-bot bedevere-bot mentioned this pull request Feb 1, 2023
Update bundled pip to 22.3 #98331
Closed
@gvanrossum

gvanrossum commented Feb 1, 2023

Copy link
Copy Markdown
Member Author

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 the LOAD_ATTR instruction dynamically decides whether to produce one or the other.)

In the latter case we then introspect callable and if it is a bound method, we extract the im_func and im_self fields and convert to the former format -- but if the callable is not a bound method, we leave the NULL in place.

There is a macro is_method(stack_pointer, oparg) that, despite its lofty name, really just checks whether there's a NULL at the indicated position (using PEEK(oparg+1), it doesn't even use the stack_pointer argument). In the converted instructions I am modeling this as an input stack effect of the form thing1, thing2, args[oparg], and I replace the is_method() macro with thing1 != NULL. Everything else then gets a little awkward, because the thing we need to call in the end is either thing1 or thing2, and the number of arguments is either oparg or oparg+1. It also means that the first argument is not the start of the args 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 with DISPATCH_INLINE(), and because of that we can't leave the popping of the stack to the generated code (it would just be STACK_SHRINK(oparg+1)) -- we have to manually do this, and while we're at it we also either DECREF the arguments (including self, 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 as method, callable, args[oparg] and do something like

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

so that we can always call callable with oparg arguments starting at args. But we still need to recall whether we did this, so we know where to push the result.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gvanrossum
gvanrossum requested a review from iritkatriel February 1, 2023 23:57
@iritkatriel

iritkatriel commented Feb 2, 2023

Copy link
Copy Markdown
Member

Note that you linked this with the wrong issue.

gvanrossum reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gvanrossum gvanrossum changed the title gh-98331: Modernize CALL and family gh-98831: Modernize CALL and family Feb 2, 2023
@bedevere-bot bedevere-bot mentioned this pull request Feb 2, 2023
Generate the interpreter #98831
Closed
@gvanrossum

gvanrossum commented Feb 2, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@markshannon

markshannon commented Feb 2, 2023

Copy link
Copy Markdown
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.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gvanrossum

gvanrossum commented Feb 2, 2023

Copy link
Copy Markdown
Member Author

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.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gvanrossum
gvanrossum force-pushed the call-family branch from 2b105e8 to 8a293d9 Compare February 3, 2023 18:31
@gvanrossum

gvanrossum commented Feb 3, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

Another thing where the code generator is getting in the way: CHECK_EVAL_BREAKER(). This may end up with goto handle_eval_breaker and at that point stack_pointer and next_instr should be updated. I guess the solution is to special-case this, and when found, move the call to just before DISPATCH(). We do the same thing with PREDICT(). (EDIT: Yeah, I should definitely do this, it makes things much simpler for most CALL* opcodes.)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gvanrossum
gvanrossum force-pushed the call-family branch from 4cd24d6 to 18a0642 Compare February 4, 2023 01:14
gvanrossum added 16 commits February 4, 2023 16:01
@gvanrossum
Special-case CHECK_EVAL_BREAKER()
234b876
@gvanrossum
Improve DECREF_INPUTS()
a6d0227
- Support arrays
- Support conditional inputs
- Skip 'unused' and 'null'
@gvanrossum
Preliminaries
bd63af8
- Move CALL_BOUND_METHOD_EXACT_ARGS into place
- Add a commented-out family definition
@gvanrossum
Modernize CALL_BOUND_METHOD_EXACT_ARGS
b6ec372
@gvanrossum
Modernize CALL_PY_EXACT_ARGS
be49e61
@gvanrossum
Modernize CALL (not too happy with it)
18cacf5
@gvanrossum
Modernize CALL_PY_WITH_DEFAULTS
d69ca8e
@gvanrossum
Modernize CALL_NO_KW_TYPE_1
09701cf
@gvanrossum
Modernize CALL_NO_KW_STR_1
389601d
@gvanrossum
Modernize CALL_NO_KW_TUPLE_1
9a7b75a
@gvanrossum
Modernize CALL_BUILTIN_CLASS (a different way)
af19fa6
@gvanrossum
Modernize CALL_NO_KW_BUILTIN_O
05e4ea8
@gvanrossum
Modernize CALL_NO_KW_BUILTIN_FAST
491de28
@gvanrossum
Modernize CALL_BUILTIN_FAST_WITH_KEYWORDS
25bc08a
@gvanrossum
Modernize CALL_NO_KW_LEN
be8ec59
@gvanrossum
Modernize CALL_NO_KW_ISINSTANCE
4397083
gvanrossum added 11 commits February 7, 2023 16:04
@gvanrossum
Cleanup CALL_BUILTIN_FAST_WITH_KEYWORDS
a968545
@gvanrossum
Cleanup CALL_NO_KW_LEN
1de410f
@gvanrossum
Move KWNAMES_LEN() to ceval_macros.h
390a9b4
@gvanrossum
Cleanup CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS
4250420
@gvanrossum
Cleanup CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS
5ca2b95
@gvanrossum
Cleanup CALL_NO_KW_METHOD_DESCRIPTOR_FAST
9c41712
@gvanrossum
Cleanup CALL_PY_WITH_DEFAULTS
b7281a9
@gvanrossum
Cleanup CALL_PY_EXACT_ARGS
e140879
@gvanrossum
Cleanup CALL_BOUND_METHOD_EXACT_ARGS
6407369
@gvanrossum
Cleanup CALL
b9432ba
@gvanrossum
Merge remote-tracking branch 'origin/main' into call-family
9595e01
@gvanrossum

gvanrossum commented Feb 8, 2023

Copy link
Copy Markdown
Member Author

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 via DISPATCH_INLINE(). I merged the latest main, so we now have (tadaaa) NO LEGACY INSTRUCTION DEFINITIONS LEFT.

brandtbucher reacted with hooray emoji
All reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot added awaiting change review and removed awaiting changes labels Feb 8, 2023
@bedevere-bot

bedevere-bot commented Feb 8, 2023

Copy link
Copy Markdown

Thanks for making the requested changes!

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot
bedevere-bot requested a review from brandtbucher February 8, 2023 04:20
gvanrossum added 2 commits February 7, 2023 20:26
@gvanrossum
Remove support for legacy instructions
d84c30f
@gvanrossum
Restore support for legacy instructions
cd69634
It will be removed in a separate PR.

This reverts commit d84c30f.
@gvanrossum gvanrossum mentioned this pull request Feb 8, 2023
gh-98831: Use opcode metadata for stack_effect() #101704
Merged
brandtbucher
brandtbucher approved these changes Feb 8, 2023
View reviewed changes

@brandtbucher brandtbucher left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this 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 it does change quite a bit of critical code in subtle ways. Your call.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Python/bytecodes.c
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

@brandtbucher brandtbucher Feb 8, 2023

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

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; // For consistenct; it's dead, though
is_meth = 1; // For consistency; it's dead, though

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-bot bedevere-bot added awaiting merge and removed awaiting change review labels Feb 8, 2023
@brandtbucher

brandtbucher commented Feb 8, 2023

Copy link
Copy Markdown
Member

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@gvanrossum
gvanrossum merged commit 616aec1 into python:main Feb 8, 2023
@bedevere-bot bedevere-bot removed the awaiting merge label Feb 8, 2023
@gvanrossum
gvanrossum deleted the call-family branch February 8, 2023 19:40
@gvanrossum
gvanrossum restored the call-family branch February 8, 2023 19:41
@gvanrossum
gvanrossum deleted the call-family branch February 8, 2023 23:02
carljm added a commit to carljm/cpython that referenced this pull request Feb 9, 2023
@carljm
Merge branch 'main' into inlinecomp2
be3becc
* 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)
  ...
@python python deleted a comment Feb 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@brandtbucher brandtbucher brandtbucher approved these changes
@iritkatriel iritkatriel Awaiting requested review from iritkatriel
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

skip news

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@gvanrossum @iritkatriel @markshannon @bedevere-bot @brandtbucher
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.