INLINE void dealloc_funp (funptr_t * fp) { program_t *prog = 0; switch (fp->hdr.type) { case FP_LOCAL | FP_NOT_BINDABLE: if (fp->hdr.owner) prog = fp->hdr.owner->prog; break; case FP_FUNCTIONAL: case FP_FUNCTIONAL | FP_NOT_BINDABLE: prog = fp->f.functional.prog; break; } if (fp->hdr.owner) free_object(&fp->hdr.owner, "free_funp"); if (fp->hdr.args) free_array(fp->hdr.args); if (prog) { prog->func_ref--; debug(d_flag, ("subtr func ref /%s: now %i\n", prog->filename, prog->func_ref)); if (!prog->func_ref && !prog->ref) deallocate_program(prog); } FREE(fp); }
static void check_svalue(svalue_t * 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, "reclaim_objects"); *v = const0u; cleaned++; } break; case T_MAPPING: gc_mapping(v->u.map); break; case T_ARRAY: case T_CLASS: for (idx = 0; idx < v->u.arr->size; idx++) check_svalue(&v->u.arr->item[idx]); break; case T_FUNCTION: { svalue_t tmp; program_t *prog; if (v->u.fp->hdr.owner && (v->u.fp->hdr.owner->flags & O_DESTRUCTED)) { if (v->u.fp->hdr.type == FP_LOCAL | FP_NOT_BINDABLE) { prog = v->u.fp->hdr.owner->prog; prog->func_ref--; debug(d_flag, ("subtr func ref /%s: now %i\n", prog->name, prog->func_ref)); if (!prog->ref && !prog->func_ref) deallocate_program(prog); } free_object(v->u.fp->hdr.owner, "reclaim_objects"); v->u.fp->hdr.owner = 0; cleaned++; } tmp.type = T_ARRAY; if ((tmp.u.arr = v->u.fp->hdr.args)) check_svalue(&tmp); break; } } nested--; return; }
/* * Decrement reference count for a program. If it is 0, then free the prgram. * The flag free_sub_strings tells if the propgram plus all used strings * should be freed. They normally are, except when objects are swapped, * as we want to be able to read the program in again from the swap area. * That means that strings are not swapped. */ void free_prog (program_t **progp) { (*progp)->ref--; if ((*progp)->ref > 0) { *progp = (program_t *)2;//NULL; return; } if ((*progp)->func_ref > 0) { *progp = (program_t *)3;//NULL; return; } deallocate_program(*progp); *progp = (program_t *)4;//NULL; }
/* * Decrement reference count for a program. If it is 0, then free the prgram. * The flag free_sub_strings tells if the propgram plus all used strings * should be freed. They normally are, except when objects are swapped, * as we want to be able to read the program in again from the swap area. * That means that strings are not swapped. */ void free_prog P2(struct program *, progp, int, free_sub_strings) { progp->p.i.ref--; if (progp->p.i.ref > 0) return; if (progp->p.i.func_ref > 0) return; #ifdef DEBUG if (progp->p.i.ref < 0) fatal("Negative ref count for prog ref.\n"); #endif if (free_sub_strings) deallocate_program(progp); else { total_prog_block_size -= progp->p.i.total_size; total_num_prog_blocks -= 1; FREE((char *) progp); } }