diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-23 07:10:56 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-23 07:10:56 +0000 |
commit | e39eb9dab50eaa681467e51145b37cdc11667830 (patch) | |
tree | b0b1e300f1105da8124013b71adab030b9182ee8 /insnhelper.ci | |
parent | ac41d2774982fcf6f297e71c3e1209a650e44ce7 (diff) | |
download | ruby-e39eb9dab50eaa681467e51145b37cdc11667830.tar.gz |
* compile.c, insns.def, parse.y: fix massign order. This change
causes performance problem. Try vm1_swap benchmark.
[ruby-dev:31522]
* insns.def, insnhelper.ci: move process body of expandarray insn to
vm_expandarray().
* bootstraptest/test_knownbug.rb, bootstraptest/test_massign.rb:
move a solved test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13236 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insnhelper.ci')
-rw-r--r-- | insnhelper.ci | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/insnhelper.ci b/insnhelper.ci index 530ccf97ab..4c52e5b01d 100644 --- a/insnhelper.ci +++ b/insnhelper.ci @@ -1321,6 +1321,64 @@ vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t throw_state, VAL } } +static inline void +vm_expandarray(rb_control_frame_t *cfp, VALUE ary, int num, int flag) +{ + int is_splat = flag & 0x01; + int space_size = num + is_splat; + VALUE *base = cfp->sp, *ptr; + int len; + + cfp->sp += space_size; + + if (TYPE(ary) != T_ARRAY) { + ary = rb_ary_to_ary(ary); + } + ptr = RARRAY_PTR(ary); + len = RARRAY_LEN(ary); + + if (flag & 0x02) { + /* post: ..., nil ,ary[-1], ..., ary[0..-num] # top */ + int i = 0, j; + + if (len < num) { + for (i=0; i<num-len; i++) { + *base++ = Qnil; + } + } + for (j=0; i<num; i++, j++) { + VALUE v = ptr[len - j - 1]; + *base++ = v; + } + if (is_splat) { + *base = rb_ary_new4(len - j, ptr); + } + } + else { + /* normal: ary[num..-1], ary[num-2], ary[num-3], ..., ary[0] # top */ + int i; + VALUE *bptr = &base[space_size - 1]; + + for (i=0; i<num; i++) { + if (len <= i) { + for (; i<num; i++) { + *bptr-- = Qnil; + } + break; + } + *bptr-- = ptr[i]; + } + if (is_splat) { + if (num > len) { + *bptr = rb_ary_new(); + } + else { + *bptr = rb_ary_new4(len - num, ptr + num); + } + } + } +} + static void call_end_proc(VALUE data) { |