summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-10-15 07:34:05 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-10-15 07:34:05 +0000
commit4a01df4a0490f5987b25809e856b7cbdb719f948 (patch)
treebc8985361b09e6ab76f4a16a1ea5be694c33c630
parentd0885b5cd816b3b4aa5a613af3c028c1123999a6 (diff)
array.c: reduce RARRAY_LEN and ARY_CAPA
* array.c: reduce use of RARRAY_LEN and ARY_CAPA when object is not modified. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43291 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--array.c87
1 files changed, 50 insertions, 37 deletions
diff --git a/array.c b/array.c
index 49e3689..df09891 100644
--- a/array.c
+++ b/array.c
@@ -313,7 +313,7 @@ rb_ary_modify(VALUE ary)
{
rb_ary_modify_check(ary);
if (ARY_SHARED_P(ary)) {
- long len = RARRAY_LEN(ary);
+ long shared_len, len = RARRAY_LEN(ary);
VALUE shared = ARY_SHARED(ary);
if (len <= RARRAY_EMBED_LEN_MAX) {
const VALUE *ptr = ARY_HEAP_PTR(ary);
@@ -323,11 +323,11 @@ rb_ary_modify(VALUE ary)
rb_ary_decrement_share(shared);
ARY_SET_EMBED_LEN(ary, len);
}
- else if (ARY_SHARED_OCCUPIED(shared) && len > (RARRAY_LEN(shared)>>1)) {
+ else if (ARY_SHARED_OCCUPIED(shared) && len > ((shared_len = RARRAY_LEN(shared))>>1)) {
long shift = RARRAY_CONST_PTR(ary) - RARRAY_CONST_PTR(shared);
FL_UNSET_SHARED(ary);
ARY_SET_PTR(ary, RARRAY_CONST_PTR(shared));
- ARY_SET_CAPA(ary, RARRAY_LEN(shared));
+ ARY_SET_CAPA(ary, shared_len);
RARRAY_PTR_USE(ary, ptr, {
MEMMOVE(ptr, ptr+shift, VALUE, len);
});
@@ -573,12 +573,13 @@ ary_make_shared(VALUE ary)
return ary;
}
else {
+ long capa = ARY_CAPA(ary), len = RARRAY_LEN(ary);
NEWOBJ_OF(shared, struct RArray, 0, T_ARRAY); /* keep shared ary as shady */
FL_UNSET_EMBED(shared);
- ARY_SET_LEN((VALUE)shared, ARY_CAPA(ary));
+ ARY_SET_LEN((VALUE)shared, capa);
ARY_SET_PTR((VALUE)shared, RARRAY_CONST_PTR(ary));
- ary_mem_clear((VALUE)shared, RARRAY_LEN(ary), ARY_CAPA(ary) - RARRAY_LEN(ary));
+ ary_mem_clear((VALUE)shared, len, capa - len);
FL_SET_SHARED_ROOT(shared);
ARY_SET_SHARED_NUM((VALUE)shared, 1);
FL_SET_SHARED(ary);
@@ -853,18 +854,20 @@ ary_take_first_or_last(int argc, VALUE *argv, VALUE ary, enum ary_take_pos_flags
{
VALUE nv;
long n;
+ long len;
long offset = 0;
rb_scan_args(argc, argv, "1", &nv);
n = NUM2LONG(nv);
- if (n > RARRAY_LEN(ary)) {
- n = RARRAY_LEN(ary);
+ len = RARRAY_LEN(ary);
+ if (n > len) {
+ n = len;
}
else if (n < 0) {
rb_raise(rb_eArgError, "negative array size");
}
if (last) {
- offset = RARRAY_LEN(ary) - n;
+ offset = len - n;
}
return ary_make_partial(ary, rb_cArray, offset, n);
}
@@ -944,14 +947,15 @@ rb_ary_pop(VALUE ary)
{
long n;
rb_ary_modify_check(ary);
- if (RARRAY_LEN(ary) == 0) return Qnil;
+ n = RARRAY_LEN(ary);
+ if (n == 0) return Qnil;
if (ARY_OWNS_HEAP_P(ary) &&
- RARRAY_LEN(ary) * 3 < ARY_CAPA(ary) &&
+ n * 3 < ARY_CAPA(ary) &&
ARY_CAPA(ary) > ARY_DEFAULT_SIZE)
{
- ary_resize_capa(ary, RARRAY_LEN(ary) * 2);
+ ary_resize_capa(ary, n * 2);
}
- n = RARRAY_LEN(ary)-1;
+ --n;
ARY_SET_LEN(ary, n);
return RARRAY_AREF(ary, n);
}
@@ -993,14 +997,15 @@ VALUE
rb_ary_shift(VALUE ary)
{
VALUE top;
+ long len = RARRAY_LEN(ary);
rb_ary_modify_check(ary);
- if (RARRAY_LEN(ary) == 0) return Qnil;
+ if (len == 0) return Qnil;
top = RARRAY_AREF(ary, 0);
if (!ARY_SHARED_P(ary)) {
- if (RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
+ if (len < ARY_DEFAULT_SIZE) {
RARRAY_PTR_USE(ary, ptr, {
- MEMMOVE(ptr, ptr+1, VALUE, RARRAY_LEN(ary)-1);
+ MEMMOVE(ptr, ptr+1, VALUE, len-1);
}); /* WB: no new reference */
ARY_INCREASE_LEN(ary, -1);
return top;
@@ -1158,8 +1163,9 @@ rb_ary_unshift(VALUE ary, VALUE item)
static inline VALUE
rb_ary_elt(VALUE ary, long offset)
{
- if (RARRAY_LEN(ary) == 0) return Qnil;
- if (offset < 0 || RARRAY_LEN(ary) <= offset) {
+ long len = RARRAY_LEN(ary);
+ if (len == 0) return Qnil;
+ if (offset < 0 || len <= offset) {
return Qnil;
}
return RARRAY_AREF(ary, offset);
@@ -1178,12 +1184,13 @@ VALUE
rb_ary_subseq(VALUE ary, long beg, long len)
{
VALUE klass;
+ long alen = RARRAY_LEN(ary);
- if (beg > RARRAY_LEN(ary)) return Qnil;
+ if (beg > alen) return Qnil;
if (beg < 0 || len < 0) return Qnil;
- if (RARRAY_LEN(ary) < len || RARRAY_LEN(ary) < beg + len) {
- len = RARRAY_LEN(ary) - beg;
+ if (alen < len || alen < beg + len) {
+ len = alen - beg;
}
klass = rb_obj_class(ary);
if (len == 0) return ary_new(klass, 0);
@@ -1326,8 +1333,9 @@ VALUE
rb_ary_last(int argc, VALUE *argv, VALUE ary)
{
if (argc == 0) {
- if (RARRAY_LEN(ary) == 0) return Qnil;
- return RARRAY_AREF(ary, RARRAY_LEN(ary)-1);
+ long len = RARRAY_LEN(ary);
+ if (len == 0) return Qnil;
+ return RARRAY_AREF(ary, len-1);
}
else {
return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
@@ -1485,8 +1493,8 @@ rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
while (i--) {
if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
return LONG2NUM(i);
- if (i > RARRAY_LEN(ary)) {
- i = RARRAY_LEN(ary);
+ if (i > (len = RARRAY_LEN(ary))) {
+ i = len;
}
}
return Qnil;
@@ -1527,17 +1535,19 @@ static void
rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
{
long rlen;
+ long olen;
if (len < 0) rb_raise(rb_eIndexError, "negative length (%ld)", len);
+ olen = RARRAY_LEN(ary);
if (beg < 0) {
- beg += RARRAY_LEN(ary);
+ beg += olen;
if (beg < 0) {
rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
- beg - RARRAY_LEN(ary), -RARRAY_LEN(ary));
+ beg - olen, -olen);
}
}
- if (RARRAY_LEN(ary) < len || RARRAY_LEN(ary) < beg + len) {
- len = RARRAY_LEN(ary) - beg;
+ if (olen < len || olen < beg + len) {
+ len = olen - beg;
}
if (rpl == Qundef) {
@@ -1546,14 +1556,15 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
else {
rpl = rb_ary_to_ary(rpl);
rlen = RARRAY_LEN(rpl);
+ olen = RARRAY_LEN(ary); /* ary may be resized in rpl.to_ary too */
}
- if (beg >= RARRAY_LEN(ary)) {
+ if (beg >= olen) {
if (beg > ARY_MAX_SIZE - rlen) {
rb_raise(rb_eIndexError, "index %ld too big", beg);
}
ary_ensure_room_for_push(ary, rlen-len); /* len is 0 or negative */
len = beg + rlen;
- ary_mem_clear(ary, RARRAY_LEN(ary), beg - RARRAY_LEN(ary));
+ ary_mem_clear(ary, olen, beg - olen);
if (rlen > 0) {
ary_memcpy(ary, beg, rlen, RARRAY_CONST_PTR(rpl));
}
@@ -1563,7 +1574,7 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
long alen;
rb_ary_modify(ary);
- alen = RARRAY_LEN(ary) + rlen - len;
+ alen = olen + rlen - len;
if (alen >= ARY_CAPA(ary)) {
ary_double_capa(ary, alen);
}
@@ -1571,7 +1582,7 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
if (len != rlen) {
RARRAY_PTR_USE(ary, ptr,
MEMMOVE(ptr + beg + rlen, ptr + beg + len,
- VALUE, RARRAY_LEN(ary) - (beg + len)));
+ VALUE, olen - (beg + len)));
ARY_SET_LEN(ary, alen);
}
if (rlen > 0) {
@@ -1832,9 +1843,11 @@ rb_ary_reverse_each(VALUE ary)
RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
len = RARRAY_LEN(ary);
while (len--) {
+ long nlen;
rb_yield(RARRAY_AREF(ary, len));
- if (RARRAY_LEN(ary) < len) {
- len = RARRAY_LEN(ary);
+ nlen = RARRAY_LEN(ary);
+ if (nlen < len) {
+ len = nlen;
}
}
return ary;
@@ -2785,8 +2798,8 @@ rb_ary_select_bang(VALUE ary)
i2++;
}
- if (RARRAY_LEN(ary) == i2) return Qnil;
- if (i2 < RARRAY_LEN(ary))
+ if (i1 == i2) return Qnil;
+ if (i2 < i1)
ARY_SET_LEN(ary, i2);
return ary;
}
@@ -2916,7 +2929,7 @@ rb_ary_delete_at(VALUE ary, long pos)
rb_ary_modify(ary);
del = RARRAY_AREF(ary, pos);
RARRAY_PTR_USE(ary, ptr, {
- MEMMOVE(ptr+pos, ptr+pos+1, VALUE, RARRAY_LEN(ary)-pos-1);
+ MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
});
ARY_INCREASE_LEN(ary, -1);