[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]