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/