[前][次][番号順一覧][スレッド一覧]

ruby-changes:49969

From: shyouhei <ko1@a...>
Date: Mon, 29 Jan 2018 15:57:00 +0900 (JST)
Subject: [ruby-changes:49969] shyouhei:r62087 (trunk): also use sp_inc in vm core

shyouhei	2018-01-29 15:56:56 +0900 (Mon, 29 Jan 2018)

  New Revision: 62087

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62087

  Log:
    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

  Modified files:
    trunk/insns.def
    trunk/tool/ruby_vm/views/_insn_entry.erb
    trunk/vm_insnhelper.c
    trunk/vm_insnhelper.h
Index: insns.def
===================================================================
--- insns.def	(revision 62086)
+++ insns.def	(revision 62087)
@@ -366,7 +366,6 @@ concatstrings https://github.com/ruby/ruby/blob/trunk/insns.def#L366
 // 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 https://github.com/ruby/ruby/blob/trunk/insns.def#L402
     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 https://github.com/ruby/ruby/blob/trunk/insns.def#L425
 // 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 https://github.com/ruby/ruby/blob/trunk/insns.def#L491
     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 https://github.com/ruby/ruby/blob/trunk/insns.def#L541
 
     INC_SP(n); /* alloca */
     MEMCPY(dst, src, VALUE, n);
+    DEC_SP(n);
 }
 
 /* swap top 2 vals */
@@ -606,7 +603,7 @@ setn https://github.com/ruby/ruby/blob/trunk/insns.def#L603
 (VALUE val)
 // attr rb_snum_t sp_inc = 0;
 {
-    TOPN(n-1) = val;
+    TOPN(n) = val;
 }
 
 /* empty current stack */
@@ -617,7 +614,7 @@ adjuststack https://github.com/ruby/ruby/blob/trunk/insns.def#L614
 (...)
 // attr rb_snum_t sp_inc = -(rb_snum_t)n;
 {
-    DEC_SP(n);
+    /* none */
 }
 
 /**********************************************************/
@@ -757,7 +754,6 @@ opt_newarray_max https://github.com/ruby/ruby/blob/trunk/insns.def#L754
 // 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 https://github.com/ruby/ruby/blob/trunk/insns.def#L764
 // 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 */
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 62086)
+++ vm_insnhelper.c	(revision 62087)
@@ -1235,7 +1235,7 @@ vm_expandarray(rb_control_frame_t *cfp, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1235
 {
     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, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1250
 	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;
Index: vm_insnhelper.h
===================================================================
--- vm_insnhelper.h	(revision 62086)
+++ vm_insnhelper.h	(revision 62087)
@@ -101,6 +101,22 @@ enum vm_regan_acttype { https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.h#L101
 #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)
Index: tool/ruby_vm/views/_insn_entry.erb
===================================================================
--- tool/ruby_vm/views/_insn_entry.erb	(revision 62086)
+++ tool/ruby_vm/views/_insn_entry.erb	(revision 62087)
@@ -21,7 +21,6 @@ INSN_ENTRY(<%= insn.name %>) https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_insn_entry.erb#L21
 % 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 %>) https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_insn_entry.erb#L31
     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 %>) https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_insn_entry.erb#L38
     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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]