static void mark_interp(PARROT_INTERP) { ASSERT_ARGS(mark_interp) PObj *obj; /* mark the list of iglobals */ Parrot_gc_mark_PMC_alive(interp, interp->iglobals); /* mark the current continuation */ obj = (PObj *)interp->current_cont; if (obj && obj != (PObj *)NEED_CONTINUATION) Parrot_gc_mark_PMC_alive(interp, (PMC *)obj); /* mark the current context. */ Parrot_gc_mark_PMC_alive(interp, CURRENT_CONTEXT(interp)); /* mark the vtables: the data, Class PMCs, etc. */ Parrot_vtbl_mark_vtables(interp); /* mark the root_namespace */ Parrot_gc_mark_PMC_alive(interp, interp->root_namespace); /* mark the concurrency scheduler */ Parrot_gc_mark_PMC_alive(interp, interp->scheduler); /* mark caches and freelists */ mark_object_cache(interp); /* Now mark the class hash */ Parrot_gc_mark_PMC_alive(interp, interp->class_hash); /* Now mark the HLL stuff */ Parrot_gc_mark_PMC_alive(interp, interp->HLL_info); Parrot_gc_mark_PMC_alive(interp, interp->HLL_namespace); /* Mark the registry */ PARROT_ASSERT(interp->gc_registry); Parrot_gc_mark_PMC_alive(interp, interp->gc_registry); /* Mark the MMD cache. */ if (interp->op_mmd_cache) Parrot_mmd_cache_mark(interp, interp->op_mmd_cache); /* Walk the iodata */ Parrot_IOData_mark(interp, interp->piodata); if (!PMC_IS_NULL(interp->final_exception)) Parrot_gc_mark_PMC_alive(interp, interp->final_exception); if (interp->parent_interpreter) mark_interp(interp->parent_interpreter); }
int Parrot_gc_trace_root(PARROT_INTERP, ARGMOD(Memory_Pools *mem_pools), Parrot_gc_trace_type trace) { ASSERT_ARGS(Parrot_gc_trace_root) PObj *obj; /* note: adding locals here did cause increased GC runs */ mark_context_start(); if (trace == GC_TRACE_SYSTEM_ONLY) { trace_system_areas(interp, mem_pools); return 0; } /* We have to start somewhere; the interpreter globals is a good place */ if (!mem_pools->gc_mark_start) { mem_pools->gc_mark_start = mem_pools->gc_mark_ptr = interp->iglobals; } /* mark the list of iglobals */ Parrot_gc_mark_PMC_alive(interp, interp->iglobals); /* mark the current continuation */ obj = (PObj *)interp->current_cont; if (obj && obj != (PObj *)NEED_CONTINUATION) Parrot_gc_mark_PMC_alive(interp, (PMC *)obj); /* mark the current context. */ Parrot_gc_mark_PMC_alive(interp, CURRENT_CONTEXT(interp)); /* mark the dynamic environment. */ Parrot_gc_mark_PMC_alive(interp, interp->dynamic_env); /* mark the vtables: the data, Class PMCs, etc. */ mark_vtables(interp); /* mark the root_namespace */ Parrot_gc_mark_PMC_alive(interp, interp->root_namespace); /* mark the concurrency scheduler */ Parrot_gc_mark_PMC_alive(interp, interp->scheduler); /* s. packfile.c */ mark_const_subs(interp); /* mark caches and freelists */ mark_object_cache(interp); /* Now mark the class hash */ Parrot_gc_mark_PMC_alive(interp, interp->class_hash); /* Now mark the HLL stuff */ Parrot_gc_mark_PMC_alive(interp, interp->HLL_info); Parrot_gc_mark_PMC_alive(interp, interp->HLL_namespace); /* Mark the registry */ PARROT_ASSERT(interp->gc_registry); Parrot_gc_mark_PMC_alive(interp, interp->gc_registry); /* Mark the MMD cache. */ if (interp->op_mmd_cache) Parrot_mmd_cache_mark(interp, interp->op_mmd_cache); /* Walk the iodata */ Parrot_IOData_mark(interp, interp->piodata); if (trace == GC_TRACE_FULL) trace_system_areas(interp, mem_pools); /* quick check to see if we have already marked all impatient PMCs. If we have, return 0 and exit here. This will alert other parts of the GC that if we are in a lazy run we can just stop it. */ if (mem_pools->lazy_gc && mem_pools->num_early_PMCs_seen >= mem_pools->num_early_gc_PMCs) return 0; return 1; }