diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-05 14:35:39 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-05 14:35:39 +0000 |
commit | 40229f892c6877ecd0d45f24b662b05c74c7774a (patch) | |
tree | 7251368c8467ececd67672d08a4815aea187f30d | |
parent | c984f7712230ffbbcb702923e421c306ca98f40b (diff) | |
download | ruby-40229f892c6877ecd0d45f24b662b05c74c7774a.tar.gz |
* array.c (rb_ary_{times, shuffle_bang, sample}): reducing macro
calls inside of the loop by keeping pointers in local
variables. a patch from Masahiro Kanai (CanI) in [ruby-dev:39406].
It was found and fixed at Security and Programming camp 2009.
* string.c (rb_str_{times, split_m}): ditto.
* struct.c (rb_struct_{getmember, set, aref_id, aset_id}, {make,
inspect}_struct, recursive_{equal, hash, eql}): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25237 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | array.c | 31 | ||||
-rw-r--r-- | string.c | 27 | ||||
-rw-r--r-- | struct.c | 100 |
4 files changed, 111 insertions, 59 deletions
@@ -1,3 +1,15 @@ +Mon Oct 5 12:22:12 2009 Yukihiro Matsumoto <matz@ruby-lang.org> + + * array.c (rb_ary_{times, shuffle_bang, sample}): reducing macro + calls inside of the loop by keeping pointers in local + variables. a patch from Masahiro Kanai (CanI) in [ruby-dev:39406]. + It was found and fixed at Security and Programming camp 2009. + + * string.c (rb_str_{times, split_m}): ditto. + + * struct.c (rb_struct_{getmember, set, aref_id, aset_id}, {make, + inspect}_struct, recursive_{equal, hash, eql}): ditto. + Mon Oct 5 00:09:57 2009 Yukihiro Matsumoto <matz@ruby-lang.org> * vm_method.c (basic_obj_respond_to): should not call @@ -2708,8 +2708,8 @@ rb_ary_concat(VALUE x, VALUE y) static VALUE rb_ary_times(VALUE ary, VALUE times) { - VALUE ary2, tmp; - long i, len; + VALUE ary2, tmp, *ptr, *ptr2; + long i, t, len; tmp = rb_check_string_type(times); if (!NIL_P(tmp)) { @@ -2732,8 +2732,11 @@ rb_ary_times(VALUE ary, VALUE times) ary2 = ary_new(rb_obj_class(ary), len); ARY_SET_LEN(ary2, len); - for (i=0; i<len; i+=RARRAY_LEN(ary)) { - MEMCPY(RARRAY_PTR(ary2)+i, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary)); + ptr = RARRAY_PTR(ary); + ptr2 = RARRAY_PTR(ary2); + t = RARRAY_LEN(ary); + for (i=0; i<len; i+=t) { + MEMCPY(ptr2+i, ptr, VALUE, t); } out: OBJ_INFECT(ary2, ary); @@ -3491,14 +3494,16 @@ rb_ary_flatten(int argc, VALUE *argv, VALUE ary) static VALUE rb_ary_shuffle_bang(VALUE ary) { + VALUE *ptr; long i = RARRAY_LEN(ary); rb_ary_modify(ary); + ptr = RARRAY_PTR(ary); while (i) { long j = (long)(rb_genrand_real()*i); - VALUE tmp = RARRAY_PTR(ary)[--i]; - RARRAY_PTR(ary)[i] = RARRAY_PTR(ary)[j]; - RARRAY_PTR(ary)[j] = tmp; + VALUE tmp = ptr[--i]; + ptr[i] = ptr[j]; + ptr[j] = tmp; } return ary; } @@ -3576,6 +3581,7 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary) return rb_ary_new3(3, ptr[i], ptr[j], ptr[k]); } if ((size_t)n < sizeof(idx)/sizeof(idx[0])) { + VALUE *ptr_result; long sorted[sizeof(idx)/sizeof(idx[0])]; sorted[0] = idx[0] = (long)(rb_genrand_real()*len); for (i=1; i<n; i++) { @@ -3588,18 +3594,21 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary) sorted[j] = idx[i] = k; } result = rb_ary_new2(n); + ptr_result = RARRAY_PTR(result); for (i=0; i<n; i++) { - RARRAY_PTR(result)[i] = RARRAY_PTR(ary)[idx[i]]; + ptr_result[i] = ptr[idx[i]]; } } else { + VALUE *ptr_result; result = rb_ary_new4(len, ptr); + ptr_result = RARRAY_PTR(result); RB_GC_GUARD(ary); for (i=0; i<n; i++) { j = (long)(rb_genrand_real()*(len-i)) + i; - nv = RARRAY_PTR(result)[j]; - RARRAY_PTR(result)[j] = RARRAY_PTR(result)[i]; - RARRAY_PTR(result)[i] = nv; + nv = ptr_result[j]; + ptr_result[j] = ptr_result[i]; + ptr_result[i] = nv; } } ARY_SET_LEN(result, n); @@ -1173,6 +1173,7 @@ rb_str_times(VALUE str, VALUE times) { VALUE str2; long n, len; + char *ptr2; len = NUM2LONG(times); if (len < 0) { @@ -1183,16 +1184,17 @@ rb_str_times(VALUE str, VALUE times) } str2 = rb_str_new5(str, 0, len *= RSTRING_LEN(str)); + ptr2 = RSTRING_PTR(str2); if (len) { n = RSTRING_LEN(str); - memcpy(RSTRING_PTR(str2), RSTRING_PTR(str), n); + memcpy(ptr2, RSTRING_PTR(str), n); while (n <= len/2) { - memcpy(RSTRING_PTR(str2) + n, RSTRING_PTR(str2), n); + memcpy(ptr2 + n, ptr2, n); n *= 2; } - memcpy(RSTRING_PTR(str2) + n, RSTRING_PTR(str2), len-n); + memcpy(ptr2 + n, ptr2, len-n); } - RSTRING_PTR(str2)[RSTRING_LEN(str2)] = '\0'; + ptr2[RSTRING_LEN(str2)] = '\0'; OBJ_INFECT(str2, str); rb_enc_cr_str_copy_for_substr(str2, str); @@ -5513,6 +5515,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) } else if (split_type == string) { char *ptr = RSTRING_PTR(str); + char *temp = ptr; char *eptr = RSTRING_END(str); char *sptr = RSTRING_PTR(spat); long slen = RSTRING_LEN(spat); @@ -5532,13 +5535,15 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) ptr = t; continue; } - rb_ary_push(result, rb_str_subseq(str, ptr - RSTRING_PTR(str), end)); + rb_ary_push(result, rb_str_subseq(str, ptr - temp, end)); ptr += end + slen; if (!NIL_P(limit) && lim <= ++i) break; } - beg = ptr - RSTRING_PTR(str); + beg = ptr - temp; } else { + char *ptr = RSTRING_PTR(str); + long len = RSTRING_LEN(str); long start = beg; long idx; int last_null = 0; @@ -5547,22 +5552,22 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) while ((end = rb_reg_search(spat, str, start, 0)) >= 0) { regs = RMATCH_REGS(rb_backref_get()); if (start == end && BEG(0) == END(0)) { - if (!RSTRING_PTR(str)) { + if (!ptr) { rb_ary_push(result, rb_str_new("", 0)); break; } else if (last_null == 1) { rb_ary_push(result, rb_str_subseq(str, beg, - rb_enc_fast_mbclen(RSTRING_PTR(str)+beg, - RSTRING_END(str), + rb_enc_fast_mbclen(ptr+beg, + ptr+len, enc))); beg = start; } else { - if (RSTRING_PTR(str)+start == RSTRING_END(str)) + if (ptr+start == ptr+len) start++; else - start += rb_enc_fast_mbclen(RSTRING_PTR(str)+start,RSTRING_END(str),enc); + start += rb_enc_fast_mbclen(ptr+start,ptr+len,enc); last_null = 1; continue; } @@ -98,14 +98,17 @@ rb_struct_members_m(VALUE obj) VALUE rb_struct_getmember(VALUE obj, ID id) { - VALUE members, slot; - long i; + VALUE members, slot, *ptr, *ptr_members; + long i, len; + ptr = RSTRUCT_PTR(obj); members = rb_struct_members(obj); + ptr_members = RARRAY_PTR(members); slot = ID2SYM(id); - for (i=0; i<RARRAY_LEN(members); i++) { - if (RARRAY_PTR(members)[i] == slot) { - return RSTRUCT_PTR(obj)[i]; + len = RARRAY_LEN(members); + for (i=0; i<len; i++) { + if (ptr_members[i] == slot) { + return ptr[i]; } } rb_name_error(id, "%s is not struct member", rb_id2name(id)); @@ -156,15 +159,18 @@ rb_struct_modify(VALUE s) static VALUE rb_struct_set(VALUE obj, VALUE val) { - VALUE members, slot; - long i; + VALUE members, slot, *ptr, *ptr_members; + long i, len; members = rb_struct_members(obj); + ptr_members = RARRAY_PTR(members); + len = RARRAY_LEN(members); rb_struct_modify(obj); - for (i=0; i<RARRAY_LEN(members); i++) { - slot = RARRAY_PTR(members)[i]; + ptr = RSTRUCT_PTR(obj); + for (i=0; i<len; i++) { + slot = ptr_members[i]; if (rb_id_attrset(SYM2ID(slot)) == rb_frame_this_func()) { - return RSTRUCT_PTR(obj)[i] = val; + return ptr[i] = val; } } rb_name_error(rb_frame_this_func(), "`%s' is not a struct member", @@ -175,9 +181,9 @@ rb_struct_set(VALUE obj, VALUE val) static VALUE make_struct(VALUE name, VALUE members, VALUE klass) { - VALUE nstr; + VALUE nstr, *ptr_members; ID id; - long i; + long i, len; OBJ_FREEZE(members); if (NIL_P(name)) { @@ -204,8 +210,10 @@ make_struct(VALUE name, VALUE members, VALUE klass) rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0); - for (i=0; i< RARRAY_LEN(members); i++) { - ID id = SYM2ID(RARRAY_PTR(members)[i]); + ptr_members = RARRAY_PTR(members); + len = RARRAY_LEN(members); + for (i=0; i< len; i++) { + ID id = SYM2ID(ptr_members[i]); if (rb_is_local_id(id) || rb_is_const_id(id)) { if (i < N_REF_FUNC) { rb_define_method_id(nstr, id, ref_func[i], 0); @@ -498,7 +506,8 @@ inspect_struct(VALUE s, VALUE dummy, int recur) { VALUE cname = rb_class_name(rb_obj_class(s)); VALUE members, str = rb_str_new2("#<struct "); - long i; + VALUE *ptr, *ptr_members; + long i, len; char first = RSTRING_PTR(cname)[0]; if (recur || first != '#') { @@ -509,7 +518,10 @@ inspect_struct(VALUE s, VALUE dummy, int recur) } members = rb_struct_members(s); - for (i=0; i<RSTRUCT_LEN(s); i++) { + ptr_members = RARRAY_PTR(members); + ptr = RSTRUCT_PTR(s); + len = RSTRUCT_LEN(s); + for (i=0; i<len; i++) { VALUE slot; ID id; @@ -519,7 +531,7 @@ inspect_struct(VALUE s, VALUE dummy, int recur) else if (first != '#') { rb_str_cat2(str, " "); } - slot = RARRAY_PTR(members)[i]; + slot = ptr_members[i]; id = SYM2ID(slot); if (rb_is_local_id(id) || rb_is_const_id(id)) { rb_str_append(str, rb_id2str(id)); @@ -528,7 +540,7 @@ inspect_struct(VALUE s, VALUE dummy, int recur) rb_str_append(str, rb_inspect(slot)); } rb_str_cat2(str, "="); - rb_str_append(str, rb_inspect(RSTRUCT_PTR(s)[i])); + rb_str_append(str, rb_inspect(ptr[i])); } rb_str_cat2(str, ">"); OBJ_INFECT(str, s); @@ -588,14 +600,16 @@ rb_struct_init_copy(VALUE copy, VALUE s) static VALUE rb_struct_aref_id(VALUE s, ID id) { - VALUE members; + VALUE *ptr, members, *ptr_members; long i, len; + ptr = RSTRUCT_PTR(s); members = rb_struct_members(s); + ptr_members = RARRAY_PTR(members); len = RARRAY_LEN(members); for (i=0; i<len; i++) { - if (SYM2ID(RARRAY_PTR(members)[i]) == id) { - return RSTRUCT_PTR(s)[i]; + if (SYM2ID(ptr_members[i]) == id) { + return ptr[i]; } } rb_name_error(id, "no member '%s' in struct", rb_id2name(id)); @@ -644,19 +658,21 @@ rb_struct_aref(VALUE s, VALUE idx) static VALUE rb_struct_aset_id(VALUE s, ID id, VALUE val) { - VALUE members; + VALUE members, *ptr, *ptr_members; long i, len; members = rb_struct_members(s); - rb_struct_modify(s); len = RARRAY_LEN(members); - if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { + rb_struct_modify(s); + if (RSTRUCT_LEN(s) != len) { rb_raise(rb_eTypeError, "struct size differs (%ld required %ld given)", - RARRAY_LEN(members), RSTRUCT_LEN(s)); + len, RSTRUCT_LEN(s)); } + ptr = RSTRUCT_PTR(s); + ptr_members = RARRAY_PTR(members); for (i=0; i<len; i++) { - if (SYM2ID(RARRAY_PTR(members)[i]) == id) { - RSTRUCT_PTR(s)[i] = val; + if (SYM2ID(ptr_members[i]) == id) { + ptr[i] = val; return val; } } @@ -771,11 +787,15 @@ rb_struct_select(int argc, VALUE *argv, VALUE s) static VALUE recursive_equal(VALUE s, VALUE s2, int recur) { - long i; + VALUE *ptr, *ptr2; + long i, len; if (recur) return Qtrue; /* Subtle! */ - for (i=0; i<RSTRUCT_LEN(s); i++) { - if (!rb_equal(RSTRUCT_PTR(s)[i], RSTRUCT_PTR(s2)[i])) return Qfalse; + ptr = RSTRUCT_PTR(s); + ptr2 = RSTRUCT_PTR(s2); + len = RSTRUCT_LEN(s); + for (i=0; i<len; i++) { + if (!rb_equal(ptr[i], ptr2[i])) return Qfalse; } return Qtrue; } @@ -813,14 +833,16 @@ rb_struct_equal(VALUE s, VALUE s2) static VALUE recursive_hash(VALUE s, VALUE dummy, int recur) { - long i; + long i, len; st_index_t h; - VALUE n; + VALUE n, *ptr; h = rb_hash_start(rb_hash(rb_obj_class(s))); if (!recur) { - for (i = 0; i < RSTRUCT_LEN(s); i++) { - n = rb_hash(RSTRUCT_PTR(s)[i]); + ptr = RSTRUCT_PTR(s); + len = RSTRUCT_LEN(s); + for (i = 0; i < len; i++) { + n = rb_hash(ptr[i]); h = rb_hash_uint(h, NUM2LONG(n)); } } @@ -844,11 +866,15 @@ rb_struct_hash(VALUE s) static VALUE recursive_eql(VALUE s, VALUE s2, int recur) { - long i; + VALUE *ptr, *ptr2; + long i, len; if (recur) return Qtrue; /* Subtle! */ - for (i=0; i<RSTRUCT_LEN(s); i++) { - if (!rb_eql(RSTRUCT_PTR(s)[i], RSTRUCT_PTR(s2)[i])) return Qfalse; + ptr = RSTRUCT_PTR(s); + ptr2 = RSTRUCT_PTR(s2); + len = RSTRUCT_LEN(s); + for (i=0; i<len; i++) { + if (!rb_eql(ptr[i], ptr2[i])) return Qfalse; } return Qtrue; } |