/* * reclaim.c * loops through all variables in all objects looking for the possibility * of freeing up destructed objects (that are still hanging around because * of references) -- coded by Blackthorn@Genocide Feb. 1993 */ #include <stdio.h> #include "config.h" #include "lint.h" #include "interpret.h" #include "mapping.h" #include "buffer.h" #include "object.h" #include "exec.h" #define MAX_RECURSION 25 void gc_indices PROT((struct mapping *)); void gc_values PROT((struct mapping *)); extern struct svalue const0n; static int cleaned, nested; void check_svalue(v) struct svalue *v; { register int idx; nested++; if (nested > MAX_RECURSION) { return; } switch (v->type) { case T_OBJECT: if (v->u.ob->flags & O_DESTRUCTED) { free_svalue(v); cleaned++; } break; case T_MAPPING: gc_values(v->u.map); gc_indices(v->u.map); break; case T_POINTER: for (idx = 0; idx < v->u.vec->size; idx++) check_svalue(&v->u.vec->item[idx]); break; case T_FUNCTION: check_svalue(&v->u.fp->obj); check_svalue(&v->u.fp->fun); break; } nested--; return; } int gcOne(m, elt, info) struct mapping *m; struct node *elt; vinfo_t *info; { check_svalue(&elt->values[info->w]); return 0; } void gc_indices(m) struct mapping *m; { vinfo_t info; info.w = 0; mapTraverse(m, (int (*)())gcOne, &info); } void gc_values(m) struct mapping *m; { vinfo_t info; info.w = 1; mapTraverse(m, (int (*)())gcOne, &info); } int reclaim_objects() { int i; struct object *ob; cleaned = nested = 0; for (ob = obj_list; ob; ob = ob->next_all) if (ob->prog) for (i = 0; i < (int)ob->prog->p.i.num_variables; i++) check_svalue(&ob->variables[i]); return cleaned; }