ruby-changes:12370
From: ko1 <ko1@a...>
Date: Mon, 13 Jul 2009 13:44:41 +0900 (JST)
Subject: [ruby-changes:12370] Ruby:r24067 (trunk): * insns.def, vm_insnhelper.c (getinstancevariable):
ko1 2009-07-13 13:44:20 +0900 (Mon, 13 Jul 2009) New Revision: 24067 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24067 Log: * insns.def, vm_insnhelper.c (getinstancevariable): fix to use inline cache. * compile.c: fix to skip inline cache entry (IC). IC is added automatically by compiler. * insns.def, vm_insnhelper.h: fix IC positions. * iseq.c: increment minor_version of ISeq because of above change. Modified files: trunk/ChangeLog trunk/compile.c trunk/insns.def trunk/iseq.c trunk/vm_insnhelper.c trunk/vm_insnhelper.h Index: ChangeLog =================================================================== --- ChangeLog (revision 24066) +++ ChangeLog (revision 24067) @@ -1,3 +1,15 @@ +Mon Jul 13 13:35:08 2009 Koichi Sasada <ko1@a...> + + * insns.def, vm_insnhelper.c (getinstancevariable): + fix to use inline cache. + + * compile.c: fix to skip inline cache entry (IC). IC is added + automatically by compiler. + + * insns.def, vm_insnhelper.h: fix IC positions. + + * iseq.c: increment minor_version of ISeq because of above change. + Mon Jul 13 08:01:00 2009 Hidetoshi NAGAI <nagai@a...> * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. Index: insns.def =================================================================== --- insns.def (revision 24066) +++ insns.def (revision 24067) @@ -150,11 +150,11 @@ */ DEFINE_INSN getinstancevariable -(ID id) +(ID id, IC ic) () (VALUE val) { - val = rb_ivar_get(GET_SELF(), id); + val = vm_getivar(GET_SELF(), id, ic); } /** @@ -1175,7 +1175,7 @@ */ DEFINE_INSN getinlinecache -(IC ic, OFFSET dst) +(OFFSET dst, IC ic) () (VALUE val) { @@ -1196,7 +1196,7 @@ */ DEFINE_INSN onceinlinecache -(IC ic, OFFSET dst) +(OFFSET dst, IC ic) () (VALUE val) { Index: iseq.c =================================================================== --- iseq.c (revision 24066) +++ iseq.c (revision 24067) @@ -1294,9 +1294,9 @@ * :catch_table, :bytecode] */ rb_ary_push(val, rb_str_new2("YARVInstructionSequence/SimpleDataFormat")); + rb_ary_push(val, INT2FIX(1)); /* major */ + rb_ary_push(val, INT2FIX(2)); /* minor */ rb_ary_push(val, INT2FIX(1)); - rb_ary_push(val, INT2FIX(1)); - rb_ary_push(val, INT2FIX(1)); rb_ary_push(val, misc); rb_ary_push(val, iseq->name); rb_ary_push(val, iseq->filename); Index: compile.c =================================================================== --- compile.c (revision 24066) +++ compile.c (revision 24067) @@ -899,13 +899,12 @@ { INSN *iobj = 0; VALUE *operands = - (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 5); + (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 4); operands[0] = id; operands[1] = argc; operands[2] = block; operands[3] = flag; - operands[4] = 0; - iobj = new_insn_core(iseq, line_no, BIN(send), 5, operands); + iobj = new_insn_core(iseq, line_no, BIN(send), 4, operands); return iobj; } @@ -1319,7 +1318,7 @@ switch (list->type) { case ISEQ_ELEMENT_INSN: { - int j, len, insn; + int j, len, insn, iclen = 0, i; const char *types; VALUE *operands; @@ -1339,12 +1338,19 @@ types = insn_op_types(insn); len = insn_len(insn); + for (i=0; i<len; i++) { + if (types[i] == TS_IC) { + iclen++; + } + } + /* operand check */ - if (iobj->operand_size != len - 1) { + if (iobj->operand_size + iclen != len - 1) { + printf("%d, %d, %d\n", iobj->operand_size, iclen, len); dump_disasm_list(list); rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no, "operand size miss! (%d for %d)", - iobj->operand_size, len - 1); + iobj->operand_size + iclen, len - 1); xfree(generated_iseq); xfree(insn_info_table); return 0; @@ -1779,22 +1785,6 @@ } static int -insn_set_specialized_instruction_with_ic(INSN *iobj, int insn_id, int n) -{ - int i; - iobj->insn_id = insn_id; - iobj->operand_size = n; - - /* max of n is 4 */ - for (i=0; i<n; i++) { - iobj->operands[i] = Qnil; - } - - return COMPILE_OK; -} - - -static int iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) { if (iobj->insn_id == BIN(send)) { @@ -1813,7 +1803,7 @@ insn_set_specialized_instruction(iobj, BIN(opt_succ)); } else if (mid == idNot) { - insn_set_specialized_instruction_with_ic(iobj, BIN(opt_not), 1); + insn_set_specialized_instruction(iobj, BIN(opt_not)); } } else if (argc == 1) { @@ -1835,10 +1825,10 @@ insn_set_specialized_instruction(iobj, BIN(opt_mod)); } else if (mid == idEq) { - insn_set_specialized_instruction_with_ic(iobj, BIN(opt_eq), 1); + insn_set_specialized_instruction(iobj, BIN(opt_eq)); } else if (mid == idNeq) { - insn_set_specialized_instruction_with_ic(iobj, BIN(opt_neq), 2); + insn_set_specialized_instruction(iobj, BIN(opt_neq)); } else if (mid == idLT) { insn_set_specialized_instruction(iobj, BIN(opt_lt)); @@ -4310,7 +4300,7 @@ LABEL *lend = NEW_LABEL(nd_line(node)); ADD_LABEL(ret, lstart); - ADD_INSN2(ret, nd_line(node), getinlinecache, 0, lend); + ADD_INSN1(ret, nd_line(node), getinlinecache, lend); ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_vid)); ADD_INSN1(ret, nd_line(node), setinlinecache, lstart); ADD_LABEL(ret, lend); @@ -4465,7 +4455,7 @@ LABEL *lend = NEW_LABEL(nd_line(node)); ADD_LABEL(ret, lstart); - ADD_INSN2(ret, nd_line(node), onceinlinecache, 0, lend); + ADD_INSN1(ret, nd_line(node), onceinlinecache, lend); ADD_INSN(ret, nd_line(node), pop); compile_dregx(iseq, ret, node); @@ -4634,7 +4624,7 @@ if (LIST_SIZE_ZERO(pref)) { if (iseq->compile_data->option->inline_const_cache) { ADD_LABEL(ret, lstart); - ADD_INSN2(ret, nd_line(node), getinlinecache, 0, lend); + ADD_INSN1(ret, nd_line(node), getinlinecache, lend); } else { ADD_INSN(ret, nd_line(node), putnil); @@ -4672,7 +4662,7 @@ /* add cache insn */ if (iseq->compile_data->option->inline_const_cache) { ADD_LABEL(ret, lstart); - ADD_INSN2(ret, nd_line(node), getinlinecache, 0, lend); + ADD_INSN1(ret, nd_line(node), getinlinecache, lend); ADD_INSN(ret, nd_line(node), pop); } @@ -4813,7 +4803,7 @@ VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK); ADD_LABEL(ret, lstart); - ADD_INSN2(ret, nd_line(node), onceinlinecache, 0, lend); + ADD_INSN1(ret, nd_line(node), onceinlinecache, lend); ADD_INSN(ret, nd_line(node), pop); ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 24066) +++ vm_insnhelper.c (revision 24067) @@ -1171,6 +1171,53 @@ return klass; } +static VALUE +vm_getivar(VALUE obj, ID id, IC ic) +{ +#if 1 + if (TYPE(obj) == T_OBJECT) { + VALUE val = Qundef; + VALUE klass = RBASIC(obj)->klass; + + if (ic->ic_class == klass) { + long index = ic->ic_vmstat; + long len = ROBJECT_NUMIV(obj); + VALUE *ptr = ROBJECT_IVPTR(obj); + + if (index < len) { + val = ptr[index]; + } + } + else { + st_data_t index; + long len = ROBJECT_NUMIV(obj); + VALUE *ptr = ROBJECT_IVPTR(obj); + struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj); + + if (iv_index_tbl) { + if (st_lookup(iv_index_tbl, id, &index)) { + if (index < len) { + val = ptr[index]; + } + ic->ic_class = CLASS_OF(obj); + ic->ic_vmstat = index; + } + } + } + if (UNLIKELY(val == Qundef)) { + rb_warning("instance variable %s not initialized", rb_id2name(id)); + val = Qnil; + } + return val; + } + else { + return rb_ivar_get(obj, id); + } +#else + return rb_ivar_get(obj, id); +#endif +} + static inline NODE * vm_method_search(VALUE id, VALUE klass, IC ic) { Index: vm_insnhelper.h =================================================================== --- vm_insnhelper.h (revision 24066) +++ vm_insnhelper.h (revision 24067) @@ -140,7 +140,7 @@ #define GET_GLOBAL(entry) rb_gvar_get((struct global_entry*)entry) #define SET_GLOBAL(entry, val) rb_gvar_set((struct global_entry*)entry, val) -#define GET_CONST_INLINE_CACHE(dst) ((IC) * (GET_PC() + (dst) + 1)) +#define GET_CONST_INLINE_CACHE(dst) ((IC) * (GET_PC() + (dst) + 2)) /**********************************************************/ /* deal with values */ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/