-
Notifications
You must be signed in to change notification settings - Fork 5.4k
YJIT: Optimize defined?(yield) #9599
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
Conversation
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.
Neat method-call free way to do block_given? without taking a block param!
081a3de
to
d3b3da1
Compare
Sequel and Roda have both been using |
Is it not possible to replace block_given? with defined(yield) in the peephole optimizer? I guess a user could have redefined the method, but why would they want to? |
We can't make sneaky language semantics changes like that, it's too surprising for users and too hard to discover. Also, there is already many redefinitions: https://github.com/search?q=%22def+block_given%3F%22&type=code |
🥲 |
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 agree with Alan. This is neat. Good thinking :)
For people stumbling on this and thinking to write a |
This PR optimizes
defined
instruction for theDEFINED_YIELD
case, which is used bydefined?(yield)
.It has been raised as an idea to use
defined?(yield)
instead ofblock_given?
when we rewrite a C method in Ruby so that it will not be impacted by method redefinition.Matz didn't ask for tolerating such redefinition, so we don't need to do it for compatibility. However, it could be still useful for performance when we rewrite C methods in Ruby since
defined?(yield)
is not a method call unlikeblock_given?
, so it's faster on the interpreter.Even for YJIT,
defined
instruction is more preferable because you don't need to split blocks fordefer_compilation
(smaller memory overhead) or add a guard for the receiver (faster).Since we're interested in removing C -> Ruby calls, we would naturally rewrite methods that check
block_given?
. To make it easier for us to merge such changes, being able to use this optimization for the interpreter performance seems useful.Example code
block_given?
defined?(yield)