diff options
author | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-01-29 06:56:56 +0000 |
---|---|---|
committer | shyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-01-29 06:56:56 +0000 |
commit | 7d4ad74f22fa259ee81064970fa12d9942472c13 (patch) | |
tree | 2eb4d97272327fcf9a288f1c1613446279d503a6 | |
parent | 592dcccdf9144a70d1dc9452034c5a583ea8be4a (diff) | |
download | ruby-7d4ad74f22fa259ee81064970fa12d9942472c13.tar.gz |
also use sp_inc in vm core
Now that sp_inc attributes are officially provided as inline
functions. Why not use them directly from the vm core, not just
by the compiler. By doing so, it is now possible for us to
optimize stack manipulations. We can now know exactly how many
words of stack space an instruction consumes before it actually
does. This changeset deletes some lines from insns.def because
they are no longer needed. As a result it reduces the size of
vm_exec_core function from 32,400 bytes to 32,352 bytes on my
machine.
It seems it does not affect performance:
-----------------------------------------------------------
benchmark results:
minimum results in each 3 measurements.
Execution time (sec)
name before after
loop_for 1.093 1.061
loop_generator 1.156 1.152
loop_times 0.982 0.974
loop_whileloop 0.549 0.587
loop_whileloop2 0.115 0.121
Speedup ratio: compare with the result of `before' (greater is better)
name after
loop_for 1.030
loop_generator 1.003
loop_times 1.008
loop_whileloop 0.935
loop_whileloop2 0.949
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62087 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | insns.def | 11 | ||||
-rw-r--r-- | tool/ruby_vm/views/_insn_entry.erb | 14 | ||||
-rw-r--r-- | vm_insnhelper.c | 4 | ||||
-rw-r--r-- | vm_insnhelper.h | 16 |
4 files changed, 27 insertions, 18 deletions
@@ -366,7 +366,6 @@ concatstrings // attr rb_snum_t sp_inc = 1 - num; { val = rb_str_concat_literals(num, STACK_ADDR_FROM_TOP(num)); - POPN(num); } /* push the result of to_s. */ @@ -403,7 +402,6 @@ toregexp VALUE rb_reg_new_ary(VALUE ary, int options); VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *); const VALUE ary = rb_ary_tmp_new_from_values(0, cnt, STACK_ADDR_FROM_TOP(cnt)); - POPN(cnt); val = rb_reg_new_ary(ary, (int)opt); rb_ary_clear(ary); } @@ -427,7 +425,6 @@ newarray // attr rb_snum_t sp_inc = 1 - num; { val = rb_ary_new4(num, STACK_ADDR_FROM_TOP(num)); - POPN(num); } /* dup array */ @@ -494,7 +491,6 @@ newhash if (num) { rb_hash_bulk_insert(num, STACK_ADDR_FROM_TOP(num), val); } - POPN(num); } /* put new Range object.(Range.new(low, high, flag)) */ @@ -545,6 +541,7 @@ dupn INC_SP(n); /* alloca */ MEMCPY(dst, src, VALUE, n); + DEC_SP(n); } /* swap top 2 vals */ @@ -606,7 +603,7 @@ setn (VALUE val) // attr rb_snum_t sp_inc = 0; { - TOPN(n-1) = val; + TOPN(n) = val; } /* empty current stack */ @@ -617,7 +614,7 @@ adjuststack (...) // attr rb_snum_t sp_inc = -(rb_snum_t)n; { - DEC_SP(n); + /* none */ } /**********************************************************/ @@ -757,7 +754,6 @@ opt_newarray_max // attr rb_snum_t sp_inc = 1 - num; { val = vm_opt_newarray_max(num, STACK_ADDR_FROM_TOP(num)); - POPN(num); } DEFINE_INSN @@ -768,7 +764,6 @@ opt_newarray_min // attr rb_snum_t sp_inc = 1 - num; { val = vm_opt_newarray_min(num, STACK_ADDR_FROM_TOP(num)); - POPN(num); } /* Invoke method without block */ diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb index 708f637f83..2118dece86 100644 --- a/tool/ruby_vm/views/_insn_entry.erb +++ b/tool/ruby_vm/views/_insn_entry.erb @@ -21,7 +21,6 @@ INSN_ENTRY(<%= insn.name %>) % insn.preamble.each do |konst| <%= render_c_expr konst -%> % end -% % insn.opes.each_with_index do |ope, i| <%= ope[:name] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>); % end @@ -32,8 +31,6 @@ INSN_ENTRY(<%= insn.name %>) DEBUG_ENTER_INSN(INSN_ATTR(name)); % if insn.handles_frame? ADD_PC(INSN_ATTR(width)); -% end -% unless insn.pops.empty? POPN(INSN_ATTR(popn)); % end COLLECT_USAGE_INSN(INSN_ATTR(bin)); @@ -41,13 +38,16 @@ INSN_ENTRY(<%= insn.name %>) COLLECT_USAGE_OPERAND(INSN_ATTR(bin), <%= i %>, <%= ope[:name] %>); % end <%= render_c_expr insn.expr -%> -% unless insn.rets.empty? CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, INSN_ATTR(retn)); -% insn.rets.each_with_index do |ret, i| +% if insn.handles_frame? +% insn.rets.reverse_each do |ret| PUSH(<%= insn.cast_to_VALUE ret %>); % end -% end -% unless insn.handles_frame? +% else + ADJ_SP(INSN_ATTR(sp_inc)); +% insn.rets.reverse_each.with_index do |ret, i| + TOPN(<%= i %>) = <%= insn.cast_to_VALUE ret %>; +% end ADD_PC(INSN_ATTR(width)); PREFETCH(GET_PC()); % end diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 9903bcc176..acb7d7999d 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1235,7 +1235,7 @@ vm_expandarray(rb_control_frame_t *cfp, VALUE ary, rb_num_t num, int flag) { int is_splat = flag & 0x01; rb_num_t space_size = num + is_splat; - VALUE *base = cfp->sp; + VALUE *base = cfp->sp - 1; const VALUE *ptr; rb_num_t len; const VALUE obj = ary; @@ -1250,8 +1250,6 @@ vm_expandarray(rb_control_frame_t *cfp, VALUE ary, rb_num_t num, int flag) len = (rb_num_t)RARRAY_LEN(ary); } - cfp->sp += space_size; - if (flag & 0x02) { /* post: ..., nil ,ary[-1], ..., ary[0..-num] # top */ rb_num_t i = 0, j; diff --git a/vm_insnhelper.h b/vm_insnhelper.h index 71ca408bf2..0fc31d2cea 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -101,6 +101,22 @@ enum vm_regan_acttype { #define DEC_SP(x) (VM_REG_SP -= (COLLECT_USAGE_REGISTER_HELPER(SP, SET, (x)))) #define SET_SV(x) (*GET_SP() = (x)) /* set current stack value as x */ +#ifdef _MSC_VER +/* Workaround needed for adding negative number to a pointer */ +#define ADJ_SP(x) do { \ + rb_snum_t adj = (x); \ + if (adj >= 0) { \ + INC_SP(adj); \ + } \ + else { \ + SIGNED_VALUE dec = -1; \ + dec *= adj; \ + DEC_SP(dec); \ + } \ +} while (0) +#else +#define ADJ_SP(x) INC_SP(x) +#endif /* instruction sequence C struct */ #define GET_ISEQ() (GET_CFP()->iseq) |