static void root_scan_phase(mrb_state *mrb) { size_t i, e; if (!is_minor_gc(mrb)) { mrb->gray_list = NULL; mrb->atomic_gray_list = NULL; } mrb_gc_mark_gv(mrb); /* mark arena */ for (i=0,e=mrb->arena_idx; i<e; i++) { mrb_gc_mark(mrb, mrb->arena[i]); } /* mark class hierarchy */ mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class); /* mark top_self */ mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self); /* mark exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); mark_context(mrb, mrb->root_c); if (mrb->root_c->fib) { mrb_gc_mark(mrb, (struct RBasic*)mrb->root_c->fib); } if (mrb->root_c != mrb->c) { mark_context(mrb, mrb->c); } }
static void mark_context(mrb_state *mrb, struct mrb_context *c) { int i, e = 0; mrb_callinfo *ci; /* mark stack */ mark_context_stack(mrb, c); /* mark VM stack */ if (c->cibase) { for (ci = c->cibase; ci <= c->ci; ci++) { if (ci->eidx > e) { e = ci->eidx; } mrb_gc_mark(mrb, (struct RBasic*)ci->env); mrb_gc_mark(mrb, (struct RBasic*)ci->proc); mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); } } /* mark ensure stack */ for (i=0; i<e; i++) { mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); } /* mark fibers */ if (c->prev && c->prev->fib) { mrb_gc_mark(mrb, (struct RBasic*)c->prev->fib); } }
static void mark_context(mrb_state *mrb, struct mrb_context *c) { int i; mrb_callinfo *ci; if (c->status == MRB_FIBER_TERMINATED) return; /* mark VM stack */ mark_context_stack(mrb, c); /* mark call stack */ if (c->cibase) { for (ci = c->cibase; ci <= c->ci; ci++) { mrb_gc_mark(mrb, (struct RBasic*)ci->env); mrb_gc_mark(mrb, (struct RBasic*)ci->proc); mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); } } /* mark ensure stack */ for (i=0; i<c->esize; i++) { if (c->ensure[i] == NULL) break; mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); } /* mark fibers */ mrb_gc_mark(mrb, (struct RBasic*)c->fib); if (c->prev) { mark_context(mrb, c->prev); } }
static void mark_context(mrb_state *mrb, struct mrb_context *c) { size_t i; size_t e; mrb_callinfo *ci; /* mark stack */ e = c->stack - c->stbase; if (c->ci) e += c->ci->nregs; if (c->stbase + e > c->stend) e = c->stend - c->stbase; for (i=0; i<e; i++) { mrb_gc_mark_value(mrb, c->stbase[i]); } /* mark ensure stack */ e = (c->ci) ? c->ci->eidx : 0; for (i=0; i<e; i++) { mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); } /* mark closure */ for (ci = c->cibase; ci <= c->ci; ci++) { if (!ci) continue; mrb_gc_mark(mrb, (struct RBasic*)ci->env); mrb_gc_mark(mrb, (struct RBasic*)ci->proc); mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); } if (c->prev && c->prev->fib) { mrb_gc_mark(mrb, (struct RBasic*)c->prev->fib); } }
static void mark_context_stack(mrb_state *mrb, struct mrb_context *c) { size_t i; size_t e; mrb_value nil; int nregs; if (c->stack == NULL) return; e = c->stack - c->stbase; if (c->ci) { nregs = c->ci->argc + 2; if (c->ci->nregs > nregs) nregs = c->ci->nregs; e += nregs; } if (c->stbase + e > c->stend) e = c->stend - c->stbase; for (i=0; i<e; i++) { mrb_value v = c->stbase[i]; if (!mrb_immediate_p(v)) { mrb_gc_mark(mrb, mrb_basic_ptr(v)); } } e = c->stend - c->stbase; nil = mrb_nil_value(); for (; i<e; i++) { c->stbase[i] = nil; } }
static void final_marking_phase(mrb_state *mrb, mrb_gc *gc) { int i, e; /* mark arena */ for (i=0,e=gc->arena_idx; i<e; i++) { mrb_gc_mark(mrb, gc->arena[i]); } mrb_gc_mark_gv(mrb); mark_context(mrb, mrb->c); mark_context(mrb, mrb->root_c); mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); gc_mark_gray_list(mrb, gc); mrb_assert(gc->gray_list == NULL); gc->gray_list = gc->atomic_gray_list; gc->atomic_gray_list = NULL; gc_mark_gray_list(mrb, gc); mrb_assert(gc->gray_list == NULL); }
static void root_scan_phase(mrb_state *mrb) { int i, j, e; mrb_callinfo *ci; mrb->gray_list = 0; mrb->variable_gray_list = 0; mrb_gc_mark_gv(mrb); /* mark arena */ for (i=0,e=mrb->arena_idx; i<e; i++) { mrb_gc_mark(mrb, mrb->arena[i]); } mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class); /* mark stack */ e = mrb->stack - mrb->stbase; if (mrb->ci) e += mrb->ci->nregs; for (i=0; i<e; i++) { mrb_gc_mark_value(mrb, mrb->stbase[i]); } /* mark ensure stack */ e = (mrb->ci) ? mrb->ci->eidx : 0; for (i=0; i<e; i++) { mrb_gc_mark(mrb, (struct RBasic*)mrb->ensure[i]); } /* mark closure */ for (ci = mrb->cibase; ci <= mrb->ci; ci++) { if (!ci) continue; mrb_gc_mark( mrb, (struct RBasic*)ci->env); } /* mark irep pool */ for (i=0; i<mrb->irep_len; i++) { mrb_irep *irep = mrb->irep[i]; if (!irep) continue; for (j=0; j<irep->plen; j++) { mrb_gc_mark_value(mrb, irep->pool[j]); } } }
static void root_scan_phase(mrb_state *mrb) { int j; size_t i, e; if (!is_minor_gc(mrb)) { mrb->gray_list = 0; mrb->variable_gray_list = 0; } mrb_gc_mark_gv(mrb); /* mark arena */ for (i=0,e=mrb->arena_idx; i<e; i++) { mrb_gc_mark(mrb, mrb->arena[i]); } /* mark class hierarchy */ mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class); /* mark top_self */ mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self); /* mark exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); mark_context(mrb, mrb->c); /* mark irep pool */ if (mrb->irep) { size_t len = mrb->irep_len; if (len > mrb->irep_capa) len = mrb->irep_capa; for (i=0; i<len; i++) { mrb_irep *irep = mrb->irep[i]; if (!irep) continue; for (j=0; j<irep->plen; j++) { mrb_gc_mark_value(mrb, irep->pool[j]); } } } }
static void root_scan_phase(mrb_state *mrb) { int i, j, e; mrb_callinfo *ci; if (!is_minor_gc(mrb)) { mrb->gray_list = 0; mrb->variable_gray_list = 0; } mrb_gc_mark_gv(mrb); /* mark arena */ for (i=0,e=mrb->arena_idx; i<e; i++) { mrb_gc_mark(mrb, mrb->arena[i]); } /* mark class hierarchy */ mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class); /* mark exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); /* mark stack */ e = mrb->stack - mrb->stbase; if (mrb->ci) e += mrb->ci->nregs; if (mrb->stbase + e > mrb->stend) e = mrb->stend - mrb->stbase; for (i=0; i<e; i++) { mrb_gc_mark_value(mrb, mrb->stbase[i]); } /* mark ensure stack */ e = (mrb->ci) ? mrb->ci->eidx : 0; for (i=0; i<e; i++) { mrb_gc_mark(mrb, (struct RBasic*)mrb->ensure[i]); } /* mark closure */ for (ci = mrb->cibase; ci <= mrb->ci; ci++) { if (!ci) continue; mrb_gc_mark(mrb, (struct RBasic*)ci->env); mrb_gc_mark(mrb, (struct RBasic*)ci->proc); mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); } /* mark irep pool */ if (mrb->irep) { size_t len = mrb->irep_len; if (len > mrb->irep_capa) len = mrb->irep_capa; for (i=0; i<len; i++) { mrb_irep *irep = mrb->irep[i]; if (!irep) continue; for (j=0; j<irep->plen; j++) { mrb_gc_mark_value(mrb, irep->pool[j]); } } } }
void mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) { khiter_t k; khash_t(mt) *h = c->mt; if (!h) return; for (k = kh_begin(h); k != kh_end(h); k++) { if (kh_exist(h, k)){ struct RProc *m = kh_value(h, k); if (m) { mrb_gc_mark(mrb, (struct RBasic*)m); } } } }
static void mark_context_stack(mrb_state *mrb, struct mrb_context *c) { size_t i; size_t e; e = c->stack - c->stbase; if (c->ci) e += c->ci->nregs; if (c->stbase + e > c->stend) e = c->stend - c->stbase; for (i=0; i<e; i++) { mrb_value v = c->stbase[i]; if (!mrb_immediate_p(v)) { if (mrb_basic_ptr(v)->tt == MRB_TT_FREE) { c->stbase[i] = mrb_nil_value(); } else { mrb_gc_mark(mrb, mrb_basic_ptr(v)); } } } }
static void gc_mark_children(mrb_state *mrb, struct RBasic *obj) { mrb_assert(is_gray(obj)); paint_black(obj); mrb->gray_list = obj->gcnext; mrb_gc_mark(mrb, (struct RBasic*)obj->c); switch (obj->tt) { case MRB_TT_ICLASS: mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); break; case MRB_TT_CLASS: case MRB_TT_MODULE: case MRB_TT_SCLASS: { struct RClass *c = (struct RClass*)obj; mrb_gc_mark_mt(mrb, c); mrb_gc_mark(mrb, (struct RBasic*)c->super); } /* fall through */ case MRB_TT_OBJECT: case MRB_TT_DATA: mrb_gc_mark_iv(mrb, (struct RObject*)obj); break; case MRB_TT_PROC: { struct RProc *p = (struct RProc*)obj; mrb_gc_mark(mrb, (struct RBasic*)p->env); mrb_gc_mark(mrb, (struct RBasic*)p->target_class); } break; case MRB_TT_ENV: { struct REnv *e = (struct REnv*)obj; if (!MRB_ENV_STACK_SHARED_P(e)) { int i, len; len = (int)MRB_ENV_STACK_LEN(e); for (i=0; i<len; i++) { mrb_gc_mark_value(mrb, e->stack[i]); } } } break; case MRB_TT_FIBER: { struct mrb_context *c = ((struct RFiber*)obj)->cxt; if (c) mark_context(mrb, c); } break; case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; size_t i, e; for (i=0,e=a->len; i<e; i++) { mrb_gc_mark_value(mrb, a->ptr[i]); } } break; case MRB_TT_HASH: mrb_gc_mark_iv(mrb, (struct RObject*)obj); mrb_gc_mark_hash(mrb, (struct RHash*)obj); break; case MRB_TT_STRING: break; case MRB_TT_RANGE: { struct RRange *r = (struct RRange*)obj; if (r->edges) { mrb_gc_mark_value(mrb, r->edges->beg); mrb_gc_mark_value(mrb, r->edges->end); } } break; default: break; } }
static void gc_mark_children(mrb_state *mrb, struct RBasic *obj) { gc_assert(is_gray(obj)); paint_black(obj); mrb->gray_list = obj->gcnext; mrb_gc_mark(mrb, (struct RBasic*)obj->c); switch (obj->tt) { case MRB_TT_ICLASS: mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); break; case MRB_TT_CLASS: case MRB_TT_MODULE: case MRB_TT_SCLASS: { struct RClass *c = (struct RClass*)obj; mrb_gc_mark_mt(mrb, c); mrb_gc_mark(mrb, (struct RBasic*)c->super); } /* fall through */ case MRB_TT_OBJECT: case MRB_TT_DATA: mrb_gc_mark_iv(mrb, (struct RObject*)obj); break; case MRB_TT_PROC: { struct RProc *p = (struct RProc*)obj; mrb_gc_mark(mrb, (struct RBasic*)p->env); mrb_gc_mark(mrb, (struct RBasic*)p->target_class); } break; case MRB_TT_ENV: { struct REnv *e = (struct REnv*)obj; if (e->cioff < 0) { int i, len; len = (int)e->flags; for (i=0; i<len; i++) { mrb_gc_mark_value(mrb, e->stack[i]); } } } break; case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; size_t i, e; for (i=0,e=a->len; i<e; i++) { mrb_gc_mark_value(mrb, a->ptr[i]); } } break; case MRB_TT_HASH: mrb_gc_mark_iv(mrb, (struct RObject*)obj); mrb_gc_mark_ht(mrb, (struct RHash*)obj); break; case MRB_TT_STRING: break; case MRB_TT_RANGE: { struct RRange *r = (struct RRange*)obj; mrb_gc_mark_value(mrb, r->edges->beg); mrb_gc_mark_value(mrb, r->edges->end); } break; #ifdef ENABLE_REGEXP case MRB_TT_MATCH: { struct RMatch *m = (struct RMatch*)obj; mrb_gc_mark(mrb, (struct RBasic*)m->str); mrb_gc_mark(mrb, (struct RBasic*)m->regexp); } break; case MRB_TT_REGEX: { struct RRegexp *r = (struct RRegexp*)obj; mrb_gc_mark(mrb, (struct RBasic*)r->src); } break; #endif #ifdef ENABLE_STRUCT case MRB_TT_STRUCT: { struct RStruct *s = (struct RStruct*)obj; long i; for (i=0; i<s->len; i++){ mrb_gc_mark_value(mrb, s->ptr[i]); } } break; #endif default: break; } }
static void root_scan_phase(mrb_state *mrb, mrb_gc *gc) { int i, e; if (!is_minor_gc(gc)) { gc->gray_list = NULL; gc->atomic_gray_list = NULL; } mrb_gc_mark_gv(mrb); /* mark arena */ for (i=0,e=gc->arena_idx; i<e; i++) { mrb_gc_mark(mrb, gc->arena[i]); } /* mark class hierarchy */ mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class); /* mark built-in classes */ mrb_gc_mark(mrb, (struct RBasic*)mrb->class_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->module_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->proc_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->string_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->nil_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->symbol_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->kernel_module); mrb_gc_mark(mrb, (struct RBasic*)mrb->eException_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->eStandardError_class); /* mark top_self */ mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self); /* mark exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); /* mark pre-allocated exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err); mrb_gc_mark(mrb, (struct RBasic*)mrb->stack_err); #ifdef MRB_GC_FIXED_ARENA mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); #endif mark_context(mrb, mrb->c); if (mrb->root_c != mrb->c) { mark_context(mrb, mrb->root_c); } }
static void gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) { mrb_assert(is_gray(obj)); paint_black(obj); gc->gray_list = obj->gcnext; mrb_gc_mark(mrb, (struct RBasic*)obj->c); switch (obj->tt) { case MRB_TT_ICLASS: { struct RClass *c = (struct RClass*)obj; if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN)) mrb_gc_mark_mt(mrb, c); mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); } break; case MRB_TT_CLASS: case MRB_TT_MODULE: case MRB_TT_SCLASS: { struct RClass *c = (struct RClass*)obj; mrb_gc_mark_mt(mrb, c); mrb_gc_mark(mrb, (struct RBasic*)c->super); } /* fall through */ case MRB_TT_OBJECT: case MRB_TT_DATA: case MRB_TT_EXCEPTION: mrb_gc_mark_iv(mrb, (struct RObject*)obj); break; case MRB_TT_PROC: { struct RProc *p = (struct RProc*)obj; mrb_gc_mark(mrb, (struct RBasic*)p->upper); mrb_gc_mark(mrb, (struct RBasic*)p->e.env); } break; case MRB_TT_ENV: { struct REnv *e = (struct REnv*)obj; mrb_int i, len; if (MRB_ENV_STACK_SHARED_P(e) && e->cxt && e->cxt->fib) { mrb_gc_mark(mrb, (struct RBasic*)e->cxt->fib); } len = MRB_ENV_STACK_LEN(e); for (i=0; i<len; i++) { mrb_gc_mark_value(mrb, e->stack[i]); } } break; case MRB_TT_FIBER: { struct mrb_context *c = ((struct RFiber*)obj)->cxt; if (c) mark_context(mrb, c); } break; case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; size_t i, e; for (i=0,e=ARY_LEN(a); i<e; i++) { mrb_gc_mark_value(mrb, ARY_PTR(a)[i]); } } break; case MRB_TT_HASH: mrb_gc_mark_iv(mrb, (struct RObject*)obj); mrb_gc_mark_hash(mrb, (struct RHash*)obj); break; case MRB_TT_STRING: if (RSTR_FSHARED_P(obj) && !RSTR_NOFREE_P(obj)) { struct RString *s = (struct RString*)obj; mrb_gc_mark(mrb, (struct RBasic*)s->as.heap.aux.fshared); } break; case MRB_TT_RANGE: { struct RRange *r = (struct RRange*)obj; if (r->edges) { mrb_gc_mark_value(mrb, r->edges->beg); mrb_gc_mark_value(mrb, r->edges->end); } } break; default: break; } }
static void gc_mark_children(mrb_state *mrb, struct RBasic *obj) { gc_assert(is_gray(obj)); paint_black(obj); mrb->gray_list = obj->gcnext; mrb_gc_mark(mrb, (struct RBasic*)obj->c); switch (obj->tt) { case MRB_TT_ICLASS: mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); break; case MRB_TT_CLASS: case MRB_TT_SCLASS: case MRB_TT_MODULE: { struct RClass *c = (struct RClass*)obj; mrb_gc_mark_iv(mrb, (struct RObject*)obj); mrb_gc_mark_mt(mrb, c); mrb_gc_mark(mrb, (struct RBasic*)c->super); } break; case MRB_TT_OBJECT: mrb_gc_mark_iv(mrb, (struct RObject*)obj); break; case MRB_TT_PROC: { struct RProc *p = (struct RProc*)obj; mrb_gc_mark(mrb, (struct RBasic*)p->env); mrb_gc_mark(mrb, (struct RBasic*)p->target_class); } break; case MRB_TT_ENV: { struct REnv *e = (struct REnv *)obj; if (e->cioff < 0) { int i, len; len = (int)e->flags; for (i=0; i<len; i++) { mrb_gc_mark_value(mrb, e->stack[i]); } } } break; case MRB_TT_ARRAY: { struct RArray *a = (struct RArray*)obj; size_t i, e; for (i=0,e=a->len; i<e; i++) { mrb_gc_mark_value(mrb, a->buf[i]); } } break; case MRB_TT_HASH: mrb_gc_mark_ht(mrb, (struct RClass*)obj); break; case MRB_TT_STRING: { struct RString *s = (struct RString*)obj; if (s->flags & MRB_STR_SHARED) { mrb_gc_mark_value(mrb, s->aux.shared) } } break; case MRB_TT_RANGE: { struct RRange *r = (struct RRange*)obj; mrb_gc_mark_value(mrb, r->edges->beg); mrb_gc_mark_value(mrb, r->edges->end); } break; case MRB_TT_REGEX: case MRB_TT_STRUCT: case MRB_TT_EXCEPTION: break; } }