summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-22 00:19:12 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-22 00:19:12 +0000
commite480660b85f79d7f6c5fed278e9f521d877620d1 (patch)
treefcef0e0276bc3e1833af7bc2284797746a6669b1
parentf36ee4406e3600ea83021779ff26edee543afeff (diff)
vm_insnhelper.c: array aref optimization
* vm_insnhelper.c (vm_opt_aref): optimize on other than fixnum argument too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60333 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--array.c32
-rw-r--r--internal.h2
-rw-r--r--vm_insnhelper.c5
3 files changed, 24 insertions, 15 deletions
diff --git a/array.c b/array.c
index c5d7274272..5ec72c6930 100644
--- a/array.c
+++ b/array.c
@@ -1284,21 +1284,29 @@ rb_ary_subseq(VALUE ary, long beg, long len)
VALUE
rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
{
- VALUE arg;
- long beg, len;
-
+ rb_check_arity(argc, 1, 2);
if (argc == 2) {
- beg = NUM2LONG(argv[0]);
- len = NUM2LONG(argv[1]);
- if (beg < 0) {
- beg += RARRAY_LEN(ary);
- }
- return rb_ary_subseq(ary, beg, len);
+ return rb_ary_aref2(ary, argv[0], argv[1]);
}
- if (argc != 1) {
- rb_scan_args(argc, argv, "11", NULL, NULL);
+ return rb_ary_aref1(ary, argv[0]);
+}
+
+VALUE
+rb_ary_aref2(VALUE ary, VALUE b, VALUE e)
+{
+ long beg = NUM2LONG(b);
+ long len = NUM2LONG(e);
+ if (beg < 0) {
+ beg += RARRAY_LEN(ary);
}
- arg = argv[0];
+ return rb_ary_subseq(ary, beg, len);
+}
+
+VALUE
+rb_ary_aref1(VALUE ary, VALUE arg)
+{
+ long beg, len;
+
/* special case - speeding up */
if (FIXNUM_P(arg)) {
return rb_ary_entry(ary, FIX2LONG(arg));
diff --git a/internal.h b/internal.h
index 6175949351..743e83187c 100644
--- a/internal.h
+++ b/internal.h
@@ -1032,6 +1032,8 @@ void rb_ary_set_len(VALUE, long);
void rb_ary_delete_same(VALUE, VALUE);
VALUE rb_ary_tmp_new_fill(long capa);
VALUE rb_ary_at(VALUE, VALUE);
+VALUE rb_ary_aref1(VALUE ary, VALUE i);
+VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e);
size_t rb_ary_memsize(VALUE);
#ifdef __GNUC__
#define rb_ary_new_from_args(n, ...) \
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 652b3d8133..0d23359f5a 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3584,9 +3584,8 @@ vm_opt_aref(VALUE recv, VALUE obj)
return Qundef;
}
else if (RBASIC_CLASS(recv) == rb_cArray &&
- BASIC_OP_UNREDEFINED_P(BOP_AREF, ARRAY_REDEFINED_OP_FLAG) &&
- FIXNUM_P(obj)) {
- return rb_ary_entry(recv, FIX2LONG(obj));
+ BASIC_OP_UNREDEFINED_P(BOP_AREF, ARRAY_REDEFINED_OP_FLAG)) {
+ return rb_ary_aref1(recv, obj);
}
else if (RBASIC_CLASS(recv) == rb_cHash &&
BASIC_OP_UNREDEFINED_P(BOP_AREF, HASH_REDEFINED_OP_FLAG)) {