diff options
-rw-r--r-- | iseq.c | 8 | ||||
-rw-r--r-- | vm_callinfo.h | 17 |
2 files changed, 23 insertions, 2 deletions
@@ -325,9 +325,13 @@ rb_iseq_mark(const rb_iseq_t *iseq) if (body->call_data) { struct rb_call_data *cds = (struct rb_call_data *)body->call_data; for (unsigned int i=0; i<body->ci_size; i++) { - rb_gc_mark_movable((VALUE)cds[i].ci); + const struct rb_callinfo *ci = cds[i].ci; const struct rb_callcache *cc = cds[i].cc; - if (cc && vm_cc_markable(cds[i].cc)) { + + if (vm_ci_markable(ci)) { + rb_gc_mark_movable((VALUE)ci); + } + if (cc && vm_cc_markable(cc)) { rb_gc_mark_movable((VALUE)cc); // TODO: check enable } diff --git a/vm_callinfo.h b/vm_callinfo.h index e938092926..14027fc112 100644 --- a/vm_callinfo.h +++ b/vm_callinfo.h @@ -229,6 +229,23 @@ vm_ci_new_runtime_(ID mid, unsigned int flag, unsigned int argc, const struct rb return vm_ci_new_(mid, flag, argc, kwarg, file, line); } +#define VM_CALLINFO_NOT_UNDER_GC IMEMO_FL_USER0 + +static inline bool +vm_ci_markable(const struct rb_callinfo *ci) +{ + if (! ci) { + return false; /* or true? This is Qfalse... */ + } + else if (vm_ci_packed_p(ci)) { + return true; + } + else { + VM_ASSERT(IMEMO_TYPE_P(ci, imemo_callinfo)); + return ! FL_ANY_RAW((VALUE)ci, VM_CALLINFO_NOT_UNDER_GC); + } +} + typedef VALUE (*vm_call_handler)( struct rb_execution_context_struct *ec, struct rb_control_frame_struct *cfp, |