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

ruby-changes:40019

From: ko1 <ko1@a...>
Date: Sat, 10 Oct 2015 18:36:31 +0900 (JST)
Subject: [ruby-changes:40019] ko1:r52100 (trunk): * vm_insnhelper.c (vm_call_method0): do not propagate enable_fastpath,

ko1	2015-10-10 18:36:10 +0900 (Sat, 10 Oct 2015)

  New Revision: 52100

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

  Log:
    * vm_insnhelper.c (vm_call_method0): do not propagate enable_fastpath,
      but pass dummy CC to prevent wrong caching.

  Modified files:
    trunk/ChangeLog
    trunk/vm_insnhelper.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 52099)
+++ ChangeLog	(revision 52100)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Oct 10 18:35:12 2015  Koichi Sasada  <ko1@a...>
+
+	* vm_insnhelper.c (vm_call_method0): do not propagate enable_fastpath,
+	  but pass dummy CC to prevent wrong caching.
+
 Sat Oct 10 15:28:45 2015  Koichi Sasada  <ko1@a...>
 
 	* import a github pull request
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 52099)
+++ vm_insnhelper.c	(revision 52100)
@@ -1237,12 +1237,11 @@ static inline VALUE vm_call_iseq_setup_n https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1237
 static inline VALUE vm_call_iseq_setup_tailcall(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, int opt_pc);
 static VALUE vm_call_iseq_setup_normal_0start(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
 static VALUE vm_call_iseq_setup_tailcall_0start(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
+
 static VALUE vm_call_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
 static VALUE vm_call_method_nome(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
-static VALUE vm_call_method0(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc,
-			     const int enable_fastpath);
-static VALUE vm_call_method_each_type(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc,
-				      const int enable_fastpath);
+static VALUE vm_call_method_each_type(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
+static inline VALUE vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc);
 
 static rb_method_definition_t *method_definition_create(rb_method_type_t type, ID mid);
 static void method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts);
@@ -1836,7 +1835,7 @@ vm_call_opt_send(rb_thread_t *th, rb_con https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1835
 
     cc->me = rb_callable_method_entry_without_refinements(CLASS_OF(calling->recv), ci->mid);
     ci->flag = VM_CALL_FCALL | VM_CALL_OPT_SEND;
-    return vm_call_method0(th, reg_cfp, calling, ci, cc, FALSE);
+    return vm_call_method(th, reg_cfp, calling, ci, cc);
 }
 
 static VALUE
@@ -1889,17 +1888,17 @@ vm_call_method_missing(rb_thread_t *th, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1888
     INC_SP(1);
 
     th->method_missing_reason = orig_cc->aux.method_missing_reason;
-    return vm_call_method0(th, reg_cfp, calling, ci, cc, FALSE);
+    return vm_call_method(th, reg_cfp, calling, ci, cc);
 }
 
 static VALUE
-vm_call_zsuper(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const int enable_fastpath, VALUE klass)
+vm_call_zsuper(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE klass)
 {
     klass = RCLASS_SUPER(klass);
     cc->me = klass ? rb_callable_method_entry(klass, ci->mid) : NULL;
 
     if (cc->me != NULL) {
-	return vm_call_method_each_type(th, cfp, calling, ci, cc, enable_fastpath);
+	return vm_call_method_each_type(th, cfp, calling, ci, cc);
     }
     else {
 	return vm_call_method_nome(th, cfp, calling, ci, cc);
@@ -2000,53 +1999,53 @@ refined_method_callable_without_refineme https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1999
 }
 
 static VALUE
-vm_call_method_each_type(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const int enable_fastpath)
+vm_call_method_each_type(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc)
 {
     switch (cc->me->def->type) {
       case VM_METHOD_TYPE_ISEQ:
-	CI_SET_FASTPATH(cc, vm_call_iseq_setup, enable_fastpath);
+	CI_SET_FASTPATH(cc, vm_call_iseq_setup, TRUE);
 	return vm_call_iseq_setup(th, cfp, calling, ci, cc);
 
       case VM_METHOD_TYPE_NOTIMPLEMENTED:
       case VM_METHOD_TYPE_CFUNC:
-	CI_SET_FASTPATH(cc, vm_call_cfunc, enable_fastpath);
+	CI_SET_FASTPATH(cc, vm_call_cfunc, TRUE);
 	return vm_call_cfunc(th, cfp, calling, ci, cc);
 
       case VM_METHOD_TYPE_ATTRSET:
 	CALLER_SETUP_ARG(cfp, calling, ci);
 	rb_check_arity(calling->argc, 1, 1);
 	cc->aux.index = 0;
-	CI_SET_FASTPATH(cc, vm_call_attrset, enable_fastpath && !(ci->flag & VM_CALL_ARGS_SPLAT));
+	CI_SET_FASTPATH(cc, vm_call_attrset, !(ci->flag & VM_CALL_ARGS_SPLAT));
 	return vm_call_attrset(th, cfp, calling, ci, cc);
 
       case VM_METHOD_TYPE_IVAR:
 	CALLER_SETUP_ARG(cfp, calling, ci);
 	rb_check_arity(calling->argc, 0, 0);
 	cc->aux.index = 0;
-	CI_SET_FASTPATH(cc, vm_call_ivar, enable_fastpath && !(ci->flag & VM_CALL_ARGS_SPLAT));
+	CI_SET_FASTPATH(cc, vm_call_ivar, !(ci->flag & VM_CALL_ARGS_SPLAT));
 	return vm_call_ivar(th, cfp, calling, ci, cc);
 
       case VM_METHOD_TYPE_MISSING:
 	cc->aux.method_missing_reason = 0;
-	CI_SET_FASTPATH(cc, vm_call_method_missing, enable_fastpath);
+	CI_SET_FASTPATH(cc, vm_call_method_missing, TRUE);
 	return vm_call_method_missing(th, cfp, calling, ci, cc);
 
       case VM_METHOD_TYPE_BMETHOD:
-	CI_SET_FASTPATH(cc, vm_call_bmethod, enable_fastpath);
+	CI_SET_FASTPATH(cc, vm_call_bmethod, TRUE);
 	return vm_call_bmethod(th, cfp, calling, ci, cc);
 
       case VM_METHOD_TYPE_ALIAS:
 	cc->me = aliased_callable_method_entry(cc->me);
 	VM_ASSERT(cc->me != NULL);
-	return vm_call_method_each_type(th, cfp, calling, ci, cc, enable_fastpath);
+	return vm_call_method_each_type(th, cfp, calling, ci, cc);
 
       case VM_METHOD_TYPE_OPTIMIZED:
 	switch (cc->me->def->body.optimize_type) {
 	  case OPTIMIZED_METHOD_TYPE_SEND:
-	    CI_SET_FASTPATH(cc, vm_call_opt_send, enable_fastpath);
+	    CI_SET_FASTPATH(cc, vm_call_opt_send, TRUE);
 	    return vm_call_opt_send(th, cfp, calling, ci, cc);
 	  case OPTIMIZED_METHOD_TYPE_CALL:
-	    CI_SET_FASTPATH(cc, vm_call_opt_call, enable_fastpath);
+	    CI_SET_FASTPATH(cc, vm_call_opt_call, TRUE);
 	    return vm_call_opt_call(th, cfp, calling, ci, cc);
 	  default:
 	    rb_bug("vm_call_method: unsupported optimized method type (%d)",
@@ -2057,7 +2056,7 @@ vm_call_method_each_type(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2056
 	break;
 
       case VM_METHOD_TYPE_ZSUPER:
-	return vm_call_zsuper(th, cfp, calling, ci, cc, enable_fastpath, RCLASS_ORIGIN(cc->me->owner));
+	return vm_call_zsuper(th, cfp, calling, ci, cc, RCLASS_ORIGIN(cc->me->owner));
 
       case VM_METHOD_TYPE_REFINED: {
 	  const rb_cref_t *cref = rb_vm_get_cref(cfp->ep);
@@ -2082,7 +2081,7 @@ vm_call_method_each_type(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2081
 	      }
 	      cc->me = ref_me;
 	      if (ref_me->def->type != VM_METHOD_TYPE_REFINED) {
-		  return vm_call_method0(th, cfp, calling, ci, cc, enable_fastpath);
+		  return vm_call_method(th, cfp, calling, ci, cc);
 	      }
 	  }
 	  else {
@@ -2097,10 +2096,10 @@ vm_call_method_each_type(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2096
 	      if (UNDEFINED_METHOD_ENTRY_P(cc->me)) {
 		  cc->me = NULL;
 	      }
-	      return vm_call_method0(th, cfp, calling, ci, cc, enable_fastpath);
+	      return vm_call_method(th, cfp, calling, ci, cc);
 	  }
 	  else {
-	      return vm_call_zsuper(th, cfp, calling, ci, cc, enable_fastpath, cc->me->owner);
+	      return vm_call_zsuper(th, cfp, calling, ci, cc, cc->me->owner);
 	  }
       }
     }
@@ -2109,14 +2108,32 @@ vm_call_method_each_type(rb_thread_t *th https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2108
 }
 
 static VALUE
-vm_call_method0(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc, const int enable_fastpath)
+vm_call_method_nome(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc)
+{
+    /* method missing */
+    const int stat = ci_missing_reason(ci);
+
+    if (ci->mid == idMethodMissing) {
+	rb_control_frame_t *reg_cfp = cfp;
+	VALUE *argv = STACK_ADDR_FROM_TOP(calling->argc);
+	rb_raise_method_missing(th, calling->argc, argv, calling->recv, stat);
+    }
+    else {
+	cc->aux.method_missing_reason = stat;
+	CI_SET_FASTPATH(cc, vm_call_method_missing, 1);
+	return vm_call_method_missing(th, cfp, calling, ci, cc);
+    }
+}
+
+static inline VALUE
+vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc)
 {
     VM_ASSERT(callable_method_entry_p(cc->me));
 
     if (cc->me != NULL) {
 	switch (METHOD_ENTRY_VISI(cc->me)) {
 	  case METHOD_VISI_PUBLIC: /* likely */
-	    return vm_call_method_each_type(th, cfp, calling, ci, cc, enable_fastpath);
+	    return vm_call_method_each_type(th, cfp, calling, ci, cc);
 
 	  case METHOD_VISI_PRIVATE:
 	    if (!(ci->flag & VM_CALL_FCALL)) {
@@ -2127,7 +2144,7 @@ vm_call_method0(rb_thread_t *th, rb_cont https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2144
 		CI_SET_FASTPATH(cc, vm_call_method_missing, 1);
 		return vm_call_method_missing(th, cfp, calling, ci, cc);
 	    }
-	    return vm_call_method_each_type(th, cfp, calling, ci, cc, enable_fastpath);
+	    return vm_call_method_each_type(th, cfp, calling, ci, cc);
 
 	  case METHOD_VISI_PROTECTED:
 	    if (!(ci->flag & VM_CALL_OPT_SEND)) {
@@ -2136,11 +2153,16 @@ vm_call_method0(rb_thread_t *th, rb_cont https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2153
 		    return vm_call_method_missing(th, cfp, calling, ci, cc);
 		}
 		else {
+		    /* caching method info to dummy cc */
+		    struct rb_call_cache cc_entry;
+		    cc_entry = *cc;
+		    cc = &cc_entry;
+
 		    VM_ASSERT(cc->me != NULL);
-		    return vm_call_method_each_type(th, cfp, calling, ci, cc, FALSE);
+		    return vm_call_method_each_type(th, cfp, calling, ci, cc);
 		}
 	    }
-	    return vm_call_method_each_type(th, cfp, calling, ci, cc, enable_fastpath);
+	    return vm_call_method_each_type(th, cfp, calling, ci, cc);
 
 	  default:
 	    rb_bug("unreachable");
@@ -2152,30 +2174,6 @@ vm_call_method0(rb_thread_t *th, rb_cont https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2174
 }
 
 static VALUE
-vm_call_method_nome(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc)
-{
-    /* method missing */
-    const int stat = ci_missing_reason(ci);
-
-    if (ci->mid == idMethodMissing) {
-	rb_control_frame_t *reg_cfp = cfp;
-	VALUE *argv = STACK_ADDR_FROM_TOP(calling->argc);
-	rb_raise_method_missing(th, calling->argc, argv, calling->recv, stat);
-    }
-    else {
-	cc->aux.method_missing_reason = stat;
-	CI_SET_FASTPATH(cc, vm_call_method_missing, 1);
-	return vm_call_method_missing(th, cfp, calling, ci, cc);
-    }
-}
-
-static inline VALUE
-vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc)
-{
-    return vm_call_method0(th, cfp, calling, ci, cc, TRUE);
-}
-
-static VALUE
 vm_call_general(rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling, const struct rb_call_info *ci, struct rb_call_cache *cc)
 {
     return vm_call_method(th, reg_cfp, calling, ci, cc);

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

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