Skip to content

Clean up the CALL sequence #105848

Closed
Closed
@brandtbucher

Description

The bytecode sequence for calls has gotten better in 3.12, but I think it can still be improved in a couple of ways:

  • First, we can start either pushing NULL or a tuple of kwnames onto the stack immediately before calls, rather than sometimes stashing kwnames away in a local eval loop variable via the KW_NAMES opcode. This should free up a register around calls, and it's nice to do anyways since it makes the bytecode more regular (and the stack is really where this sort of stuff belongs).
  • Once that is done, we can use the low bit of the CALL oparg to indicate whether or not to expect kwnames on the stack. This should get rid of lots of new PUSH_NULL/CALL pairs.
  • Separate from the above, but still sort of related: it's a bit awkward that our method call optimization either leaves [callable, self, args...] or [NULL, callable, args...] on the stack, since it means that CALL (and most of its specializations) have to do an awkward swap in order to load the "correct" callable. This can be simplified by always entering calls with [callable, self_or_null, args...] on the stack, so that the callable is always in the same position.

After this is all said and done, the CALL stack effect will look something like:

inst(CALL, (counter/1, cache/2, callable, self_or_null, args[oparg >> 1], kwnames if (oparg & 1) -- res)) {
    // ...
}

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

3.13bugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)performancePerformance or resource usagetriagedThe issue has been accepted as valid by a triager.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions