diff --git a/compile.c b/compile.c
index 9ba55e5bc7..f441b7dca5 100644
--- a/compile.c
+++ b/compile.c
@@ -8952,6 +8952,57 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
     return keyword;
 }
 
+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)
diff --git a/iseq.c b/iseq.c
index b5417cba19..f76b350056 100644
--- a/iseq.c
+++ b/iseq.c
@@ -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);
         }
diff --git a/iseq.h b/iseq.h
index 8bb4f30b4b..f1d446ccb7 100644
--- a/iseq.h
+++ b/iseq.h
@@ -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);