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

ruby-changes:31376

From: charliesome <ko1@a...>
Date: Tue, 29 Oct 2013 09:52:48 +0900 (JST)
Subject: [ruby-changes:31376] charliesome:r43455 (trunk): * insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h, vm_method.c: split

charliesome	2013-10-29 09:52:38 +0900 (Tue, 29 Oct 2013)

  New Revision: 43455

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43455

  Log:
    * insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h, vm_method.c: split
      ruby_vm_global_state_version into two separate counters - one for the
      global method state and one for the global constant state. This means
      changes to constants do not affect method caches, and changes to
      methods do not affect constant caches. In particular, this means
      inclusions of modules containing constants no longer globally
      invalidate the method cache.
    
    * class.c, eval.c, include/ruby/intern.h, insns.def, vm.c, vm_method.c:
      rename rb_clear_cache_by_class to rb_clear_method_cache_by_class
    
    * class.c, include/ruby/intern.h, variable.c, vm_method.c: add
      rb_clear_constant_cache
    
    * compile.c, vm_core.h, vm_insnhelper.c: rename vmstat field in
      rb_call_info_struct to method_state
    
    * vm_method.c: rename vmstat field in struct cache_entry to method_state

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/compile.c
    trunk/eval.c
    trunk/include/ruby/intern.h
    trunk/insns.def
    trunk/variable.c
    trunk/vm.c
    trunk/vm_core.h
    trunk/vm_insnhelper.c
    trunk/vm_insnhelper.h
    trunk/vm_method.c
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 43454)
+++ include/ruby/intern.h	(revision 43455)
@@ -376,7 +376,8 @@ void rb_define_alloc_func(VALUE, rb_allo https://github.com/ruby/ruby/blob/trunk/include/ruby/intern.h#L376
 void rb_undef_alloc_func(VALUE);
 rb_alloc_func_t rb_get_alloc_func(VALUE);
 void rb_clear_cache(void);
-void rb_clear_cache_by_class(VALUE);
+void rb_clear_constant_cache(void);
+void rb_clear_method_cache_by_class(VALUE);
 void rb_alias(VALUE, ID, ID);
 void rb_attr(VALUE,ID,int,int,int);
 int rb_method_boundp(VALUE, ID, int);
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 43454)
+++ ChangeLog	(revision 43455)
@@ -1,3 +1,24 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Oct 29 09:53:00 2013  Charlie Somerville  <charliesome@r...>
+
+	* insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h, vm_method.c: split
+	  ruby_vm_global_state_version into two separate counters - one for the
+	  global method state and one for the global constant state. This means
+	  changes to constants do not affect method caches, and changes to
+	  methods do not affect constant caches. In particular, this means
+	  inclusions of modules containing constants no longer globally
+	  invalidate the method cache.
+
+	* class.c, eval.c, include/ruby/intern.h, insns.def, vm.c, vm_method.c:
+	  rename rb_clear_cache_by_class to rb_clear_method_cache_by_class
+
+	* class.c, include/ruby/intern.h, variable.c, vm_method.c: add
+	  rb_clear_constant_cache
+
+	* compile.c, vm_core.h, vm_insnhelper.c: rename vmstat field in
+	  rb_call_info_struct to method_state
+
+	* vm_method.c: rename vmstat field in struct cache_entry to method_state
+
 Mon Oct 28 23:26:04 2013  Tanaka Akira  <akr@f...>
 
 	* test/readline/test_readline.rb (teardown): Clear Readline.input and
Index: insns.def
===================================================================
--- insns.def	(revision 43454)
+++ insns.def	(revision 43455)
@@ -218,7 +218,6 @@ setconstant https://github.com/ruby/ruby/blob/trunk/insns.def#L218
 {
     vm_check_if_namespace(cbase);
     rb_const_set(cbase, id, val);
-    rb_clear_cache_by_class(cbase);
 }
 
 /**
@@ -974,8 +973,6 @@ defineclass https://github.com/ruby/ruby/blob/trunk/insns.def#L973
 		  class_iseq->iseq_encoded, GET_SP(),
 		  class_iseq->local_size, 0, class_iseq->stack_max);
     RESTORE_REGS();
-
-    rb_clear_cache_by_class(klass);
     NEXT_INSN();
 }
 
@@ -1186,7 +1183,7 @@ getinlinecache https://github.com/ruby/ruby/blob/trunk/insns.def#L1183
 ()
 (VALUE val)
 {
-    if (ic->ic_vmstat == GET_VM_STATE_VERSION()) {
+    if (ic->ic_vmstat == GET_CONSTANT_STATE_VERSION()) {
 	val = ic->ic_value.value;
 	JUMP(dst);
     }
@@ -1211,7 +1208,7 @@ setinlinecache https://github.com/ruby/ruby/blob/trunk/insns.def#L1208
 	rb_iseq_add_mark_object(GET_ISEQ(), val);
     }
     ic->ic_value.value = val;
-    ic->ic_vmstat = GET_VM_STATE_VERSION() - ruby_vm_const_missing_count;
+    ic->ic_vmstat = GET_CONSTANT_STATE_VERSION() - ruby_vm_const_missing_count;
     ruby_vm_const_missing_count = 0;
 }
 
Index: variable.c
===================================================================
--- variable.c	(revision 43454)
+++ variable.c	(revision 43455)
@@ -1941,7 +1941,7 @@ rb_const_remove(VALUE mod, ID id) https://github.com/ruby/ruby/blob/trunk/variable.c#L1941
 		      rb_class_name(mod), QUOTE_ID(id));
     }
 
-    rb_clear_cache();
+    rb_clear_constant_cache();
 
     val = ((rb_const_entry_t*)v)->value;
     if (val == Qundef) {
@@ -2151,7 +2151,7 @@ rb_const_set(VALUE klass, ID id, VALUE v https://github.com/ruby/ruby/blob/trunk/variable.c#L2151
 		load = autoload_data(klass, id);
 		/* for autoloading thread, keep the defined value to autoloading storage */
 		if (load && (ele = check_autoload_data(load)) && (ele->thread == rb_thread_current())) {
-		    rb_clear_cache();
+		    rb_clear_constant_cache();
 
 		    ele->value = val; /* autoload_i is shady */
 		    return;
@@ -2175,7 +2175,7 @@ rb_const_set(VALUE klass, ID id, VALUE v https://github.com/ruby/ruby/blob/trunk/variable.c#L2175
 	}
     }
 
-    rb_clear_cache();
+    rb_clear_constant_cache();
 
 
     ce = ALLOC(rb_const_entry_t);
@@ -2222,7 +2222,7 @@ set_const_visibility(VALUE mod, int argc https://github.com/ruby/ruby/blob/trunk/variable.c#L2222
 	id = rb_check_id(&val);
 	if (!id) {
 	    if (i > 0) {
-		rb_clear_cache();
+		rb_clear_constant_cache();
 	    }
 
 	    rb_name_error_str(val, "constant %"PRIsVALUE"::%"PRIsVALUE" not defined",
@@ -2234,13 +2234,13 @@ set_const_visibility(VALUE mod, int argc https://github.com/ruby/ruby/blob/trunk/variable.c#L2234
 	}
 	else {
 	    if (i > 0) {
-		rb_clear_cache();
+		rb_clear_constant_cache();
 	    }
 	    rb_name_error(id, "constant %"PRIsVALUE"::%"PRIsVALUE" not defined",
 			  rb_class_name(mod), QUOTE_ID(id));
 	}
     }
-    rb_clear_cache();
+    rb_clear_constant_cache();
 }
 
 /*
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 43454)
+++ vm_core.h	(revision 43455)
@@ -162,7 +162,7 @@ typedef struct rb_call_info_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L162
     rb_iseq_t *blockiseq;
 
     /* inline cache: keys */
-    vm_state_version_t vmstat;
+    vm_state_version_t method_state;
     vm_state_version_t seq;
     VALUE klass;
 
Index: compile.c
===================================================================
--- compile.c	(revision 43454)
+++ compile.c	(revision 43455)
@@ -961,7 +961,7 @@ new_callinfo(rb_iseq_t *iseq, ID mid, in https://github.com/ruby/ruby/blob/trunk/compile.c#L961
 	    ci->flag |= VM_CALL_ARGS_SKIP_SETUP;
 	}
     }
-    ci->vmstat = 0;
+    ci->method_state = 0;
     ci->seq = 0;
     ci->blockptr = 0;
     ci->recv = Qundef;
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 43454)
+++ vm_method.c	(revision 43455)
@@ -25,7 +25,7 @@ static void rb_vm_check_redefinition_opt https://github.com/ruby/ruby/blob/trunk/vm_method.c#L25
 #define attached            id__attached__
 
 struct cache_entry {
-    vm_state_version_t vm_state;
+    vm_state_version_t method_state;
     vm_state_version_t seq;
     ID mid;
     rb_method_entry_t* me;
@@ -46,15 +46,23 @@ rb_class_clear_method_cache(VALUE klass) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L46
 void
 rb_clear_cache(void)
 {
-    INC_VM_STATE_VERSION();
+    rb_warning("rb_clear_cache() is deprecated.");
+    INC_METHOD_STATE_VERSION();
+    INC_CONSTANT_STATE_VERSION();
 }
 
 void
-rb_clear_cache_by_class(VALUE klass)
+rb_clear_constant_cache(void)
+{
+    INC_CONSTANT_STATE_VERSION();
+}
+
+void
+rb_clear_method_cache_by_class(VALUE klass)
 {
     if (klass && klass != Qundef) {
 	if (klass == rb_cBasicObject || klass == rb_cObject || klass == rb_mKernel) {
-	    INC_VM_STATE_VERSION();
+	    INC_METHOD_STATE_VERSION();
 	}
 	else {
 	    rb_class_clear_method_cache(klass);
@@ -203,7 +211,7 @@ rb_add_refined_method_entry(VALUE refine https://github.com/ruby/ruby/blob/trunk/vm_method.c#L211
 
     if (me) {
 	make_method_entry_refined(me);
-	rb_clear_cache_by_class(refined_class);
+	rb_clear_method_cache_by_class(refined_class);
     }
     else {
 	rb_add_method(refined_class, mid, VM_METHOD_TYPE_REFINED, 0,
@@ -302,7 +310,7 @@ rb_method_entry_make(VALUE klass, ID mid https://github.com/ruby/ruby/blob/trunk/vm_method.c#L310
 
     me = ALLOC(rb_method_entry_t);
 
-    rb_clear_cache_by_class(klass);
+    rb_clear_method_cache_by_class(klass);
 
     me->flag = NOEX_WITH_SAFE(noex);
     me->mark = 0;
@@ -464,7 +472,7 @@ rb_add_method(VALUE klass, ID mid, rb_me https://github.com/ruby/ruby/blob/trunk/vm_method.c#L472
     if (type != VM_METHOD_TYPE_UNDEF && type != VM_METHOD_TYPE_REFINED) {
 	method_added(klass, mid);
     }
-    rb_clear_cache_by_class(klass);
+    rb_clear_method_cache_by_class(klass);
     return me;
 }
 
@@ -542,7 +550,7 @@ rb_method_entry_get_without_cache(VALUE https://github.com/ruby/ruby/blob/trunk/vm_method.c#L550
 	struct cache_entry *ent;
 	ent = GLOBAL_METHOD_CACHE(klass, id);
 	ent->seq = RCLASS_EXT(klass)->seq;
-	ent->vm_state = GET_VM_STATE_VERSION();
+	ent->method_state = GET_METHOD_STATE_VERSION();
 	ent->defined_class = defined_class;
 	ent->mid = id;
 
@@ -580,7 +588,7 @@ rb_method_entry(VALUE klass, ID id, VALU https://github.com/ruby/ruby/blob/trunk/vm_method.c#L588
 #if OPT_GLOBAL_METHOD_CACHE
     struct cache_entry *ent;
     ent = GLOBAL_METHOD_CACHE(klass, id);
-    if (ent->vm_state == GET_VM_STATE_VERSION() &&
+    if (ent->method_state == GET_METHOD_STATE_VERSION() &&
 	ent->seq == RCLASS_EXT(klass)->seq &&
 	ent->mid == id) {
 	if (defined_class_ptr)
@@ -701,7 +709,7 @@ remove_method(VALUE klass, ID mid) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L709
     st_delete(RCLASS_M_TBL(klass), &key, &data);
 
     rb_vm_check_redefinition_opt_method(me, klass);
-    rb_clear_cache_by_class(klass);
+    rb_clear_method_cache_by_class(klass);
     rb_unlink_method_entry(me);
 
     CALL_METHOD_HOOK(self, removed, mid);
@@ -1232,7 +1240,7 @@ rb_alias(VALUE klass, ID name, ID def) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1240
 
     if (flag == NOEX_UNDEF) flag = orig_me->flag;
     rb_method_entry_set(target_klass, name, orig_me, flag);
-    rb_clear_cache_by_class(target_klass);
+    rb_clear_method_cache_by_class(target_klass);
 }
 
 /*
@@ -1287,7 +1295,7 @@ set_method_visibility(VALUE self, int ar https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1295
 	}
 	rb_export_method(self, id, ex);
     }
-    rb_clear_cache_by_class(self);
+    rb_clear_method_cache_by_class(self);
 }
 
 static VALUE
Index: eval.c
===================================================================
--- eval.c	(revision 43454)
+++ eval.c	(revision 43455)
@@ -1263,7 +1263,7 @@ mod_using(VALUE self, VALUE module) https://github.com/ruby/ruby/blob/trunk/eval.c#L1263
     }
     Check_Type(module, T_MODULE);
     rb_using_module(cref, module);
-    rb_clear_cache_by_class(rb_cObject);
+    rb_clear_method_cache_by_class(rb_cObject);
     return self;
 }
 
@@ -1399,7 +1399,7 @@ top_using(VALUE self, VALUE module) https://github.com/ruby/ruby/blob/trunk/eval.c#L1399
     }
     Check_Type(module, T_MODULE);
     rb_using_module(cref, module);
-    rb_clear_cache_by_class(rb_cObject);
+    rb_clear_method_cache_by_class(rb_cObject);
     return self;
 }
 
Index: class.c
===================================================================
--- class.c	(revision 43454)
+++ class.c	(revision 43455)
@@ -900,8 +900,8 @@ include_modules_at(const VALUE klass, VA https://github.com/ruby/ruby/blob/trunk/class.c#L900
 	module = RCLASS_SUPER(module);
     }
 
-    if (method_changed) rb_clear_cache_by_class(klass);
-    if (constant_changed) rb_clear_cache();
+    if (method_changed) rb_clear_method_cache_by_class(klass);
+    if (constant_changed) rb_clear_constant_cache();
 
     return method_changed;
 }
Index: vm.c
===================================================================
--- vm.c	(revision 43454)
+++ vm.c	(revision 43455)
@@ -71,7 +71,8 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm.c#L71
 vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self, VALUE defined_class,
 	       int argc, const VALUE *argv, const rb_block_t *blockptr);
 
-static vm_state_version_t ruby_vm_global_state_version = 1;
+static vm_state_version_t ruby_vm_method_state_version = 1;
+static vm_state_version_t ruby_vm_constant_state_version = 1;
 static vm_state_version_t ruby_vm_sequence = 1;
 
 #include "vm_insnhelper.h"
@@ -2075,12 +2076,12 @@ vm_define_method(rb_thread_t *th, VALUE https://github.com/ruby/ruby/blob/trunk/vm.c#L2076
     OBJ_WRITE(miseq->self, &miseq->klass, klass);
     miseq->defined_method_id = id;
     rb_add_method(klass, id, VM_METHOD_TYPE_ISEQ, miseq, noex);
-    rb_clear_cache_by_class(klass);
+    rb_clear_method_cache_by_class(klass);
 
     if (!is_singleton && noex == NOEX_MODFUNC) {
 	klass = rb_singleton_class(klass);
 	rb_add_method(klass, id, VM_METHOD_TYPE_ISEQ, miseq, NOEX_PUBLIC);
-	rb_clear_cache_by_class(klass);
+	rb_clear_method_cache_by_class(klass);
     }
 }
 
@@ -2130,8 +2131,8 @@ m_core_undef_method(VALUE self, VALUE cb https://github.com/ruby/ruby/blob/trunk/vm.c#L2131
 {
     REWIND_CFP({
 	rb_undef(cbase, SYM2ID(sym));
-	rb_clear_cache_by_class(cbase);
-	rb_clear_cache_by_class(self);
+	rb_clear_method_cache_by_class(cbase);
+	rb_clear_method_cache_by_class(self);
     });
     return Qnil;
 }
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 43454)
+++ vm_insnhelper.c	(revision 43455)
@@ -846,7 +846,7 @@ vm_search_method(rb_call_info_t *ci, VAL https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L846
     VALUE klass = CLASS_OF(recv);
 
 #if OPT_INLINE_METHOD_CACHE
-    if (LIKELY(GET_VM_STATE_VERSION() == ci->vmstat && RCLASS_EXT(klass)->seq == ci->seq)) {
+    if (LIKELY(GET_METHOD_STATE_VERSION() == ci->method_state && RCLASS_EXT(klass)->seq == ci->seq)) {
 	/* cache hit! */
 	return;
     }
@@ -856,7 +856,7 @@ vm_search_method(rb_call_info_t *ci, VAL https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L856
     ci->klass = klass;
     ci->call = vm_call_general;
 #if OPT_INLINE_METHOD_CACHE
-    ci->vmstat = GET_VM_STATE_VERSION();
+    ci->method_state = GET_METHOD_STATE_VERSION();
     ci->seq = RCLASS_EXT(klass)->seq;
 #endif
 }
@@ -924,7 +924,7 @@ rb_equal_opt(VALUE obj1, VALUE obj2) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L924
     rb_call_info_t ci;
     ci.mid = idEq;
     ci.klass = 0;
-    ci.vmstat = 0;
+    ci.method_state = 0;
     ci.me = NULL;
     ci.defined_class = 0;
     return opt_eq_func(obj1, obj2, &ci);
Index: vm_insnhelper.h
===================================================================
--- vm_insnhelper.h	(revision 43454)
+++ vm_insnhelper.h	(revision 43455)
@@ -260,10 +260,10 @@ enum vm_regan_acttype { https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.h#L260
 } while (0)
 
 #define NEXT_CLASS_SEQUENCE() (++ruby_vm_sequence)
-#define GET_VM_STATE_VERSION() (ruby_vm_global_state_version)
-#define INC_VM_STATE_VERSION() do { \
-    ruby_vm_global_state_version = (ruby_vm_global_state_version + 1); \
-} while (0)
+#define GET_METHOD_STATE_VERSION() (ruby_vm_method_state_version)
+#define INC_METHOD_STATE_VERSION() (++ruby_vm_method_state_version)
+#define GET_CONSTANT_STATE_VERSION() (ruby_vm_constant_state_version)
+#define INC_CONSTANT_STATE_VERSION() (++ruby_vm_constant_state_version)
 
 static VALUE make_no_method_exception(VALUE exc, const char *format,
 				      VALUE obj, int argc, const VALUE *argv);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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