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

ruby-changes:39910

From: nobu <ko1@a...>
Date: Thu, 1 Oct 2015 11:58:07 +0900 (JST)
Subject: [ruby-changes:39910] nobu:r51991 (trunk): vm_args.c: GC guard

nobu	2015-10-01 11:57:43 +0900 (Thu, 01 Oct 2015)

  New Revision: 51991

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

  Log:
    vm_args.c: GC guard
    
    * vm_args.c (vm_caller_setup_arg_block): prevent newly created
      ifunc object from GC.

  Modified files:
    trunk/insns.def
    trunk/test/ruby/test_symbol.rb
    trunk/vm_args.c
Index: insns.def
===================================================================
--- insns.def	(revision 51990)
+++ insns.def	(revision 51991)
@@ -941,10 +941,10 @@ send https://github.com/ruby/ruby/blob/trunk/insns.def#L941
 (VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
 {
     struct rb_calling_info calling;
-
-    vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, FALSE);
+    VALUE mark = vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, FALSE);
     vm_search_method(ci, cc, calling.recv = TOPN(calling.argc = ci->orig_argc));
     CALL_METHOD(&calling, ci, cc);
+    RB_GC_GUARD(mark);
 }
 
 DEFINE_INSN
@@ -989,13 +989,15 @@ invokesuper https://github.com/ruby/ruby/blob/trunk/insns.def#L989
 (...)
 (VALUE val) // inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
 {
+    VALUE mark;
     struct rb_calling_info calling;
     calling.argc = ci->orig_argc;
 
-    vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, TRUE);
+    mark = vm_caller_setup_arg_block(th, reg_cfp, &calling, ci, blockiseq, TRUE);
     calling.recv = GET_SELF();
     vm_search_super_method(th, GET_CFP(), &calling, ci, cc);
     CALL_METHOD(&calling, ci, cc);
+    RB_GC_GUARD(mark);
 }
 
 /**
Index: test/ruby/test_symbol.rb
===================================================================
--- test/ruby/test_symbol.rb	(revision 51990)
+++ test/ruby/test_symbol.rb	(revision 51991)
@@ -117,6 +117,11 @@ class TestSymbol < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_symbol.rb#L117
       ary_ids = ary.collect{|x| x.object_id }
       assert_equal ary_ids, ary.collect(&:object_id)
     end
+
+    assert_ruby_status([], <<-"end;", timeout: 0.1)
+      GC.stress = true
+      true.tap(&:itself)
+    end;
   end
 
   def test_call
Index: vm_args.c
===================================================================
--- vm_args.c	(revision 51990)
+++ vm_args.c	(revision 51991)
@@ -766,10 +766,11 @@ vm_caller_setup_arg_kw(rb_control_frame_ https://github.com/ruby/ruby/blob/trunk/vm_args.c#L766
     calling->argc -= kw_len - 1;
 }
 
-static void
+static VALUE
 vm_caller_setup_arg_block(const rb_thread_t *th, rb_control_frame_t *reg_cfp,
 			  struct rb_calling_info *calling, const struct rb_call_info *ci, rb_iseq_t *blockiseq, const int is_super)
 {
+    VALUE mark = 0;
     if (ci->flag & VM_CALL_ARGS_BLOCKARG) {
 	rb_proc_t *po;
 	VALUE proc;
@@ -778,8 +779,10 @@ vm_caller_setup_arg_block(const rb_threa https://github.com/ruby/ruby/blob/trunk/vm_args.c#L779
 
 	if (SYMBOL_P(proc) && rb_method_basic_definition_p(rb_cSymbol, idTo_proc)) {
 	    calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp);
-	    calling->blockptr->iseq = (rb_iseq_t *)IFUNC_NEW(rb_sym_proc_call, SYM2ID(proc), 0);
+	    blockiseq = (rb_iseq_t *)IFUNC_NEW(rb_sym_proc_call, SYM2ID(proc), 0);
+	    calling->blockptr->iseq = blockiseq;
 	    calling->blockptr->proc = 0;
+	    mark = (VALUE)blockiseq;
 	}
 	else if (!NIL_P(proc)) {
 	    if (!rb_obj_is_proc(proc)) {
@@ -814,6 +817,8 @@ vm_caller_setup_arg_block(const rb_threa https://github.com/ruby/ruby/blob/trunk/vm_args.c#L817
 	    calling->blockptr = NULL;
 	}
     }
+
+    return mark;
 }
 
 #define IS_ARGS_SPLAT(ci)   ((ci)->flag & VM_CALL_ARGS_SPLAT)

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

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