From 67faea970857c292ae35dadd103287d4f4449a58 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Mon, 7 Mar 2022 11:08:15 -0800 Subject: [PATCH] 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. --- vm_insnhelper.c | 10 ++++++++-- 1 file 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;