Make opt_aref instruction support Integer#[]
only when its receiver and the argument are both Integers. Since 6bedbf4625, Integer#[] has supported a range extraction. This means that Integer#[] now accepts multiple arguments, which made the method very slow unfortunately. This change fixes the performance issue by adding a special handling for its traditional use case: `num[idx]` where both `num` and `idx` are Integers.
This commit is contained in:
parent
7df65ef676
commit
65e63af377
@ -1737,6 +1737,7 @@ VALUE rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode);
|
|||||||
VALUE rb_int2str(VALUE num, int base);
|
VALUE rb_int2str(VALUE num, int base);
|
||||||
VALUE rb_dbl_hash(double d);
|
VALUE rb_dbl_hash(double d);
|
||||||
VALUE rb_fix_plus(VALUE x, VALUE y);
|
VALUE rb_fix_plus(VALUE x, VALUE y);
|
||||||
|
VALUE rb_fix_aref(VALUE fix, VALUE idx);
|
||||||
VALUE rb_int_gt(VALUE x, VALUE y);
|
VALUE rb_int_gt(VALUE x, VALUE y);
|
||||||
int rb_float_cmp(VALUE x, VALUE y);
|
int rb_float_cmp(VALUE x, VALUE y);
|
||||||
VALUE rb_float_gt(VALUE x, VALUE y);
|
VALUE rb_float_gt(VALUE x, VALUE y);
|
||||||
|
@ -4630,8 +4630,8 @@ rb_int_rshift(VALUE x, VALUE y)
|
|||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
MJIT_FUNC_EXPORTED VALUE
|
||||||
fix_aref(VALUE fix, VALUE idx)
|
rb_fix_aref(VALUE fix, VALUE idx)
|
||||||
{
|
{
|
||||||
long val = FIX2LONG(fix);
|
long val = FIX2LONG(fix);
|
||||||
long i;
|
long i;
|
||||||
@ -4722,7 +4722,7 @@ int_aref1(VALUE num, VALUE arg)
|
|||||||
|
|
||||||
one_bit:
|
one_bit:
|
||||||
if (FIXNUM_P(num)) {
|
if (FIXNUM_P(num)) {
|
||||||
return fix_aref(num, arg);
|
return rb_fix_aref(num, arg);
|
||||||
}
|
}
|
||||||
else if (RB_TYPE_P(num, T_BIGNUM)) {
|
else if (RB_TYPE_P(num, T_BIGNUM)) {
|
||||||
return rb_big_aref(num, arg);
|
return rb_big_aref(num, arg);
|
||||||
|
2
vm.c
2
vm.c
@ -1643,7 +1643,7 @@ vm_init_redefined_flag(void)
|
|||||||
OP(GT, GT), (C(Integer), C(Float));
|
OP(GT, GT), (C(Integer), C(Float));
|
||||||
OP(GE, GE), (C(Integer), C(Float));
|
OP(GE, GE), (C(Integer), C(Float));
|
||||||
OP(LTLT, LTLT), (C(String), C(Array));
|
OP(LTLT, LTLT), (C(String), C(Array));
|
||||||
OP(AREF, AREF), (C(Array), C(Hash));
|
OP(AREF, AREF), (C(Array), C(Hash), C(Integer));
|
||||||
OP(ASET, ASET), (C(Array), C(Hash));
|
OP(ASET, ASET), (C(Array), C(Hash));
|
||||||
OP(Length, LENGTH), (C(Array), C(String), C(Hash));
|
OP(Length, LENGTH), (C(Array), C(String), C(Hash));
|
||||||
OP(Size, SIZE), (C(Array), C(String), C(Hash));
|
OP(Size, SIZE), (C(Array), C(String), C(Hash));
|
||||||
|
@ -4129,6 +4129,10 @@ static VALUE
|
|||||||
vm_opt_aref(VALUE recv, VALUE obj)
|
vm_opt_aref(VALUE recv, VALUE obj)
|
||||||
{
|
{
|
||||||
if (SPECIAL_CONST_P(recv)) {
|
if (SPECIAL_CONST_P(recv)) {
|
||||||
|
if (FIXNUM_P(recv) && FIXNUM_P(obj) &&
|
||||||
|
BASIC_OP_UNREDEFINED_P(BOP_AREF, INTEGER_REDEFINED_OP_FLAG)) {
|
||||||
|
return rb_fix_aref(recv, obj);
|
||||||
|
}
|
||||||
return Qundef;
|
return Qundef;
|
||||||
}
|
}
|
||||||
else if (RBASIC_CLASS(recv) == rb_cArray &&
|
else if (RBASIC_CLASS(recv) == rb_cArray &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user