diff --git a/compile.c b/compile.c index 8b574cb5b340cd..31783feeafa9a2 100644 --- a/compile.c +++ b/compile.c @@ -1375,7 +1375,7 @@ new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line) } static void -iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE *, VALUE), VALUE data) +iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE, VALUE), VALUE data) { const char *types = insn_op_types(insn->insn_id); for (int j = 0; types[j]; j++) { @@ -1386,7 +1386,7 @@ iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE *, VALUE), VALUE d case TS_VALUE: case TS_IC: // constant path array case TS_CALLDATA: // ci is stored. - func(&OPERAND_AT(insn, j), data); + func(OPERAND_AT(insn, j), data); break; default: break; @@ -1395,9 +1395,9 @@ iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE *, VALUE), VALUE d } static void -iseq_insn_each_object_write_barrier(VALUE *obj_ptr, VALUE iseq) +iseq_insn_each_object_write_barrier(VALUE obj, VALUE iseq) { - RB_OBJ_WRITTEN(iseq, Qundef, *obj_ptr); + RB_OBJ_WRITTEN(iseq, Qundef, obj); } static INSN * @@ -10877,13 +10877,13 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords) } static void -iseq_insn_each_object_mark_and_move(VALUE *obj_ptr, VALUE _) +iseq_insn_each_object_mark_and_pin(VALUE obj, VALUE _) { - rb_gc_mark_and_move(obj_ptr); + rb_gc_mark(obj); } void -rb_iseq_mark_and_move_insn_storage(struct iseq_compile_data_storage *storage) +rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *storage) { INSN *iobj = 0; size_t size = sizeof(INSN); @@ -10908,7 +10908,7 @@ rb_iseq_mark_and_move_insn_storage(struct iseq_compile_data_storage *storage) iobj = (INSN *)&storage->buff[pos]; if (iobj->operands) { - iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark_and_move, (VALUE)0); + iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark_and_pin, (VALUE)0); } pos += (int)size; } diff --git a/iseq.c b/iseq.c index 03c7623b3cd04b..47d19a98f314f6 100644 --- a/iseq.c +++ b/iseq.c @@ -393,7 +393,14 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating) else if (FL_TEST_RAW((VALUE)iseq, ISEQ_USE_COMPILE_DATA)) { const struct iseq_compile_data *const compile_data = ISEQ_COMPILE_DATA(iseq); - rb_iseq_mark_and_move_insn_storage(compile_data->insn.storage_head); + if (!reference_updating) { + /* The operands in each instruction needs to be pinned because + * if auto-compaction runs in iseq_set_sequence, then the objects + * could exist on the generated_iseq buffer, which would not be + * reference updated which can lead to T_MOVED (and subsequently + * T_NONE) objects on the iseq. */ + rb_iseq_mark_and_pin_insn_storage(compile_data->insn.storage_head); + } rb_gc_mark_and_move((VALUE *)&compile_data->err_info); rb_gc_mark_and_move((VALUE *)&compile_data->catch_table_ary); diff --git a/iseq.h b/iseq.h index 1ad07e9065d8c7..5d17bb5d5b984d 100644 --- a/iseq.h +++ b/iseq.h @@ -189,7 +189,7 @@ VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq); void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE args, VALUE exception, VALUE body); -void rb_iseq_mark_and_move_insn_storage(struct iseq_compile_data_storage *arena); +void rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *arena); VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt); VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);