[前][次][番号順一覧][スレッド一覧]

ruby-changes:55944

From: Yusuke <ko1@a...>
Date: Sat, 1 Jun 2019 13:34:56 +0900 (JST)
Subject: [ruby-changes:55944] Yusuke Endoh: 65e63af377 (trunk): Make opt_aref instruction support Integer#[]

https://git.ruby-lang.org/ruby.git/commit/?id=65e63af377

From 65e63af377bb493dea4d0207627ed87d5da360a8 Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@r...>
Date: Sat, 1 Jun 2019 13:15:43 +0900
Subject: 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.

diff --git a/internal.h b/internal.h
index 4312f8d..b1e6aec 100644
--- a/internal.h
+++ b/internal.h
@@ -1737,6 +1737,7 @@ VALUE rb_int_round(VALUE num, int ndigits, enum ruby_num_rounding_mode mode); https://github.com/ruby/ruby/blob/trunk/internal.h#L1737
 VALUE rb_int2str(VALUE num, int base);
 VALUE rb_dbl_hash(double d);
 VALUE rb_fix_plus(VALUE x, VALUE y);
+VALUE rb_fix_aref(VALUE fix, VALUE idx);
 VALUE rb_int_gt(VALUE x, VALUE y);
 int rb_float_cmp(VALUE x, VALUE y);
 VALUE rb_float_gt(VALUE x, VALUE y);
diff --git a/numeric.c b/numeric.c
index 336ff70..1fce19a 100644
--- a/numeric.c
+++ b/numeric.c
@@ -4630,8 +4630,8 @@ rb_int_rshift(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4630
     return Qnil;
 }
 
-static VALUE
-fix_aref(VALUE fix, VALUE idx)
+MJIT_FUNC_EXPORTED VALUE
+rb_fix_aref(VALUE fix, VALUE idx)
 {
     long val = FIX2LONG(fix);
     long i;
@@ -4722,7 +4722,7 @@ int_aref1(VALUE num, VALUE arg) https://github.com/ruby/ruby/blob/trunk/numeric.c#L4722
 
 one_bit:
     if (FIXNUM_P(num)) {
-        return fix_aref(num, arg);
+        return rb_fix_aref(num, arg);
     }
     else if (RB_TYPE_P(num, T_BIGNUM)) {
         return rb_big_aref(num, arg);
diff --git a/vm.c b/vm.c
index 3f5a619..70ec231 100644
--- a/vm.c
+++ b/vm.c
@@ -1643,7 +1643,7 @@ vm_init_redefined_flag(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L1643
     OP(GT, GT), (C(Integer), C(Float));
     OP(GE, GE), (C(Integer), C(Float));
     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(Length, LENGTH), (C(Array), C(String), C(Hash));
     OP(Size, SIZE), (C(Array), C(String), C(Hash));
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 7946f9a..3cd0c8d 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -4129,6 +4129,10 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L4129
 vm_opt_aref(VALUE recv, VALUE obj)
 {
     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;
     }
     else if (RBASIC_CLASS(recv) == rb_cArray &&
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]