diff options
author | Aaron Patterson <tenderlove@ruby-lang.org> | 2022-03-07 11:08:15 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2022-03-10 08:44:28 -0800 |
commit | 67faea970857c292ae35dadd103287d4f4449a58 (patch) | |
tree | 8658e97b0aedde5ced412ad5a38b6b840eacd389 /vm_insnhelper.c | |
parent | 702f40628ad0e56cb42337fb2b0c53e0b901ed4d (diff) |
Small optimization for the opt_and instruction
This change eagerly performs a bitwise and on the parameters. If both
parameters are fixnums, then the result value should also be a fixnum.
We can just test the bit on the result and return if it's a fixnum.
Otherwise return Qundef.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/5629
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 27d9d13aac..f6d9c2c634 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -5335,9 +5335,15 @@ vm_opt_ltlt(VALUE recv, VALUE obj) static VALUE vm_opt_and(VALUE recv, VALUE obj) { - if (FIXNUM_2_P(recv, obj) && + // If recv and obj are both fixnums, then the bottom tag bit + // will be 1 on both. 1 & 1 == 1, so the result value will also + // be a fixnum. If either side is *not* a fixnum, then the tag bit + // will be 0, and we return Qundef. + VALUE ret = ((SIGNED_VALUE) recv) & ((SIGNED_VALUE) obj); + + if (FIXNUM_P(ret) && BASIC_OP_UNREDEFINED_P(BOP_AND, INTEGER_REDEFINED_OP_FLAG)) { - return (recv & obj) | 1; + return ret; } else { return Qundef; |