mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@24085 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									762f9b28c6
								
							
						
					
					
						commit
						20d9aefccb
					
				
					 8 changed files with 83 additions and 27 deletions
				
			
		
							
								
								
									
										15
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,18 @@
 | 
			
		|||
Mon Jul 13 17:49:11 2009  Koichi Sasada  <ko1@atdot.net>
 | 
			
		||||
 | 
			
		||||
	* 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@atdot.net>
 | 
			
		||||
 | 
			
		||||
	* insns.def, vm_insnhelper.c (getinstancevariable):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								compile.c
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								compile.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
 | 
			
		|||
    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 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
 | 
			
		|||
		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 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
 | 
			
		|||
    /* 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 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
 | 
			
		|||
	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,12 +1344,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
 | 
			
		|||
		generated_iseq[pos] = insn;
 | 
			
		||||
		types = insn_op_types(insn);
 | 
			
		||||
		len = insn_len(insn);
 | 
			
		||||
 | 
			
		||||
		for (i=0; i<len; i++) {
 | 
			
		||||
		    if (types[i] == TS_IC) {
 | 
			
		||||
			iclen++;
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
		iclen = insn_iclen(insn);
 | 
			
		||||
 | 
			
		||||
		/* operand check */
 | 
			
		||||
		if (iobj->operand_size + iclen != len - 1) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1432,9 +1434,12 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
 | 
			
		|||
			}
 | 
			
		||||
		      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 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
 | 
			
		|||
			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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1223,7 +1223,7 @@ setinlinecache
 | 
			
		|||
{
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								iseq.c
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								iseq.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -74,6 +74,7 @@ iseq_free(void *ptr)
 | 
			
		|||
	    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 @@ iseq_free(void *ptr)
 | 
			
		|||
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 @@ iseq_mark(void *ptr)
 | 
			
		|||
/*	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 @@ iseq_memsize(void *ptr)
 | 
			
		|||
	    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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,10 @@ static const int insn_len_info[] = {
 | 
			
		|||
<%= 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 @@ insn_ret_num(int insn)
 | 
			
		|||
  return insn_stack_push_num_info[insn];
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef USE_INSN_ICLEN
 | 
			
		||||
static int
 | 
			
		||||
insn_iclen(int insn)
 | 
			
		||||
{
 | 
			
		||||
    return insn_iclen_info[insn];
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -977,6 +977,8 @@ class RubyVM
 | 
			
		|||
      # operands info
 | 
			
		||||
      operands_info = ''
 | 
			
		||||
      operands_num_info = ''
 | 
			
		||||
      icoperands_num_info = ''
 | 
			
		||||
 | 
			
		||||
      @insns.each{|insn|
 | 
			
		||||
        opes = insn.opes
 | 
			
		||||
        operands_info << '  '
 | 
			
		||||
| 
						 | 
				
			
			@ -987,6 +989,12 @@ class RubyVM
 | 
			
		|||
 | 
			
		||||
        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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								vm_core.h
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								vm_core.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -106,6 +106,18 @@ typedef struct rb_compile_option_struct {
 | 
			
		|||
    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 @@ struct rb_iseq_struct {
 | 
			
		|||
    /* 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 @@ typedef struct {
 | 
			
		|||
  (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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1180,7 +1180,7 @@ vm_getivar(VALUE obj, ID id, IC ic)
 | 
			
		|||
	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 @@ vm_getivar(VALUE obj, ID id, IC ic)
 | 
			
		|||
		    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 @@ vm_method_search(VALUE id, VALUE klass, IC ic)
 | 
			
		|||
	}
 | 
			
		||||
	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();
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue