Skip to content

gh-106581: Start projecting through calls #107793

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

Closed
wants to merge 26 commits into from

Conversation

gvanrossum
Copy link
Member

@gvanrossum gvanrossum commented Aug 9, 2023

For now, builds on gh-107760.

  • Add function-by-version cache (and redid it using borrowed refs)
  • Double max trace length to 64
  • Trace into function calls
  • Support RESUME op in Tier 2

TODO:

This is only the first step for doing `CALL` in Tier 2.
The next step involves tracing into the called code object.
After that we'll have to do the remaining `CALL` specialization.
Finally we'll have to tweak various things like `KW_NAMES`,
and possibly move the `NULL` (for method calls) *above* the callable.
But those are things for future PRs.

Note: this moves setting `frame->return_offset` directly in front of
`DISPATCH_INLINED()`, to make it easier to move it into `_PUSH_FRAME`.
Instead, the special case is an opcode using SAVE_FRAME_STATE().
Introducing #if TIER_ONE and #if TIER_TWO so we can implement
_PUSH_FRAME differently for both tiers.
Instead, we special-case SAVE_IP:
- Its Tier 2 expansion sets oparg to the instruction offset
- In Tier 1 it is a no-op (and skipped if present in a macro)
@gvanrossum
Copy link
Member Author

This leaks quite a bit, probably in the function-by-version cache.

@gvanrossum
Copy link
Member Author

I suspect I have to redo the function version cache using weak references if I want all tests to pass. Unfortunately that will slow things down. Having borrowed references to function objects in a cache seems horrible. What else could we try?

Perhaps the cache could contain code objects (which are what we want anyways, so perhaps a scheme like the current one doesn't break so many tests), and when a function's __code__ or __defaults__ attributes (or a few others) are updated we just lose the ability to specialize calls to it. In fact, when its __code__ is set, we could just reset its version to the new code object's co_version.

(BTW, why is func_version set to code->co_version only by MAKE_FUNCTION and not during regular function object initialization? This feels like a relevant mystery.)

@gvanrossum
Copy link
Member Author

Or perhaps we could leave borrowed references in the function version cache that we remove when the function is deleted? (Also when the function's func_version attribute is changed.) That would be a custom variant on using weak references that might be faster.

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

Successfully merging this pull request may close these issues.

2 participants