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

ruby-changes:51708

From: tenderlove <ko1@a...>
Date: Tue, 10 Jul 2018 02:47:43 +0900 (JST)
Subject: [ruby-changes:51708] tenderlove:r63920 (trunk): Fix crash when loading iseq from an array

tenderlove	2018-07-10 02:47:37 +0900 (Tue, 10 Jul 2018)

  New Revision: 63920

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

  Log:
    Fix crash when loading iseq from an array
    
    Objects loaded during iseq deserialization using arrays need to be added
    to the compile time mark array so that they stay alive until iseqs
    finish loading.

  Modified files:
    trunk/compile.c
    trunk/test/-ext-/iseq_load/test_iseq_load.rb
Index: test/-ext-/iseq_load/test_iseq_load.rb
===================================================================
--- test/-ext-/iseq_load/test_iseq_load.rb	(revision 63919)
+++ test/-ext-/iseq_load/test_iseq_load.rb	(revision 63920)
@@ -16,6 +16,13 @@ class TestIseqLoad < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/-ext-/iseq_load/test_iseq_load.rb#L16
     end;
   end
 
+  def test_stressful_roundtrip
+    stress, GC.stress = GC.stress, true
+    test_bug8543
+  ensure
+    GC.stress = stress
+  end
+
   def test_case_when
     assert_iseq_roundtrip "#{<<~"begin;"}\n#{<<~'end;'}"
     begin;
Index: compile.c
===================================================================
--- compile.c	(revision 63919)
+++ compile.c	(revision 63920)
@@ -2159,6 +2159,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L2159
 				rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, body->is_size);
 			    }
 			    generated_iseq[code_index + 1 + j] = (VALUE)ic;
+			    RB_OBJ_WRITTEN(iseq, Qundef, ic);
 			    FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
 			    break;
 			}
@@ -7914,11 +7915,14 @@ iseq_build_from_ary_body(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L7915
 			break;
 		      case TS_VALUE:
 			argv[j] = op;
+			iseq_add_mark_object_compile_time(iseq, op);
 			break;
 		      case TS_ISEQ:
 			{
 			    if (op != Qnil) {
-				argv[j] = (VALUE)iseq_build_load_iseq(iseq, op);
+				VALUE v = (VALUE)iseq_build_load_iseq(iseq, op);
+				argv[j] = v;
+				iseq_add_mark_object_compile_time(iseq, v);
 			    }
 			    else {
 				argv[j] = 0;
@@ -7929,8 +7933,9 @@ iseq_build_from_ary_body(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L7933
 			op = rb_to_symbol_type(op);
 			argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
 			break;
-		      case TS_IC:
 		      case TS_ISE:
+			FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
+		      case TS_IC:
 			argv[j] = op;
 			if (NUM2UINT(op) >= iseq->body->is_size) {
 			    iseq->body->is_size = NUM2INT(op) + 1;
@@ -7961,6 +7966,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L7966
 			    }
 			    RB_GC_GUARD(op);
 			    argv[j] = map;
+			    iseq_add_mark_object_compile_time(iseq, map);
 			}
 			break;
 		      case TS_FUNCPTR:
@@ -8655,9 +8661,9 @@ ibf_load_code(const struct ibf_load *loa https://github.com/ruby/ruby/blob/trunk/compile.c#L8661
 		    }
 		    break;
 		}
-	      case TS_IC:
-		FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
 	      case TS_ISE:
+		FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
+	      case TS_IC:
 		code[code_index] = (VALUE)&is_entries[(int)op];
 		break;
 	      case TS_CALLINFO:

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

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