-
Notifications
You must be signed in to change notification settings - Fork 5.4k
YJIT: add codegen for String#setbyte #9767
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
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
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.
Are we okay with breaking the backtrace when YJIT is enabled? We discussed this exact problem on Thursday and you suggested to put a guard on the index.
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.
On the flip side, you could probably remove
jit_prepare_routine_call
if you guard it, so it would allow you to keep local types.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.
We'd also need to guard for frozen strings.
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.
The method can still raise though? You're saying it won't report the method raising correctly? Why is that?
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.
I didn't say it can't raise. I only talked about the backtrace.
master:
this branch:
With this change, you can't know which method is raising the exception. If a line has a chain of method calls, it'd be harder to tell whether it's from
setbyte
or not. And this problem will happen only after YJIT compiles it.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.
Ideally we'd preserve the backtrace, but at the same time, this can really get in the way of performance optimizations. How do you guys feel about it?
In theory, it may be possible to add JIT support for recovering a correct backtrace based on the PC (we do set up the PC in
jit_prepare_routine_call
) ?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.
I feel uneasy about messing with the backtrace since it's user facing. More people should probably be brought into the discussion if we really want to do it.
With stuff like
send
and alias methods, it's hard to recover the callee from the PC alone, since that just points you to the callsite.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.
Ok hmmm.
I feel like if we have to guard that the index is fixnum and in range, and that the string is also frozen, it really nerfs this PR because we're adding a fair bit of extra work on top of a C call that will duplicate the guards we just did.
So this opens up at least 2 discussion threads:
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.
For (2), if we're going to guard, it's probably faster and cleaner to write a version of the C function that returns a bool instead of raising, that way we can just call it without preparation and we don't repeat any guards. With the guards, it's really close to actually setting the byte.
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.
For this PR, Alan's idea on (2) seems reasonable to me.
For a long term, we should aim for having this capability. We have so many almost-leaf methods that are not leaf only because they raise. Many C methods need to be inlining-safe when we start inlining non-trivial ISEQs.
We could have a YJIT-global hash map
{ PC => C method }
, make sure it's currently the only callee from the PC on YJIT (otherwise invalidate the existing block), and resurrect the frame onrb_raise
if the top-most frame's PC is in the hash map.If the same ISEQ is called from the interpreter for any reason, another frame (
setbyte
or another method, not the caller we're compiling) would be the top-most frame, so it wouldn't doubly push the frame.