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

ruby-changes:25069

From: ko1 <ko1@a...>
Date: Tue, 9 Oct 2012 14:34:10 +0900 (JST)
Subject: [ruby-changes:25069] ko1:r37121 (trunk): * vm_core.h (rb_call_info_t): add new type `rb_call_inf_t'.

ko1	2012-10-09 14:33:54 +0900 (Tue, 09 Oct 2012)

  New Revision: 37121

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37121

  Log:
    * vm_core.h (rb_call_info_t): add new type `rb_call_inf_t'.
      This data structure contains information including inline method
      cache. After that, `struct iseq_inline_cache_entry' does not
      need to contain inline cache for method invocation.
      Other information will be added to this data structure.
    * vm_core.h (rb_iseq_t): add `callinfo_entries' and `callinfo_size'
      members to `rb_iseq_t'.
    * insns.def, compile.c: Use CALL_INFO instead of IC.
    * tool/instruction.rb: support CALL_INFO as operand type.
    * vm_insnhelper.c, vm_insnhelper.h: ditto.

  Modified files:
    trunk/ChangeLog
    trunk/compile.c
    trunk/insns.def
    trunk/tool/instruction.rb
    trunk/vm_core.h
    trunk/vm_insnhelper.c
    trunk/vm_insnhelper.h

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37120)
+++ ChangeLog	(revision 37121)
@@ -1,3 +1,20 @@
+Tue Oct  9 14:28:18 2012  Koichi Sasada  <ko1@a...>
+
+	* vm_core.h (rb_call_info_t): add new type `rb_call_inf_t'.
+	  This data structure contains information including inline method
+	  cache. After that, `struct iseq_inline_cache_entry' does not 
+	  need to contain inline cache for method invocation.
+	  Other information will be added to this data structure.
+
+	* vm_core.h (rb_iseq_t): add `callinfo_entries' and `callinfo_size'
+	  members to `rb_iseq_t'.
+
+	* insns.def, compile.c: Use CALL_INFO instead of IC.
+
+	* tool/instruction.rb: support CALL_INFO as operand type.
+
+	* vm_insnhelper.c, vm_insnhelper.h: ditto.
+
 Sun Oct  7 23:54:33 2012  CHIKANAGA Tomoyuki  <nagachika@r...>
 
 	* ext/zlib/zlib.c (zstream_run_func): don't call inflate() when
Index: insns.def
===================================================================
--- insns.def	(revision 37120)
+++ insns.def	(revision 37121)
@@ -963,7 +963,7 @@
  */
 DEFINE_INSN
 send
-(ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic)
+(ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, CALL_INFO ci)
 (...)
 (VALUE val) // inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
 {
@@ -978,7 +978,7 @@
     /* get receiver */
     recv = TOPN(num);
     klass = CLASS_OF(recv);
-    me = vm_method_search(id, klass, ic, &defined_class);
+    me = vm_method_search(id, klass, ci, &defined_class);
     CALL_METHOD(num, blockptr, flag, id, me, recv, defined_class);
 }
 
@@ -1286,7 +1286,7 @@
  */
 DEFINE_INSN
 opt_plus
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1349,7 +1349,7 @@
  */
 DEFINE_INSN
 opt_minus
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1397,7 +1397,7 @@
  */
 DEFINE_INSN
 opt_mult
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1450,7 +1450,7 @@
  */
 DEFINE_INSN
 opt_div
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1513,7 +1513,7 @@
  */
 DEFINE_INSN
 opt_mod
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1577,11 +1577,11 @@
  */
 DEFINE_INSN
 opt_eq
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
-    val = opt_eq_func(recv, obj, ic);
+    val = opt_eq_func(recv, obj, ci);
 
     if (val == Qundef) {
 	/* other */
@@ -1598,16 +1598,16 @@
  */
 DEFINE_INSN
 opt_neq
-(IC ic, IC ic_eq)
+(CALL_INFO ci, CALL_INFO ci_eq)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
     extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
-    const rb_method_entry_t *me = vm_method_search(idNeq, CLASS_OF(recv), ic, 0);
+    const rb_method_entry_t *me = vm_method_search(idNeq, CLASS_OF(recv), ci, 0);
     val = Qundef;
 
     if (check_cfunc(me, rb_obj_not_equal)) {
-	val = opt_eq_func(recv, obj, ic_eq);
+	val = opt_eq_func(recv, obj, ci_eq);
 
 	if (val != Qundef) {
 	    val = RTEST(val) ? Qfalse : Qtrue;
@@ -1629,7 +1629,7 @@
  */
 DEFINE_INSN
 opt_lt
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1673,7 +1673,7 @@
  */
 DEFINE_INSN
 opt_le
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1708,7 +1708,7 @@
  */
 DEFINE_INSN
 opt_gt
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1752,7 +1752,7 @@
  */
 DEFINE_INSN
 opt_ge
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1786,7 +1786,7 @@
  */
 DEFINE_INSN
 opt_ltlt
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1818,7 +1818,7 @@
  */
 DEFINE_INSN
 opt_aref
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
@@ -1848,7 +1848,7 @@
  */
 DEFINE_INSN
 opt_aset
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv, VALUE obj, VALUE set)
 (VALUE val)
 {
@@ -1881,7 +1881,7 @@
  */
 DEFINE_INSN
 opt_length
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv)
 (VALUE val)
 {
@@ -1916,7 +1916,7 @@
  */
 DEFINE_INSN
 opt_size
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv)
 (VALUE val)
 {
@@ -1951,7 +1951,7 @@
  */
 DEFINE_INSN
 opt_empty_p
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv)
 (VALUE val)
 {
@@ -1989,7 +1989,7 @@
  */
 DEFINE_INSN
 opt_succ
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv)
 (VALUE val)
 {
@@ -2036,12 +2036,12 @@
  */
 DEFINE_INSN
 opt_not
-(IC ic)
+(CALL_INFO ci)
 (VALUE recv)
 (VALUE val)
 {
     extern VALUE rb_obj_not(VALUE obj);
-    const rb_method_entry_t *me = vm_method_search(idNot, CLASS_OF(recv), ic, 0);
+    const rb_method_entry_t *me = vm_method_search(idNot, CLASS_OF(recv), ci, 0);
 
     if (check_cfunc(me, rb_obj_not)) {
 	val = RTEST(recv) ? Qfalse : Qtrue;
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 37120)
+++ vm_core.h	(revision 37121)
@@ -134,14 +134,21 @@
     VALUE ic_class;
     union {
 	VALUE value;
-	rb_method_entry_t *method;
 	long index;
     } ic_value;
-    union {
-	VALUE defined_class;
-    } ic_value2;
 };
 
+/* rb_call_info_t contains calling information including inline cache */
+typedef struct rb_call_info_struct {
+    /* inline cache: keys */
+    VALUE ic_vmstat;
+    VALUE ic_class;
+
+    /* inline cache: values */
+    rb_method_entry_t *method;
+    VALUE defined_class;
+} rb_call_info_t;
+
 #if 1
 #define GetCoreDataFromValue(obj, type, ptr) do { \
     (ptr) = (type*)DATA_PTR(obj); \
@@ -201,6 +208,9 @@
     struct iseq_inline_cache_entry *ic_entries;
     int ic_size;
 
+    rb_call_info_t *callinfo_entries;
+    int callinfo_size;
+
     /**
      * argument information
      *
@@ -661,6 +671,7 @@
 
 /* inline cache */
 typedef struct iseq_inline_cache_entry *IC;
+typedef rb_call_info_t *CALL_INFO;
 
 void rb_vm_change_state(void);
 
Index: compile.c
===================================================================
--- compile.c	(revision 37120)
+++ compile.c	(revision 37121)
@@ -946,7 +946,7 @@
     operands[1] = argc;
     operands[2] = block;
     operands[3] = flag;
-    operands[4] = INT2FIX(iseq->ic_size++);
+    operands[4] = INT2FIX(iseq->callinfo_size++);
     iobj = new_insn_core(iseq, line_no, BIN(send), 5, operands);
     return iobj;
 }
@@ -1398,6 +1398,8 @@
     line_info_table = ALLOC_N(struct iseq_line_info_entry, k);
     iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, iseq->ic_size);
     MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, iseq->ic_size);
+    iseq->callinfo_entries = ALLOC_N(rb_call_info_t, iseq->callinfo_size);
+    MEMZERO(iseq->callinfo_entries, rb_call_info_t, iseq->callinfo_size);
 
     list = FIRST_ELEMENT(anchor);
     k = pos = sp = 0;
@@ -1495,12 +1497,21 @@
 			    int ic_index = FIX2INT(operands[j]);
 			    IC ic = &iseq->ic_entries[ic_index];
 			    if (UNLIKELY(ic_index >= iseq->ic_size)) {
-				rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d",
-				       ic_index, iseq->ic_size);
+				rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->ic_size);
 			    }
 			    generated_iseq[pos + 1 + j] = (VALUE)ic;
 			    break;
 			}
+		      case TS_CALLINFO: /* call info */
+			{
+			    int ci_index = FIX2INT(operands[j]);
+			    CALL_INFO ci = &iseq->callinfo_entries[ci_index];
+			    if (UNLIKELY(ci_index >= iseq->callinfo_size)) {
+				rb_bug("iseq_set_sequence: ci_index overflow: index: %d, size: %d", ci_index, iseq->callinfo_size);
+			    }
+			    generated_iseq[pos + 1 + j] = (VALUE)ci;
+			    break;
+			}
 		      case TS_ID: /* ID */
 			generated_iseq[pos + 1 + j] = SYM2ID(operands[j]);
 			break;
@@ -1859,7 +1870,7 @@
     }
 
     for (i=0; i<iobj->operand_size; i++) {
-	iobj->operands[i] = INT2FIX(iseq->ic_size++);
+	iobj->operands[i] = INT2FIX(iseq->callinfo_size++);
     }
 
     return COMPILE_OK;
@@ -5234,9 +5245,12 @@
 		      (OPERAND_AT(iobj, j) & (~1));
 		    rb_str_cat2(str, rb_id2name(entry->id));
 		}
-	      case TS_IC:	/* method cache */
+	      case TS_IC:	/* inline cache */
 		rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
 		break;
+	      case TS_CALLINFO: /* call info */
+		rb_str_catf(str, "<callinfo:%d>", FIX2INT(OPERAND_AT(iobj, j)));
+		break;
 	      case TS_CDHASH:	/* case/when condition cache */
 		rb_str_cat2(str, "<ch>");
 		break;
@@ -5500,9 +5514,15 @@
 			break;
 		      case TS_IC:
 			argv[j] = op;
-			if (NUM2INT(op) >= iseq->ic_size)
+			if (NUM2INT(op) >= iseq->ic_size) {
 			    iseq->ic_size = NUM2INT(op) + 1;
+			}
 			break;
+		      case TS_CALLINFO:
+			argv[j] = op;
+			if (NUM2INT(op) >= iseq->callinfo_size) {
+			    iseq->callinfo_size = NUM2INT(op) + 1;
+			}
 		      case TS_ID:
 			argv[j] = rb_convert_type(op, T_SYMBOL,
 						  "Symbol", "to_sym");
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 37120)
+++ vm_insnhelper.c	(revision 37121)
@@ -1430,25 +1430,27 @@
 }
 
 static inline const rb_method_entry_t *
-vm_method_search(VALUE id, VALUE klass, IC ic, VALUE *defined_class_ptr)
+vm_method_search(VALUE id, VALUE klass, CALL_INFO ci, VALUE *defined_class_ptr)
 {
     rb_method_entry_t *me;
 #if OPT_INLINE_METHOD_CACHE
-    if (LIKELY(klass == ic->ic_class &&
-	GET_VM_STATE_VERSION() == ic->ic_vmstat)) {
-	me = ic->ic_value.method;
-	if (defined_class_ptr)
-	    *defined_class_ptr = ic->ic_value2.defined_class;
+    if (LIKELY(klass == ci->ic_class &&
+	GET_VM_STATE_VERSION() == ci->ic_vmstat)) {
+	me = ci->method;
+	if (defined_class_ptr) {
+	    *defined_class_ptr = ci->defined_class;
+	}
     }
     else {
 	VALUE defined_class;
 	me = rb_method_entry(klass, id, &defined_class);
-	if (defined_class_ptr)
+	if (defined_class_ptr) {
 	    *defined_class_ptr = defined_class;
-	ic->ic_class = klass;
-	ic->ic_value.method = me;
-	ic->ic_value2.defined_class = defined_class;
-	ic->ic_vmstat = GET_VM_STATE_VERSION();
+	}
+	ci->ic_class = klass;
+	ci->method = me;
+	ci->defined_class = defined_class;
+	ci->ic_vmstat = GET_VM_STATE_VERSION();
     }
 #else
     me = rb_method_entry(klass, id, defined_class_ptr);
@@ -1773,7 +1775,7 @@
 inline
 #endif
 VALUE
-opt_eq_func(VALUE recv, VALUE obj, IC ic)
+opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci)
 {
     if (FIXNUM_2_P(recv, obj) &&
 	BASIC_OP_UNREDEFINED_P(BOP_EQ, FIXNUM_REDEFINED_OP_FLAG)) {
@@ -1803,7 +1805,7 @@
     }
 
     {
-	const rb_method_entry_t *me = vm_method_search(idEq, CLASS_OF(recv), ic, 0);
+	const rb_method_entry_t *me = vm_method_search(idEq, CLASS_OF(recv), ci, 0);
 
 	if (check_cfunc(me, rb_obj_equal)) {
 	    return recv == obj ? Qtrue : Qfalse;
Index: vm_insnhelper.h
===================================================================
--- vm_insnhelper.h	(revision 37120)
+++ vm_insnhelper.h	(revision 37121)
@@ -239,7 +239,7 @@
 
 #define CALL_SIMPLE_METHOD(num, id, recv) do { \
     VALUE klass = CLASS_OF(recv), defined_class; \
-    const rb_method_entry_t *me = vm_method_search((id), klass, ic, &defined_class); \
+    const rb_method_entry_t *me = vm_method_search((id), klass, ci, &defined_class); \
     CALL_METHOD((num), 0, 0, (id), me, (recv), defined_class); \
 } while (0)
 
Index: tool/instruction.rb
===================================================================
--- tool/instruction.rb	(revision 37120)
+++ tool/instruction.rb	(revision 37121)
@@ -706,10 +706,13 @@
           break
         end
 
+        # skip make operands when body has no reference to this operand
+        # TODO: really needed?
         re = /\b#{var}\b/n
-        if re =~ insn.body or re =~ insn.sp_inc or insn.rets.any?{|t, v| re =~ v} or re =~ 'ic'
+        if re =~ insn.body or re =~ insn.sp_inc or insn.rets.any?{|t, v| re =~ v} or re =~ 'ic' or re =~ 'ci'
           ops << "  #{type} #{var} = (#{type})GET_OPERAND(#{i+1});"
         end
+
         n   += 1
       }
       @opn = n
@@ -938,6 +941,8 @@
         "TS_GENTRY"
       when /^IC/
         "TS_IC"
+      when /^CALL_INFO/
+        "TS_CALLINFO"
       when /^\.\.\./
         "TS_VARIABLE"
       when /^CDHASH/
@@ -958,7 +963,8 @@
       'TS_VALUE'     => 'V',
       'TS_ID'        => 'I',
       'TS_GENTRY'    => 'G',
-      'TS_IC'        => 'C',
+      'TS_IC'        => 'K',
+      'TS_CALLINFO'  => 'C',
       'TS_CDHASH'    => 'H',
       'TS_ISEQ'      => 'S',
       'TS_VARIABLE'  => '.',

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

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