diff options
-rw-r--r-- | compile.c | 51 | ||||
-rw-r--r-- | iseq.c | 3 | ||||
-rw-r--r-- | iseq.h | 1 |
3 files changed, 55 insertions, 0 deletions
@@ -8953,6 +8953,57 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords) } void +rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage) +{ + INSN *iobj = 0; + size_t size = sizeof(INSN); + unsigned int pos = 0; + + while (storage) { +#ifdef STRICT_ALIGNMENT + size_t padding = calc_padding((void *)&storage->buff[pos], size); +#else + const size_t padding = 0; /* expected to be optimized by compiler */ +#endif /* STRICT_ALIGNMENT */ + size_t offset = pos + size + padding; + if (offset > storage->size || offset > storage->pos) { + pos = 0; + storage = storage->next; + } else { +#ifdef STRICT_ALIGNMENT + pos += (int)padding; +#endif /* STRICT_ALIGNMENT */ + + iobj = (INSN *)&storage->buff[pos]; + + if (iobj->operands) { + int j; + const char *types = insn_op_types(iobj->insn_id); + + for(j = 0; types[j]; j++) { + char type = types[j]; + switch(type) { + case TS_CDHASH: + case TS_ISEQ: + case TS_VALUE: + { + VALUE op = OPERAND_AT(iobj, j); + if (!SPECIAL_CONST_P(op)) { + rb_gc_mark(op); + } + break; + } + default: + break; + } + } + } + pos += (int)size; + } + } +} + +void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, VALUE exception, VALUE body) { @@ -336,6 +336,9 @@ rb_iseq_mark(const rb_iseq_t *iseq) } else if (FL_TEST_RAW(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); + if (RTEST(compile_data->mark_ary)) { rb_gc_mark(compile_data->mark_ary); } @@ -174,6 +174,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); /* iseq.c */ VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt); |