/* This Parrot-specific addition to the API is used to mark an object. */ static void gc_mark(PARROT_INTERP, PMC *obj) { UninstantiableInstance *instance = (UninstantiableInstance *)PMC_data(obj); if (!PMC_IS_NULL(instance->common.stable)) Parrot_gc_mark_PMC_alive(interp, instance->common.stable); if (!PMC_IS_NULL(instance->common.sc)) Parrot_gc_mark_PMC_alive(interp, instance->common.sc); }
/* This Parrot-specific addition to the API is used to mark an object. */ static void gc_mark(PARROT_INTERP, PMC *obj) { P6strInstance *instance = (P6strInstance *)PMC_data(obj); if (!PMC_IS_NULL(instance->common.stable)) Parrot_gc_mark_PMC_alive(interp, instance->common.stable); if (!PMC_IS_NULL(instance->common.sc)) Parrot_gc_mark_PMC_alive(interp, instance->common.sc); if (!STRING_IS_NULL(instance->value)) Parrot_gc_mark_STRING_alive(interp, instance->value); }
/* This Parrot-specific addition to the API is used to mark an object. */ static void gc_mark(PARROT_INTERP, STable *st, void *data) { KnowHOWREPRBody *body = (KnowHOWREPRBody *)data; UNUSED(st); if (!STRING_IS_NULL(body->name)) Parrot_gc_mark_STRING_alive(interp, body->name); if (!PMC_IS_NULL(body->methods)) Parrot_gc_mark_PMC_alive(interp, body->methods); if (!PMC_IS_NULL(body->attributes)) Parrot_gc_mark_PMC_alive(interp, body->attributes); }
/* This Parrot-specific addition to the API is used to mark an object. */ static void gc_mark(PARROT_INTERP, PMC *obj) { HashAttrStoreInstance *instance = (HashAttrStoreInstance *)PMC_data(obj); /* Mark STable. */ if (!PMC_IS_NULL(instance->common.stable)) Parrot_gc_mark_PMC_alive(interp, instance->common.stable); /* Mark store */ if (!PMC_IS_NULL(instance->store)) Parrot_gc_mark_PMC_alive(interp, instance->store); }
/* This Parrot-specific addition to the API is used to mark an object. */ static void gc_mark(PARROT_INTERP, PMC *obj) { KnowHOWREPRInstance *instance = (KnowHOWREPRInstance *)PMC_data(obj); if (!PMC_IS_NULL(instance->common.stable)) Parrot_gc_mark_PMC_alive(interp, instance->common.stable); if (!PMC_IS_NULL(instance->common.sc)) Parrot_gc_mark_PMC_alive(interp, instance->common.sc); if (!PMC_IS_NULL(instance->methods)) Parrot_gc_mark_PMC_alive(interp, instance->methods); if (!PMC_IS_NULL(instance->attributes)) Parrot_gc_mark_PMC_alive(interp, instance->attributes); }
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); }
/* This Parrot-specific addition to the API is used to mark an object. */ static void gc_mark(PARROT_INTERP, PMC *obj) { P6opaqueInstance *instance = (P6opaqueInstance *)PMC_data(obj); /* Mark STable and SC. */ if (!PMC_IS_NULL(instance->common.stable)) Parrot_gc_mark_PMC_alive(interp, instance->common.stable); if (!PMC_IS_NULL(instance->common.sc)) Parrot_gc_mark_PMC_alive(interp, instance->common.sc); /* If there's spill storage, mark that. */ if (!PMC_IS_NULL(instance->spill)) Parrot_gc_mark_PMC_alive(interp, instance->spill); /* Mark contained PMC and string attributes, provided this is a * real object. */ if (instance->spill) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)STABLE(obj)->REPR_data; INTVAL i; /* Mark PMCs. */ if (repr_data->gc_pmc_mark_offsets) { for (i = 0; i < repr_data->num_attributes; i++) { INTVAL offset = repr_data->gc_pmc_mark_offsets[i]; if (offset) { PMC *to_mark = get_pmc_at_offset(instance, offset); if (!PMC_IS_NULL(to_mark)) Parrot_gc_mark_PMC_alive(interp, to_mark); } else { break; } } } /* Mark strings. */ if (repr_data->gc_str_mark_offsets) { for (i = 0; i < repr_data->num_attributes; i++) { INTVAL offset = repr_data->gc_str_mark_offsets[i]; if (offset) { STRING *to_mark = get_str_at_offset(instance, offset); if (to_mark) Parrot_gc_mark_STRING_alive(interp, to_mark); } else { break; } } } } }
/* This Parrot-specific addition to the API is used to mark a repr's * per-type data. */ static void gc_mark_repr_data(PARROT_INTERP, STable *st) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; if (repr_data->name_to_index_mapping) { P6opaqueNameMap *cur_map_entry = repr_data->name_to_index_mapping; while (cur_map_entry->class_key != NULL) { Parrot_gc_mark_PMC_alive(interp, cur_map_entry->name_map); cur_map_entry++; } } if (repr_data->auto_viv_values) { int i; for (i = 0; i < repr_data->num_attributes; i++) { PMC *to_mark = repr_data->auto_viv_values[i]; if (to_mark != NULL && !PMC_IS_NULL(to_mark)) Parrot_gc_mark_PMC_alive(interp, to_mark); } } }
static void gc_mark(PARROT_INTERP, STable *st, void *data) { NativeCallBody *body = (NativeCallBody *)data; UNUSED(st); if (body->arg_info) { INTVAL i; for (i = 0; i < body->num_args; i++) { if (body->arg_info[i]) Parrot_gc_mark_PMC_alive(interp, body->arg_info[i]); } } }
/* This Parrot-specific addition to the API is used to mark an object. */ static void gc_mark(PARROT_INTERP, STable *st, void *data) { NFABody *body = (NFABody *)data; INTVAL i, j; if (!PMC_IS_NULL(body->fates)) Parrot_gc_mark_PMC_alive(interp, body->fates); for (i = 0; i < body->num_states; i++) { INTVAL edges = body->num_state_edges[i]; for (j = 0; j < edges; j++) { switch (body->states[i][j].act) { case EDGE_CHARLIST: case EDGE_CHARLIST_NEG: Parrot_gc_mark_STRING_alive(interp, body->states[i][j].arg.s); } } } }
void mark_special(PARROT_INTERP, ARGMOD(Memory_Pools *mem_pools), ARGIN(PMC *obj)) { ASSERT_ARGS(mark_special) PObj_get_FLAGS(obj) |= PObj_custom_GC_FLAG; /* clearing the flag is much more expensive then testing */ if (!PObj_needs_early_gc_TEST(obj)) PObj_high_priority_gc_CLEAR(obj); /* mark properties */ Parrot_gc_mark_PMC_alive(interp, PMC_metadata(obj)); if (PObj_custom_mark_TEST(obj)) { PARROT_ASSERT(!PObj_on_free_list_TEST(obj)); VTABLE_mark(interp, obj); } }
/* This Parrot-specific addition to the API is used to mark an object. */ static void gc_mark(PARROT_INTERP, STable *st, void *data) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; INTVAL i; /* Mark PMCs. */ if (repr_data->gc_pmc_mark_offsets) { for (i = 0; i < repr_data->gc_pmc_mark_offsets_count; i++) { INTVAL offset = repr_data->gc_pmc_mark_offsets[i]; PMC *to_mark = get_pmc_at_offset(data, offset); if (!PMC_IS_NULL(to_mark)) Parrot_gc_mark_PMC_alive(interp, to_mark); } } /* Mark any nested reprs that need it. */ if (repr_data->gc_mark_slots) { for (i = 0; repr_data->gc_mark_slots[i] >= 0; i++) { INTVAL offset = repr_data->attribute_offsets[repr_data->gc_mark_slots[i]]; STable *st = repr_data->flattened_stables[repr_data->gc_mark_slots[i]]; st->REPR->gc_mark(interp, st, (char *)data + offset); } } }
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; }