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/