diff --git a/compile.c b/compile.c index c20ef48c43..997ec75dfb 100644 --- a/compile.c +++ b/compile.c @@ -10736,7 +10736,7 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords) } void -rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage) +rb_iseq_mark_and_update_insn_storage(struct iseq_compile_data_storage *storage) { INSN *iobj = 0; size_t size = sizeof(INSN); @@ -10772,13 +10772,7 @@ rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage) case TS_VALUE: case TS_IC: // constant path array case TS_CALLDATA: // ci is stored. - { - VALUE op = OPERAND_AT(iobj, j); - - if (!SPECIAL_CONST_P(op)) { - rb_gc_mark(op); - } - } + rb_gc_mark_and_move(&OPERAND_AT(iobj, j)); break; default: break; diff --git a/iseq.c b/iseq.c index ecacc7963f..97b9da9339 100644 --- a/iseq.c +++ b/iseq.c @@ -373,28 +373,23 @@ rb_iseq_mark_and_update(rb_iseq_t *iseq, bool reference_updating) } } - // TODO: make these not pinned - if (!reference_updating) { - if (FL_TEST_RAW((VALUE)iseq, ISEQ_NOT_LOADED_YET)) { - rb_gc_mark(iseq->aux.loader.obj); - } - else if (FL_TEST_RAW((VALUE)iseq, ISEQ_USE_COMPILE_DATA)) { - const struct iseq_compile_data *const compile_data = ISEQ_COMPILE_DATA(iseq); + if (FL_TEST_RAW((VALUE)iseq, ISEQ_NOT_LOADED_YET)) { + rb_gc_mark_and_move(&iseq->aux.loader.obj); + } + 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_insn_storage(compile_data->insn.storage_head); + rb_iseq_mark_and_update_insn_storage(compile_data->insn.storage_head); - RUBY_MARK_UNLESS_NULL(compile_data->err_info); - if (RTEST(compile_data->catch_table_ary)) { - rb_gc_mark(compile_data->catch_table_ary); - } - VM_ASSERT(compile_data != NULL); - } - else { - /* executable */ - VM_ASSERT(ISEQ_EXECUTABLE_P(iseq)); - if (iseq->aux.exec.local_hooks) { - rb_hook_list_mark(iseq->aux.exec.local_hooks); - } + rb_gc_mark_and_move((VALUE *)&compile_data->err_info); + rb_gc_mark_and_move((VALUE *)&compile_data->catch_table_ary); + } + else { + /* executable */ + VM_ASSERT(ISEQ_EXECUTABLE_P(iseq)); + + if (iseq->aux.exec.local_hooks) { + rb_hook_list_mark_and_update(iseq->aux.exec.local_hooks); } } diff --git a/iseq.h b/iseq.h index e5ab4870e8..5e26ea3589 100644 --- a/iseq.h +++ b/iseq.h @@ -186,7 +186,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_insn_storage(struct iseq_compile_data_storage *arena); +void rb_iseq_mark_and_update_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); diff --git a/vm_core.h b/vm_core.h index c67b3a5f4b..e07b49077a 100644 --- a/vm_core.h +++ b/vm_core.h @@ -2015,6 +2015,7 @@ struct rb_trace_arg_struct { }; void rb_hook_list_mark(rb_hook_list_t *hooks); +void rb_hook_list_mark_and_update(rb_hook_list_t *hooks); void rb_hook_list_free(rb_hook_list_t *hooks); void rb_hook_list_connect_tracepoint(VALUE target, rb_hook_list_t *list, VALUE tpval, unsigned int target_line); void rb_hook_list_remove_tracepoint(rb_hook_list_t *list, VALUE tpval); diff --git a/vm_trace.c b/vm_trace.c index 20fade5fd9..428c4a0170 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -66,6 +66,17 @@ rb_hook_list_mark(rb_hook_list_t *hooks) } } +void +rb_hook_list_mark_and_update(rb_hook_list_t *hooks) +{ + rb_event_hook_t *hook = hooks->hooks; + + while (hook) { + rb_gc_mark_and_move(&hook->data); + hook = hook->next; + } +} + static void clean_hooks(const rb_execution_context_t *ec, rb_hook_list_t *list); void