summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2019-09-16 17:19:44 -0700
committerAaron Patterson <tenderlove@ruby-lang.org>2019-09-26 13:56:41 -0700
commit50fadefb7ed275148b2266712b923b8cca1ed785 (patch)
tree653a9b55812c11a887712bdd842aaf73f7377c68 /compile.c
parenta618d6408653b7f2459acb5af6205c42ad3aad87 (diff)
Scan the ISEQ arena for markables and mark them
This commit scans the ISEQ arena for objects that can be marked and marks them. This should make the mark array unnecessary.
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 9ba55e5bc7..f441b7dca5 100644
--- a/compile.c
+++ b/compile.c
@@ -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)
{