From 0ac93a1a405d3642a1e73294c04f428c79f5f947 Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 13 Jul 2009 04:44:20 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24067 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 ++++++++++++ compile.c | 50 ++++++++++++++++++++----------------------------- insns.def | 8 ++++---- iseq.c | 4 ++-- vm_insnhelper.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ vm_insnhelper.h | 2 +- 6 files changed, 86 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index d53aaa3a34..2e4ca09db4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Mon Jul 13 13:35:08 2009 Koichi Sasada + + * 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 * ext/tk/extconf.rb: New strategy for searching Tcl/Tk libraries. diff --git a/compile.c b/compile.c index 710e00d612..57d58d2d63 100644 --- a/compile.c +++ b/compile.c @@ -899,13 +899,12 @@ new_insn_send(rb_iseq_t *iseq, int line_no, { 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 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor) 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 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor) types = insn_op_types(insn); len = insn_len(insn); + for (i=0; ioperand_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; @@ -1778,22 +1784,6 @@ insn_set_specialized_instruction(INSN *iobj, int insn_id) return COMPILE_OK; } -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; ioperands[i] = Qnil; - } - - return COMPILE_OK; -} - - static int iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) { @@ -1813,7 +1803,7 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) 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 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) 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 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) /* 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 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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)); diff --git a/insns.def b/insns.def index 363a8ed8c0..d7a06f6a12 100644 --- a/insns.def +++ b/insns.def @@ -150,11 +150,11 @@ setdynamic */ 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 @@ branchunless */ DEFINE_INSN getinlinecache -(IC ic, OFFSET dst) +(OFFSET dst, IC ic) () (VALUE val) { @@ -1196,7 +1196,7 @@ getinlinecache */ DEFINE_INSN onceinlinecache -(IC ic, OFFSET dst) +(OFFSET dst, IC ic) () (VALUE val) { diff --git a/iseq.c b/iseq.c index ac9f572ca4..b01874b98f 100644 --- a/iseq.c +++ b/iseq.c @@ -1294,8 +1294,8 @@ iseq_data_to_ary(rb_iseq_t *iseq) * :catch_table, :bytecode] */ rb_ary_push(val, rb_str_new2("YARVInstructionSequence/SimpleDataFormat")); - rb_ary_push(val, INT2FIX(1)); - rb_ary_push(val, INT2FIX(1)); + rb_ary_push(val, INT2FIX(1)); /* major */ + rb_ary_push(val, INT2FIX(2)); /* minor */ rb_ary_push(val, INT2FIX(1)); rb_ary_push(val, misc); rb_ary_push(val, iseq->name); diff --git a/vm_insnhelper.c b/vm_insnhelper.c index de1f812d24..de53d533b8 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1171,6 +1171,53 @@ vm_get_cvar_base(NODE *cref) 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) { diff --git a/vm_insnhelper.h b/vm_insnhelper.h index 838a652672..d927807c56 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -140,7 +140,7 @@ extern VALUE ruby_vm_const_missing_count; #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 */