ruby-changes:12386
From: ko1 <ko1@a...>
Date: Mon, 13 Jul 2009 18:30:49 +0900 (JST)
Subject: [ruby-changes:12386] Ruby:r24085 (trunk): * vm_core.h, compile.c: declare struct iseq_inline_cache_entry.
ko1 2009-07-13 18:30:23 +0900 (Mon, 13 Jul 2009) New Revision: 24085 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24085 Log: * vm_core.h, compile.c: declare struct iseq_inline_cache_entry. Inline cache (IC) entries are no longer GC managed object. IC entries are freed when ISeq is freed. * iseq.c: fix mark, free, memsize functions for above change. * insns.def: remove rb_gc_write_barrier(). * vm_insnhelper.c (vm_method_search): ditto. * tool/instruction.rb, template/insns_info.inc.tmpl (insn_iclen): added. Modified files: trunk/ChangeLog trunk/compile.c trunk/insns.def trunk/iseq.c trunk/template/insns_info.inc.tmpl trunk/tool/instruction.rb trunk/vm_core.h trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 24084) +++ ChangeLog (revision 24085) @@ -1,3 +1,18 @@ +Mon Jul 13 17:49:11 2009 Koichi Sasada <ko1@a...> + + * vm_core.h, compile.c: declare struct iseq_inline_cache_entry. + Inline cache (IC) entries are no longer GC managed object. + IC entries are freed when ISeq is freed. + + * iseq.c: fix mark, free, memsize functions for above change. + + * insns.def: remove rb_gc_write_barrier(). + + * vm_insnhelper.c (vm_method_search): ditto. + + * tool/instruction.rb, template/insns_info.inc.tmpl (insn_iclen): + added. + Mon Jul 13 13:35:08 2009 Koichi Sasada <ko1@a...> * insns.def, vm_insnhelper.c (getinstancevariable): Index: insns.def =================================================================== --- insns.def (revision 24084) +++ insns.def (revision 24085) @@ -1223,7 +1223,7 @@ { IC ic = GET_CONST_INLINE_CACHE(dst); - ic->ic_value = rb_gc_write_barrier(val); + ic->ic_value = val; ic->ic_vmstat = GET_VM_STATE_VERSION() - ruby_vm_const_missing_count; ruby_vm_const_missing_count = 0; } Index: vm_core.h =================================================================== --- vm_core.h (revision 24084) +++ vm_core.h (revision 24085) @@ -106,6 +106,18 @@ int debug_level; } rb_compile_option_t; +struct iseq_inline_cache_entry { + long ic_vmstat; + VALUE ic_class; + union { + NODE *method; + VALUE value; + } value; +#define ic_value value.value +#define ic_method value.method +#define ic_index ic_vmstat +}; + #if 1 #define GetCoreDataFromValue(obj, type, ptr) do { \ ptr = (type*)DATA_PTR(obj); \ @@ -143,6 +155,9 @@ /* method, class frame: sizeof(vars) + 1, block frame: sizeof(vars) */ int local_size; + struct iseq_inline_cache_entry *ic_entries; + int ic_size; + /** * argument information * @@ -522,13 +537,8 @@ (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC) -/* inline (method|const) cache */ -#define NEW_INLINE_CACHE_ENTRY() NEW_NODE_LONGLIFE(NODE_WHILE, Qundef, 0, 0) -#define ic_class u1.value -#define ic_method u2.node -#define ic_value u2.value -#define ic_vmstat u3.value -typedef NODE *IC; +/* inline cache */ +typedef struct iseq_inline_cache_entry *IC; void rb_vm_change_state(void); Index: iseq.c =================================================================== --- iseq.c (revision 24084) +++ iseq.c (revision 24085) @@ -74,6 +74,7 @@ RUBY_FREE_UNLESS_NULL(iseq->iseq); RUBY_FREE_UNLESS_NULL(iseq->insn_info_table); RUBY_FREE_UNLESS_NULL(iseq->local_table); + RUBY_FREE_UNLESS_NULL(iseq->ic_entries); RUBY_FREE_UNLESS_NULL(iseq->catch_table); RUBY_FREE_UNLESS_NULL(iseq->arg_opt_table); compile_data_free(iseq->compile_data); @@ -86,11 +87,12 @@ static void iseq_mark(void *ptr) { - rb_iseq_t *iseq; RUBY_MARK_ENTER("iseq"); if (ptr) { - iseq = ptr; + int i; + rb_iseq_t *iseq = ptr; + RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename)); RUBY_MARK_UNLESS_NULL(iseq->mark_ary); RUBY_MARK_UNLESS_NULL(iseq->name); @@ -102,6 +104,11 @@ /* RUBY_MARK_UNLESS_NULL(iseq->cached_special_block); */ RUBY_MARK_UNLESS_NULL(iseq->orig); + for (i=0; i<iseq->ic_size; i++) { + RUBY_MARK_UNLESS_NULL(iseq->ic_entries[i].ic_class); + RUBY_MARK_UNLESS_NULL(iseq->ic_entries[i].ic_value); + } + if (iseq->compile_data != 0) { RUBY_MARK_UNLESS_NULL(iseq->compile_data->mark_ary); RUBY_MARK_UNLESS_NULL(iseq->compile_data->err_info); @@ -129,6 +136,7 @@ size += iseq->local_table_size * sizeof(ID); size += iseq->catch_table_size * sizeof(struct iseq_catch_table_entry); size += iseq->arg_opts * sizeof(VALUE); + size += iseq->ic_size * sizeof(struct iseq_inline_cache_entry); if (iseq->compile_data) { struct iseq_compile_data_storage *cur; Index: compile.c =================================================================== --- compile.c (revision 24084) +++ compile.c (revision 24085) @@ -12,6 +12,7 @@ #include "ruby/ruby.h" #define USE_INSN_STACK_INCREASE 1 +#define USE_INSN_ICLEN 1 #include "vm_core.h" #include "iseq.h" #include "insns.inc" @@ -1260,6 +1261,8 @@ struct iseq_insn_info_entry *insn_info_table; LINK_ELEMENT *list; VALUE *generated_iseq; + int ic_size = 0; + int ic_index = 0; int k, pos, sp, stack_max = 0, line = 0; @@ -1273,6 +1276,7 @@ iobj = (INSN *)list; line = iobj->line_no; pos += insn_data_length(iobj); + ic_size += insn_iclen(iobj->insn_id); k++; break; } @@ -1310,6 +1314,9 @@ /* make instruction sequence */ generated_iseq = ALLOC_N(VALUE, pos); insn_info_table = ALLOC_N(struct iseq_insn_info_entry, k); + iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, ic_size); + MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, ic_size); + iseq->ic_size = ic_size; list = FIRST_ELEMENT(anchor); k = pos = sp = 0; @@ -1318,7 +1325,7 @@ switch (list->type) { case ISEQ_ELEMENT_INSN: { - int j, len, insn, iclen = 0, i; + int j, len, insn, iclen = 0; const char *types; VALUE *operands; @@ -1337,13 +1344,8 @@ generated_iseq[pos] = insn; types = insn_op_types(insn); len = insn_len(insn); + iclen = insn_iclen(insn); - for (i=0; i<len; i++) { - if (types[i] == TS_IC) { - iclen++; - } - } - /* operand check */ if (iobj->operand_size + iclen != len - 1) { printf("%d, %d, %d\n", iobj->operand_size, iclen, len); @@ -1432,9 +1434,12 @@ } case TS_IC: /* inline cache */ { - VALUE v = (VALUE)NEW_INLINE_CACHE_ENTRY(); - generated_iseq[pos + 1 + j] = v; - iseq_add_mark_object(iseq, v); + IC ic = &iseq->ic_entries[ic_index++]; + if (UNLIKELY(ic_index > ic_size)) { + rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", + ic_index, ic_size); + } + generated_iseq[pos + 1 + j] = (VALUE)ic; break; } case TS_ID: /* ID */ @@ -5241,8 +5246,6 @@ argv[j] = (VALUE)rb_global_entry(SYM2ID(op)); break; case TS_IC: - argv[j] = (VALUE)NEW_INLINE_CACHE_ENTRY(); - iseq_add_mark_object(iseq, argv[j]); break; case TS_ID: argv[j] = rb_convert_type(op, T_SYMBOL, Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 24084) +++ vm_insnhelper.c (revision 24085) @@ -1180,7 +1180,7 @@ VALUE klass = RBASIC(obj)->klass; if (ic->ic_class == klass) { - long index = ic->ic_vmstat; + long index = ic->ic_index; long len = ROBJECT_NUMIV(obj); VALUE *ptr = ROBJECT_IVPTR(obj); @@ -1199,8 +1199,8 @@ if (index < len) { val = ptr[index]; } - ic->ic_class = CLASS_OF(obj); - ic->ic_vmstat = index; + ic->ic_class = RBASIC(obj)->klass; + ic->ic_index = index; } } } @@ -1231,8 +1231,8 @@ } else { mn = rb_method_node(klass, id); - ic->ic_class = rb_gc_write_barrier(klass); - ic->ic_method = (NODE *)rb_gc_write_barrier((VALUE)mn); + ic->ic_class = klass; + ic->ic_method = mn; ic->ic_vmstat = GET_VM_STATE_VERSION(); } } Index: tool/instruction.rb =================================================================== --- tool/instruction.rb (revision 24084) +++ tool/instruction.rb (revision 24085) @@ -977,6 +977,8 @@ # operands info operands_info = '' operands_num_info = '' + icoperands_num_info = '' + @insns.each{|insn| opes = insn.opes operands_info << ' ' @@ -987,6 +989,12 @@ num = opes.size + 1 operands_num_info << " #{num},\n" + + icnum = 0 + opes.each{|e| + icnum += 1 if e[0] == 'IC' + } + icoperands_num_info << " #{icnum},\n" } # stack num Index: template/insns_info.inc.tmpl =================================================================== --- template/insns_info.inc.tmpl (revision 24084) +++ template/insns_info.inc.tmpl (revision 24085) @@ -23,6 +23,10 @@ <%= operands_num_info %> }; +static const int insn_iclen_info[] = { +<%= icoperands_num_info %> +}; + #ifdef USE_INSN_RET_NUM static const int insn_stack_push_num_info[] = { <%= stack_num_info %> @@ -81,3 +85,11 @@ return insn_stack_push_num_info[insn]; } #endif + +#ifdef USE_INSN_ICLEN +static int +insn_iclen(int insn) +{ + return insn_iclen_info[insn]; +} +#endif -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/